[Public][Service] Upgrade d2d app version as v1.0.1 90/255490/6 submit/tizen/20210319.160018
authorYoungsoo Choi <kenshin.choi@samsung.com>
Fri, 19 Mar 2021 01:48:26 +0000 (18:48 -0700)
committerYoungsoo Choi <kenshin.choi@samsung.com>
Fri, 19 Mar 2021 05:22:22 +0000 (22:22 -0700)
This upgrades d2d app version as v1.0.1.

Change-Id: I6c305c011537e026779634993a56fcaec1d02425
Signed-off-by: Youngsoo Choi <kenshin.choi@samsung.com>
670 files changed:
d2d_app/about.html [new file with mode: 0644]
d2d_app/client/client.html
d2d_app/client/control.html [new file with mode: 0644]
d2d_app/client/css/app-remote-control-basic.css [new file with mode: 0644]
d2d_app/client/css/pincode.css [new file with mode: 0644]
d2d_app/client/css/style.css
d2d_app/client/images/Hamburger_icon.svg [new file with mode: 0644]
d2d_app/client/images/control/btn_down.png [new file with mode: 0644]
d2d_app/client/images/control/btn_minus.png [new file with mode: 0644]
d2d_app/client/images/control/btn_plus.png [new file with mode: 0644]
d2d_app/client/images/control/btn_up.png [new file with mode: 0644]
d2d_app/client/images/control/control1_bg .png [new file with mode: 0644]
d2d_app/client/images/control/control2_bg .png [new file with mode: 0644]
d2d_app/client/images/control/cta/oval/default.png [new file with mode: 0644]
d2d_app/client/images/control/default.png [new file with mode: 0644]
d2d_app/client/images/control/ic_control1_bottom.png [new file with mode: 0644]
d2d_app/client/images/control/ic_control1_left.png [new file with mode: 0644]
d2d_app/client/images/control/ic_control1_right.png [new file with mode: 0644]
d2d_app/client/images/control/ic_control1_top.png [new file with mode: 0644]
d2d_app/client/images/control/ic_function_media_next.svg [new file with mode: 0644]
d2d_app/client/images/control/ic_function_media_prev.svg [new file with mode: 0644]
d2d_app/client/images/control/ic_function_media_stop.svg [new file with mode: 0644]
d2d_app/client/images/control/ic_home.png [new file with mode: 0644]
d2d_app/client/images/control/ic_source.png [new file with mode: 0644]
d2d_app/client/images/control/squarcle_bg.png [new file with mode: 0644]
d2d_app/client/images/control/tw_list_icon_connections.svg [new file with mode: 0644]
d2d_app/client/images/folder.png [deleted file]
d2d_app/client/images/ic_back.png [new file with mode: 0644]
d2d_app/client/images/icon.png [new file with mode: 0755]
d2d_app/client/images/tw_list_icon_wallpaper.svg [new file with mode: 0644]
d2d_app/client/invited.html [new file with mode: 0644]
d2d_app/client/js/actions.js [new file with mode: 0644]
d2d_app/client/js/app.js [new file with mode: 0644]
d2d_app/client/js/client.js
d2d_app/client/js/clipping-storage.js [new file with mode: 0644]
d2d_app/client/js/control.js [new file with mode: 0644]
d2d_app/client/js/invited.js [new file with mode: 0755]
d2d_app/client/js/jsencrypt.js [new file with mode: 0644]
d2d_app/client/js/myApps.js [new file with mode: 0755]
d2d_app/client/js/pincode.js [new file with mode: 0755]
d2d_app/client/lib/tau/LICENSE.Flora [new file with mode: 0644]
d2d_app/client/lib/tau/VERSION [new file with mode: 0644]
d2d_app/client/lib/tau/animation/tau.animation.js [new file with mode: 0644]
d2d_app/client/lib/tau/animation/tau.animation.min.js [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/js/jquery.js [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/js/jquery.min.js [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/js/tau.js [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/js/tau.min.js [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Light.ttf [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Medium.ttf [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Regular.ttf [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/bottom_left.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/bottom_right.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/top_left.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/top_right.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_action_bar_icon_current_location_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_ab_back_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_ab_more_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_clear_search_api_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_voice_search_api_mtrl_alpha.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/13_View_controls/tw_spinner_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_cursor_handler_bottom.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_cursor_handler_top.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_select_handler_left.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_select_handler_right.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_ic_ab_back_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_ic_ab_more_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_add_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_back_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_more_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_search_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_delete_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_move_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_share_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/2_Buttons/tw_ic_ab_add_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_000.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_001.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_002.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_003.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_004.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_005.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_006.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_007.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_008.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_009.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_010.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_011.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_012.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_013.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_014.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_015.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_016.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_017.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_018.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_019.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_020.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_021.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_022.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_023.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_024.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_025.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_026.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_000.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_001.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_002.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_003.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_004.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_005.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_006.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_007.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_008.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_009.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_010.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_011.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_012.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_013.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_014.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_015.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_016.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_017.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_018.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_019.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_020.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_021.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_022.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_023.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_024.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_025.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_026.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_000.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_001.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_002.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_003.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_004.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_005.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_006.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_007.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_008.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_009.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_010.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_011.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_012.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_013.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_014.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_015.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_016.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_017.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_018.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_019.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_020.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_021.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_022.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_023.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_024.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_025.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_026.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/gallery_btn_check_bg_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_chips_icon_add_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_chips_icon_delete_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_expander_close_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_expander_open_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_add_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_delete_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_reorder.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/4_Dialogs/tw_numberpicker_next_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/4_Dialogs/tw_numberpicker_prev_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_expander_close_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_expander_open_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_connections.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_display.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_notifications.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_sound.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_wallpaper.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_subheader_dot.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/9_Progress/tw_ic_progress_download_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/9_Progress/tw_ic_progress_refresh_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_001.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_002.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_003.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_004.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_005.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_006.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_007.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_008.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_009.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_010.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_011.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_012.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/images/controls/00_button_pause.png [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/tau.css [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/changeable/tau.min.css [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Light.ttf [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Medium.ttf [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Regular.ttf [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/bottom_left.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/bottom_right.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/top_left.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/top_right.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_action_bar_icon_current_location_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_ab_back_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_ab_more_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_clear_search_api_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_voice_search_api_mtrl_alpha.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/13_View_controls/tw_spinner_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_cursor_handler_bottom.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_cursor_handler_top.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_select_handler_left.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_select_handler_right.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_ic_ab_back_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_ic_ab_more_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_add_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_back_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_more_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_search_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_delete_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_move_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_share_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/2_Buttons/tw_ic_ab_add_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_000.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_001.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_002.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_003.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_004.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_005.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_006.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_007.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_008.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_009.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_010.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_011.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_012.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_013.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_014.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_015.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_016.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_017.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_018.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_019.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_020.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_021.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_022.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_023.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_024.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_025.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_026.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_000.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_001.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_002.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_003.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_004.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_005.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_006.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_007.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_008.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_009.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_010.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_011.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_012.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_013.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_014.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_015.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_016.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_017.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_018.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_019.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_020.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_021.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_022.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_023.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_024.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_025.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_026.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_000.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_001.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_002.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_003.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_004.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_005.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_006.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_007.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_008.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_009.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_010.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_011.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_012.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_013.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_014.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_015.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_016.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_017.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_018.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_019.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_020.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_021.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_022.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_023.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_024.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_025.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_026.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/gallery_btn_check_bg_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_chips_icon_add_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_chips_icon_delete_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_expander_close_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_expander_open_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_add_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_delete_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_reorder.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/4_Dialogs/tw_numberpicker_next_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/4_Dialogs/tw_numberpicker_prev_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_expander_close_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_expander_open_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_connections.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_display.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_notifications.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_sound.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_wallpaper.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_subheader_dot.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/9_Progress/tw_ic_progress_download_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/9_Progress/tw_ic_progress_refresh_mtrl.svg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_001.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_002.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_003.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_004.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_005.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_006.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_007.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_008.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_009.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_010.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_011.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_012.jpg [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/images/controls/00_button_pause.png [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/tau.css [new file with mode: 0644]
d2d_app/client/lib/tau/mobile/theme/default/tau.min.css [new file with mode: 0644]
d2d_app/client/manifest.webmanifest [new file with mode: 0644]
d2d_app/client/pincode.html [new file with mode: 0755]
d2d_app/config.xml
d2d_app/icon.png [changed mode: 0755->0644]
d2d_app/node_modules/.bin/ejs [new symlink]
d2d_app/node_modules/.bin/jake [new symlink]
d2d_app/node_modules/ansi-styles/index.js [new file with mode: 0644]
d2d_app/node_modules/ansi-styles/license [new file with mode: 0644]
d2d_app/node_modules/ansi-styles/package.json [new file with mode: 0644]
d2d_app/node_modules/ansi-styles/readme.md [new file with mode: 0644]
d2d_app/node_modules/async/.travis.yml [new file with mode: 0644]
d2d_app/node_modules/async/LICENSE [moved from d2d_app/node_modules/express/node_modules/ms/license.md with 87% similarity]
d2d_app/node_modules/async/README.md [new file with mode: 0644]
d2d_app/node_modules/async/bower.json [new file with mode: 0644]
d2d_app/node_modules/async/component.json [new file with mode: 0644]
d2d_app/node_modules/async/lib/async.js [new file with mode: 0644]
d2d_app/node_modules/async/package.json [new file with mode: 0644]
d2d_app/node_modules/async/support/sync-package-managers.js [new file with mode: 0755]
d2d_app/node_modules/balanced-match/.npmignore [new file with mode: 0644]
d2d_app/node_modules/balanced-match/LICENSE.md [new file with mode: 0644]
d2d_app/node_modules/balanced-match/README.md [new file with mode: 0644]
d2d_app/node_modules/balanced-match/index.js [new file with mode: 0644]
d2d_app/node_modules/balanced-match/package.json [new file with mode: 0644]
d2d_app/node_modules/brace-expansion/LICENSE [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/node_modules/ms/license.md with 93% similarity]
d2d_app/node_modules/brace-expansion/README.md [new file with mode: 0644]
d2d_app/node_modules/brace-expansion/index.js [new file with mode: 0644]
d2d_app/node_modules/brace-expansion/package.json [new file with mode: 0644]
d2d_app/node_modules/chalk/index.js [new file with mode: 0644]
d2d_app/node_modules/chalk/index.js.flow [new file with mode: 0644]
d2d_app/node_modules/chalk/license [new file with mode: 0644]
d2d_app/node_modules/chalk/package.json [new file with mode: 0644]
d2d_app/node_modules/chalk/readme.md [new file with mode: 0644]
d2d_app/node_modules/chalk/templates.js [new file with mode: 0644]
d2d_app/node_modules/chalk/types/index.d.ts [new file with mode: 0644]
d2d_app/node_modules/color-convert/CHANGELOG.md [new file with mode: 0644]
d2d_app/node_modules/color-convert/LICENSE [new file with mode: 0644]
d2d_app/node_modules/color-convert/README.md [new file with mode: 0644]
d2d_app/node_modules/color-convert/conversions.js [new file with mode: 0644]
d2d_app/node_modules/color-convert/index.js [new file with mode: 0644]
d2d_app/node_modules/color-convert/package.json [new file with mode: 0644]
d2d_app/node_modules/color-convert/route.js [new file with mode: 0644]
d2d_app/node_modules/color-name/.eslintrc.json [new file with mode: 0644]
d2d_app/node_modules/color-name/.npmignore [new file with mode: 0644]
d2d_app/node_modules/color-name/LICENSE [new file with mode: 0644]
d2d_app/node_modules/color-name/README.md [new file with mode: 0644]
d2d_app/node_modules/color-name/index.js [new file with mode: 0644]
d2d_app/node_modules/color-name/package.json [new file with mode: 0644]
d2d_app/node_modules/color-name/test.js [new file with mode: 0644]
d2d_app/node_modules/concat-map/.travis.yml [new file with mode: 0644]
d2d_app/node_modules/concat-map/LICENSE [new file with mode: 0644]
d2d_app/node_modules/concat-map/README.markdown [new file with mode: 0644]
d2d_app/node_modules/concat-map/example/map.js [new file with mode: 0644]
d2d_app/node_modules/concat-map/index.js [new file with mode: 0644]
d2d_app/node_modules/concat-map/package.json [new file with mode: 0644]
d2d_app/node_modules/concat-map/test/map.js [new file with mode: 0644]
d2d_app/node_modules/cookie-signature/.npmignore [moved from d2d_app/node_modules/express/node_modules/cookie-signature/.npmignore with 100% similarity]
d2d_app/node_modules/cookie-signature/History.md [moved from d2d_app/node_modules/express/node_modules/cookie-signature/History.md with 100% similarity]
d2d_app/node_modules/cookie-signature/Readme.md [moved from d2d_app/node_modules/express/node_modules/cookie-signature/Readme.md with 100% similarity]
d2d_app/node_modules/cookie-signature/index.js [moved from d2d_app/node_modules/express/node_modules/cookie-signature/index.js with 100% similarity]
d2d_app/node_modules/cookie-signature/package.json [moved from d2d_app/node_modules/express/node_modules/cookie-signature/package.json with 90% similarity]
d2d_app/node_modules/cookie/HISTORY.md [moved from d2d_app/node_modules/express/node_modules/cookie/HISTORY.md with 100% similarity]
d2d_app/node_modules/cookie/LICENSE [moved from d2d_app/node_modules/express/node_modules/cookie/LICENSE with 100% similarity]
d2d_app/node_modules/cookie/README.md [moved from d2d_app/node_modules/express/node_modules/cookie/README.md with 100% similarity]
d2d_app/node_modules/cookie/index.js [moved from d2d_app/node_modules/express/node_modules/cookie/index.js with 100% similarity]
d2d_app/node_modules/cookie/package.json [moved from d2d_app/node_modules/express/node_modules/cookie/package.json with 92% similarity]
d2d_app/node_modules/debug/.coveralls.yml [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/.coveralls.yml with 100% similarity]
d2d_app/node_modules/debug/.eslintrc [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/.eslintrc with 100% similarity]
d2d_app/node_modules/debug/.npmignore [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/.npmignore with 100% similarity]
d2d_app/node_modules/debug/.travis.yml [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/.travis.yml with 100% similarity]
d2d_app/node_modules/debug/CHANGELOG.md [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/CHANGELOG.md with 100% similarity]
d2d_app/node_modules/debug/LICENSE [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/LICENSE with 100% similarity]
d2d_app/node_modules/debug/Makefile [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/Makefile with 100% similarity]
d2d_app/node_modules/debug/README.md [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/README.md with 100% similarity]
d2d_app/node_modules/debug/component.json [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/component.json with 100% similarity]
d2d_app/node_modules/debug/karma.conf.js [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/karma.conf.js with 100% similarity]
d2d_app/node_modules/debug/node.js [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/node.js with 100% similarity]
d2d_app/node_modules/debug/package.json [moved from d2d_app/node_modules/express/node_modules/debug/package.json with 91% similarity]
d2d_app/node_modules/debug/src/browser.js [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/src/browser.js with 100% similarity]
d2d_app/node_modules/debug/src/debug.js [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/src/debug.js with 100% similarity]
d2d_app/node_modules/debug/src/index.js [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/src/index.js with 100% similarity]
d2d_app/node_modules/debug/src/inspector-log.js [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/src/inspector-log.js with 100% similarity]
d2d_app/node_modules/debug/src/node.js [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/src/node.js with 100% similarity]
d2d_app/node_modules/depd/History.md [moved from d2d_app/node_modules/express/node_modules/depd/History.md with 91% similarity]
d2d_app/node_modules/depd/LICENSE [moved from d2d_app/node_modules/express/node_modules/depd/LICENSE with 95% similarity]
d2d_app/node_modules/depd/Readme.md [moved from d2d_app/node_modules/express/node_modules/depd/Readme.md with 95% similarity]
d2d_app/node_modules/depd/index.js [moved from d2d_app/node_modules/express/node_modules/depd/index.js with 90% similarity]
d2d_app/node_modules/depd/lib/browser/index.js [moved from d2d_app/node_modules/express/node_modules/depd/lib/browser/index.js with 100% similarity]
d2d_app/node_modules/depd/package.json [moved from d2d_app/node_modules/express/node_modules/depd/package.json with 52% similarity]
d2d_app/node_modules/ejs/LICENSE [new file with mode: 0644]
d2d_app/node_modules/ejs/README.md [new file with mode: 0644]
d2d_app/node_modules/ejs/bin/cli.js [new file with mode: 0755]
d2d_app/node_modules/ejs/ejs.js [new file with mode: 0644]
d2d_app/node_modules/ejs/ejs.min.js [new file with mode: 0644]
d2d_app/node_modules/ejs/jakefile.js [new file with mode: 0644]
d2d_app/node_modules/ejs/lib/ejs.js [new file with mode: 0755]
d2d_app/node_modules/ejs/lib/utils.js [new file with mode: 0644]
d2d_app/node_modules/ejs/package.json [new file with mode: 0644]
d2d_app/node_modules/ejs/usage.txt [new file with mode: 0644]
d2d_app/node_modules/escape-string-regexp/index.js [new file with mode: 0644]
d2d_app/node_modules/escape-string-regexp/license [new file with mode: 0644]
d2d_app/node_modules/escape-string-regexp/package.json [new file with mode: 0644]
d2d_app/node_modules/escape-string-regexp/readme.md [new file with mode: 0644]
d2d_app/node_modules/express-session/HISTORY.md [new file with mode: 0644]
d2d_app/node_modules/express-session/LICENSE [new file with mode: 0644]
d2d_app/node_modules/express-session/README.md [new file with mode: 0644]
d2d_app/node_modules/express-session/index.js [new file with mode: 0644]
d2d_app/node_modules/express-session/package.json [new file with mode: 0644]
d2d_app/node_modules/express-session/session/cookie.js [new file with mode: 0644]
d2d_app/node_modules/express-session/session/memory.js [new file with mode: 0644]
d2d_app/node_modules/express-session/session/session.js [new file with mode: 0644]
d2d_app/node_modules/express-session/session/store.js [new file with mode: 0644]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.coveralls.yml [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.eslintrc [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.npmignore [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.travis.yml [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/CHANGELOG.md [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/LICENSE [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/Makefile [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/README.md [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/component.json [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/karma.conf.js [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/node.js [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/package.json [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/browser.js [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/debug.js [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/index.js [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/inspector-log.js [deleted file]
d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/node.js [deleted file]
d2d_app/node_modules/express/node_modules/debug/.coveralls.yml [deleted file]
d2d_app/node_modules/express/node_modules/debug/.eslintrc [deleted file]
d2d_app/node_modules/express/node_modules/debug/.npmignore [deleted file]
d2d_app/node_modules/express/node_modules/debug/.travis.yml [deleted file]
d2d_app/node_modules/express/node_modules/debug/CHANGELOG.md [deleted file]
d2d_app/node_modules/express/node_modules/debug/LICENSE [deleted file]
d2d_app/node_modules/express/node_modules/debug/Makefile [deleted file]
d2d_app/node_modules/express/node_modules/debug/README.md [deleted file]
d2d_app/node_modules/express/node_modules/debug/component.json [deleted file]
d2d_app/node_modules/express/node_modules/debug/karma.conf.js [deleted file]
d2d_app/node_modules/express/node_modules/debug/node.js [deleted file]
d2d_app/node_modules/express/node_modules/debug/src/browser.js [deleted file]
d2d_app/node_modules/express/node_modules/debug/src/debug.js [deleted file]
d2d_app/node_modules/express/node_modules/debug/src/index.js [deleted file]
d2d_app/node_modules/express/node_modules/debug/src/inspector-log.js [deleted file]
d2d_app/node_modules/express/node_modules/debug/src/node.js [deleted file]
d2d_app/node_modules/express/node_modules/depd/lib/compat/callsite-tostring.js [deleted file]
d2d_app/node_modules/express/node_modules/depd/lib/compat/event-listener-count.js [deleted file]
d2d_app/node_modules/express/node_modules/depd/lib/compat/index.js [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.coveralls.yml [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.eslintrc [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.npmignore [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.travis.yml [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/CHANGELOG.md [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/LICENSE [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/Makefile [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/README.md [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/component.json [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/karma.conf.js [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/node.js [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/package.json [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/browser.js [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/debug.js [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/index.js [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/inspector-log.js [deleted file]
d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/node.js [deleted file]
d2d_app/node_modules/express/node_modules/ms/index.js [deleted file]
d2d_app/node_modules/express/node_modules/ms/package.json [deleted file]
d2d_app/node_modules/express/node_modules/ms/readme.md [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/debug/package.json [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/mime/.npmignore [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/mime/CHANGELOG.md [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/mime/README.md [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/mime/cli.js [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/mime/mime.js [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/mime/package.json [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/mime/src/build.js [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/mime/src/test.js [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/mime/types.json [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/ms/index.js [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/ms/package.json [deleted file]
d2d_app/node_modules/express/node_modules/send/node_modules/ms/readme.md [deleted file]
d2d_app/node_modules/has-flag/index.js [new file with mode: 0644]
d2d_app/node_modules/has-flag/license [new file with mode: 0644]
d2d_app/node_modules/has-flag/package.json [new file with mode: 0644]
d2d_app/node_modules/has-flag/readme.md [new file with mode: 0644]
d2d_app/node_modules/jake/Makefile [new file with mode: 0644]
d2d_app/node_modules/jake/README.md [new file with mode: 0644]
d2d_app/node_modules/jake/bin/bash_completion.sh [new file with mode: 0755]
d2d_app/node_modules/jake/bin/cli.js [new file with mode: 0755]
d2d_app/node_modules/jake/jakefile.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/api.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/jake.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/loader.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/namespace.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/package_task.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/parseargs.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/program.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/publish_task.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/rule.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/task/directory_task.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/task/file_task.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/task/index.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/task/task.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/test_task.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/utils/file.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/utils/index.js [new file with mode: 0644]
d2d_app/node_modules/jake/lib/utils/logger.js [new file with mode: 0644]
d2d_app/node_modules/jake/package.json [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/concurrent.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/file.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/file_task.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/helpers.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/jakefile.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/jakelib/concurrent.jake.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/jakelib/publish.jake.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/jakelib/required_module.jake.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/jakelib/rule.jake.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/publish_task.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/rule.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/selfdep.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/integration/task_base.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/unit/jakefile.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/unit/namespace.js [new file with mode: 0644]
d2d_app/node_modules/jake/test/unit/parseargs.js [new file with mode: 0644]
d2d_app/node_modules/jake/usage.txt [new file with mode: 0644]
d2d_app/node_modules/minimatch/LICENSE [new file with mode: 0644]
d2d_app/node_modules/minimatch/README.md [new file with mode: 0644]
d2d_app/node_modules/minimatch/minimatch.js [new file with mode: 0644]
d2d_app/node_modules/minimatch/package.json [new file with mode: 0644]
d2d_app/node_modules/ms/index.js [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/node_modules/ms/index.js with 100% similarity]
d2d_app/node_modules/ms/license.md [moved from d2d_app/node_modules/express/node_modules/send/node_modules/ms/license.md with 100% similarity]
d2d_app/node_modules/ms/package.json [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/node_modules/ms/package.json with 89% similarity]
d2d_app/node_modules/ms/readme.md [moved from d2d_app/node_modules/express/node_modules/send/node_modules/debug/node_modules/ms/readme.md with 100% similarity]
d2d_app/node_modules/on-headers/HISTORY.md [new file with mode: 0644]
d2d_app/node_modules/on-headers/LICENSE [new file with mode: 0644]
d2d_app/node_modules/on-headers/README.md [new file with mode: 0644]
d2d_app/node_modules/on-headers/index.js [new file with mode: 0644]
d2d_app/node_modules/on-headers/package.json [new file with mode: 0644]
d2d_app/node_modules/parseurl/HISTORY.md [moved from d2d_app/node_modules/express/node_modules/parseurl/HISTORY.md with 100% similarity]
d2d_app/node_modules/parseurl/LICENSE [moved from d2d_app/node_modules/express/node_modules/parseurl/LICENSE with 100% similarity]
d2d_app/node_modules/parseurl/README.md [moved from d2d_app/node_modules/express/node_modules/parseurl/README.md with 100% similarity]
d2d_app/node_modules/parseurl/index.js [moved from d2d_app/node_modules/express/node_modules/parseurl/index.js with 100% similarity]
d2d_app/node_modules/parseurl/package.json [moved from d2d_app/node_modules/express/node_modules/parseurl/package.json with 93% similarity]
d2d_app/node_modules/random-bytes/HISTORY.md [new file with mode: 0644]
d2d_app/node_modules/random-bytes/LICENSE [moved from d2d_app/node_modules/express/node_modules/send/node_modules/mime/LICENSE with 93% similarity]
d2d_app/node_modules/random-bytes/README.md [new file with mode: 0644]
d2d_app/node_modules/random-bytes/index.js [new file with mode: 0644]
d2d_app/node_modules/random-bytes/package.json [new file with mode: 0644]
d2d_app/node_modules/safe-buffer/LICENSE [moved from d2d_app/node_modules/express/node_modules/safe-buffer/LICENSE with 100% similarity]
d2d_app/node_modules/safe-buffer/README.md [moved from d2d_app/node_modules/express/node_modules/safe-buffer/README.md with 99% similarity]
d2d_app/node_modules/safe-buffer/index.d.ts [moved from d2d_app/node_modules/express/node_modules/safe-buffer/index.d.ts with 100% similarity]
d2d_app/node_modules/safe-buffer/index.js [moved from d2d_app/node_modules/express/node_modules/safe-buffer/index.js with 96% similarity]
d2d_app/node_modules/safe-buffer/package.json [moved from d2d_app/node_modules/express/node_modules/safe-buffer/package.json with 50% similarity]
d2d_app/node_modules/supports-color/browser.js [new file with mode: 0644]
d2d_app/node_modules/supports-color/index.js [new file with mode: 0644]
d2d_app/node_modules/supports-color/license [new file with mode: 0644]
d2d_app/node_modules/supports-color/package.json [new file with mode: 0644]
d2d_app/node_modules/supports-color/readme.md [new file with mode: 0644]
d2d_app/node_modules/uid-safe/HISTORY.md [new file with mode: 0644]
d2d_app/node_modules/uid-safe/LICENSE [new file with mode: 0644]
d2d_app/node_modules/uid-safe/README.md [new file with mode: 0644]
d2d_app/node_modules/uid-safe/index.js [new file with mode: 0644]
d2d_app/node_modules/uid-safe/package.json [new file with mode: 0644]
d2d_app/node_modules/xmlhttprequest/.jshintrc [new file with mode: 0644]
d2d_app/node_modules/xmlhttprequest/.npmignore [new file with mode: 0644]
d2d_app/node_modules/xmlhttprequest/LICENSE [new file with mode: 0644]
d2d_app/node_modules/xmlhttprequest/README.md [new file with mode: 0644]
d2d_app/node_modules/xmlhttprequest/lib/XMLHttpRequest.js [new file with mode: 0644]
d2d_app/node_modules/xmlhttprequest/package.json [new file with mode: 0644]
d2d_app/package-lock.json [new file with mode: 0644]
d2d_app/service/app_proxy.js [changed mode: 0644->0755]
d2d_app/service/app_router.js [changed mode: 0644->0755]
d2d_app/service/jsencrypt.js [new file with mode: 0644]
d2d_app/service/private.key [new file with mode: 0644]
d2d_app/service/public.key [new file with mode: 0644]
d2d_app/service/relay-server.js
d2d_app/service/service.js

diff --git a/d2d_app/about.html b/d2d_app/about.html
new file mode 100644 (file)
index 0000000..4360646
--- /dev/null
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
+</head>
+
+<body>
+    <div style="text-align:center">
+        <h2>Global Device Web Server v.0.1</h2>
+    </div>
+</body>
+
+</html>
index 1cad15a..59c8298 100755 (executable)
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
-       <meta name="viewport" content="width=device-width,user-scalable=no"/>
-    <link rel="stylesheet" type="text/css" href="css/style.css"/>
-    <script src="js/client.js"></script>
-    <title>Client</title>
+       <meta charset="UTF-8">
+       <meta name="viewport" content="width=device-width, user-scalable=no">
+       <title>My Device App</title>
+       <link href="lib/tau/mobile/theme/default/tau.css" rel="stylesheet" />
+       <link rel="stylesheet" href="css/style.css" />
+       <link rel="manifest" href="./manifest.webmanifest">
+       <link rel="shortcut icon" href="images/Icon.png">
+       <script>
+               const logged = '<%=JSON.stringify(logged)%>';
+               if (logged !== 'true')
+                       location.replace('/');
+       </script>
+       <script data-build-remove="false" src="lib/tau/mobile/js/tau.js"></script>
+       <script src="js/clipping-storage.js" type="module"></script>
+       <script src="js/app.js" type="module"></script>
+       <script src="js/myApps.js" type="module"></script>
 </head>
 <body>
-    <div id="container">
-        <div id="page-main" class="page">
-            <div id="header-main" class="header">
-                <div id="text-header-main" class="text-header">
-                    App List
-                </div>
-            </div>
-            <div id="contents-main" class="contents">
-                <div id="detail-main" class="detail">
-                </div>
-            </div>
-        </div>
-        <div id="spinner-main" class="spinner">
-             <div class="spinner-img">
-        </div>
-    </div>
+       <div class="ui-page ui-page-active" id="main">
+               <header>
+                       <div class="ui-appbar-title-container">
+                               <span class="ui-appbar-title">My Device App</span>
+                       </div>
+                       <div class="ui-appbar-left-icons-container">
+                               <a href="#" class="ui-btn ui-btn-icon app-btn-icon-burger" data-style="flat"></a>
+                       </div>
+                       <div class="ui-appbar-action-buttons-container">
+                               <a class="ui-btn ui-btn-icon ui-btn-icon-add" data-style="flat" href="#turn-on-dialog"></a>
+                               <button class="ui-btn ui-btn-icon ui-btn-icon-more" id="selector-opener" data-style="flat"></button>
+                               <select data-native-menu="false" id="theme-selector" style="display: none;">
+                                       <option value="light">
+                                               Light Theme
+                                       </option>
+                                       <option value="dark">
+                                               Dark Theme
+                                       </option>
+                               </select>
+                       </div>
+                       <div class="ui-appbar-container ui-content-area">
+                               <div class="ui-icon">
+                                       <img src="images/icon.png"/>
+                               </div>
+                               <span class="ui-title">Instant Control</span>
+                               <a href="control.html" class="ui-btn" data-style="flat" data-inline="true" data-icon="next"></a>
+                       </div>
+               </header>
+               <div class="ui-content" id="page-main">
+                       <div id="web-clips"></div>
+
+                       <div class="ui-content-subheader">
+                               D2D on My Device
+                       </div>
+                       <div class="ui-content-area" id="d2dApps">
+                               <div class="app-image-grid" id="d2dAppList">
+                               </div>
+                       </div>
+                       <div class="ui-drawer" data-position="left" id="leftDrawer" data-drag-edge="0">
+                               <div class="ui-drawer-header">
+                                       <div class="ui-drawer-title">My Device App</div>
+                               </div>
+                               <ul class="ui-listview ui-content-area">
+                                       <li class="ui-li-divider ui-li-has-icon">
+                                               <div class="ui-li-icon">
+                                                       <img src="images/tw_list_icon_wallpaper.svg"/>
+                                               </div>
+                                               <a href="#" data-rel="back">
+                                                       <span class="ui-li-text">Media item 1</span>
+                                               </a>
+                                       </li>
+                                       <li class="ui-li-divider ui-li-has-icon">
+                                               <div class="ui-li-icon">
+                                                       <img src="images/tw_list_icon_wallpaper.svg"/>
+                                               </div>
+                                               <a href="#" data-rel="back">
+                                                       <span class="ui-li-text">Media item 2</span>
+                                               </a>
+                                       </li>
+                                       <li class="ui-li-divider ui-li-has-icon">
+                                               <div class="ui-li-icon">
+                                                       <img src="images/tw_list_icon_wallpaper.svg"/>
+                                               </div>
+                                               <a href="#" data-rel="back">
+                                                       <span class="ui-li-text">Media item 3</span>
+                                               </a>
+                                       </li>
+                               </ul>
+                       </div>
+                       <div class="ui-popup" id="turn-on-dialog">
+                               <div class="ui-popup-header">
+                                       Customize widgets
+                               </div>
+                               <div class="ui-popup-content">
+                                       <ul class="ui-listview ui-content-area popup-list" id="popup-list">
+                                       </ul>
+                               </div>
+                               <div class="ui-popup-footer">
+                                       <button class="ui-btn ui-btn-flat ui-btn-text" data-style="flat" id="popup-submit">OK</button>
+                               </div>
+                       </div>
+               </div>
+       </div>
 </body>
 </html>
diff --git a/d2d_app/client/control.html b/d2d_app/client/control.html
new file mode 100644 (file)
index 0000000..9fa5c96
--- /dev/null
@@ -0,0 +1,196 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+       <meta charset="UTF-8">
+       <meta name="viewport" content="width=device-width, user-scalable=no">
+       <title>Home Tv App</title>
+       <link href="lib/tau/mobile/theme/default/tau.css" rel="stylesheet" />
+       <link rel="stylesheet" href="css/style.css" />
+       <script data-build-remove="false" src="lib/tau/mobile/js/tau.js"></script>
+</head>
+<body>
+       <div class="ui-page" id="open-control-app-1">
+               <script src="./js/control.js"></script>
+               <header data-expanding-enabled="false">
+                       <div class="ui-appbar-title-container">
+                               <span class="ui-appbar-title">Instant Control</span>
+                       </div>
+                       <div class="ui-appbar-left-icons-container">
+                               <a href="#" class="ui-btn ui-btn-icon ui-btn-icon-back" data-style="flat" data-rel="back"></a>
+                       </div>
+               </header>
+
+               <div class="ui-content ui-tabs">
+                       <div class="ui-sub-tab ui-sub-tab-static">
+                               <ul>
+                                       <li class="ui-li-anchor">
+                                               <a class="ui-tab-active" href="#">
+                                                       Basic
+                                               </a>
+                                       </li>
+                                       <li class="ui-li-anchor">
+                                               <a href="#">
+                                                       Channel
+                                               </a>
+                                       </li>
+                                       <li class="ui-li-anchor">
+                                               <a href="#">
+                                                       Typing
+                                               </a>
+                                       </li>
+                                       <li class="ui-li-anchor">
+                                               <a href="#">
+                                                       Media
+                                               </a>
+                                       </li>
+                               </ul>
+                       </div>
+                       <div class="ui-section-changer">
+                               <div>
+                                       <section class="ui-content ui-section-active">
+                                               <div class="ui-card ui-card-service app-border">
+                                                       <div class="ui-header" data-expanding-enabled="false">
+                                                               <div class="ui-title">Remote Control</div>
+                                                               <div class="ui-icon app-remote-control-icon"></div>
+                                                       </div>
+                                                       <div class="ui-content">
+                                                               <link rel="stylesheet" href="./css/app-remote-control-basic.css" />
+                                                               <div class="app-home-buttons">
+                                                                       <button class="ui-btn ui-btn-icon app-btn-enter" data-icon="enter" data-style="flat"></button>
+                                                                       <button class="ui-btn ui-btn-icon app-btn-home" data-icon="home" data-style="flat"></button>
+                                                                       <button class="ui-btn ui-btn-icon app-btn-backward" data-icon="backward" data-style="flat"></button>
+                                                               </div>
+                                                               <div class="app-remote-control">
+                                                                       <div class="app-volume-channel">
+                                                                               <div class="app-volume-control">
+                                                                                       <button class="ui-btn ui-btn-icon app-btn-icon-volume-up" data-icon="plus" data-style="flat"></button>
+                                                                                       VOL
+                                                                                       <button class="ui-btn ui-btn-icon app-btn-icon-volume-down"  data-icon="minus" data-style="flat"></button>
+                                                                               </div>
+                                                                               <div class="app-channel-control">
+                                                                                       <button class="ui-btn ui-btn-icon app-btn-icon-channel-up" data-icon="up" data-style="flat"></button>
+                                                                                       CH
+                                                                                       <button class="ui-btn ui-btn-icon app-btn-icon-channel-down" data-icon="down" data-style="flat"></button>
+                                                                               </div>
+                                                                       </div>
+                                                                       <div class="app-4way-direction">
+                                                                               <button class="ui-btn ui-btn-icon app-4way-btn-up" data-icon="up" data-style="flat"></button>
+                                                                               <button class="ui-btn ui-btn-icon app-4way-btn-right" data-icon="right" data-style="flat"></button>
+                                                                               <div class="app-4way-touchpad"></div>
+                                                                               <button class="ui-btn ui-btn-icon app-4way-btn-left" data-icon="left" data-style="flat"></button>
+                                                                               <button class="ui-btn ui-btn-icon app-4way-btn-down" data-icon="down" data-style="flat"></button>
+                                                                       </div>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                       </section>
+                                       <section class="ui-content">
+                                               <div class="ui-card ui-card-service app-border">
+                                                       <div class="ui-header" data-expanding-enabled="false">
+                                                               <div class="ui-title">Remote Control</div>
+                                                               <div class="ui-icon app-remote-control-icon"></div>
+                                                       </div>
+                                                       <div class="ui-content">
+                                                               <link rel="stylesheet" href="./css/app-remote-control-channel.css" />
+                                                               <div class="app-home-buttons">
+                                                                       <button class="ui-btn ui-btn-icon app-btn-enter" data-icon="enter" data-style="flat"></button>
+                                                                       <button class="ui-btn ui-btn-icon app-btn-home" data-icon="home" data-style="flat"></button>
+                                                                       <button class="ui-btn ui-btn-icon app-btn-backward" data-icon="backward" data-style="flat"></button>
+                                                               </div>
+                                                               <div class="app-remote-control">
+                                                                       <div class="app-volume-channel">
+                                                                               <div class="app-volume-control">
+                                                                                       <button class="ui-btn ui-btn-icon app-btn-icon-volume-up" data-icon="plus" data-style="flat"></button>
+                                                                                       VOL
+                                                                                       <button class="ui-btn ui-btn-icon app-btn-icon-volume-down"  data-icon="minus" data-style="flat"></button>
+                                                                               </div>
+                                                                               <div class="app-channel-control">
+                                                                                       <button class="ui-btn ui-btn-icon app-btn-icon-channel-up" data-icon="up" data-style="flat"></button>
+                                                                                       CH
+                                                                                       <button class="ui-btn ui-btn-icon app-btn-icon-channel-down" data-icon="down" data-style="flat"></button>
+                                                                               </div>
+                                                                       </div>
+                                                                       <div class="app-remote-num-pad">
+                                                                               <button class="ui-btn app-num-pad-1" data-style="flat">1</button>
+                                                                               <button class="ui-btn app-num-pad-2" data-style="flat">2</button>
+                                                                               <button class="ui-btn app-num-pad-3" data-style="flat">3</button>
+                                                                               <button class="ui-btn app-num-pad-4" data-style="flat">4</button>
+                                                                               <button class="ui-btn app-num-pad-5" data-style="flat">5</button>
+                                                                               <button class="ui-btn app-num-pad-6" data-style="flat">6</button>
+                                                                               <button class="ui-btn app-num-pad-7" data-style="flat">7</button>
+                                                                               <button class="ui-btn app-num-pad-8" data-style="flat">8</button>
+                                                                               <button class="ui-btn app-num-pad-9" data-style="flat">9</button>
+                                                                               <button class="ui-btn app-num-pad" data-style="flat"></button>
+                                                                               <button class="ui-btn app-num-pad-0" data-style="flat">0</button>
+                                                                               <button class="ui-btn app-num-pad-done" data-style="flat">Done</button>
+                                                                       </div>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                       </section>
+                                       <section class="ui-content">
+                                               <div class="ui-card ui-card-service app-border">
+                                                       <div class="ui-header" data-expanding-enabled="false">
+                                                               <div class="ui-title">Typing Control</div>
+                                                               <div class="ui-icon app-typing-control-icon"></div>
+                                                       </div>
+                                                       <div class="ui-content">
+                                                               <link rel="stylesheet" href="./css/app-remote-control-channel.css" />
+                                                               <div class="app-input-with-button">
+                                                                       <input id="remote-typing" placeholder="Input text" type="text" data-outside-div="true" data-inline="true"/>
+                                                                       <a href="#" class="ui-btn app-voice-button" data-style="flat"></a>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                       </section>
+                                       <section class="ui-content">
+                                               <div class="ui-card ui-card-service app-border">
+                                                       <div class="ui-header">
+                                                               <div class="ui-title">Media Control</div>
+                                                               <div class="ui-icon app-media-control-icon"></div>
+                                                       </div>
+                                                       <div class="ui-content">
+                                                               <div class="app-media-progress">
+                                                                       <input type="range" min="0" max="150" value="30" data-labels="true"></input>
+                                                               </div>
+                                                               <div class="app-media-buttons">
+                                                                       <a href="#" class="ui-btn" data-style="flat">-10s</a>
+                                                                       <a href="#" class="ui-btn ui-btn-icon" data-icon="prev" data-style="flat"></a>
+                                                                       <a href="#" class="ui-btn ui-btn-icon" data-icon="play" data-style="flat"></a>
+                                                                       <a href="#" class="ui-btn ui-btn-icon" data-icon="next" data-style="flat"></a>
+                                                                       <a href="#" class="ui-btn" data-style="flat">+10s</a>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                       </section>
+                                       <section class="ui-content">
+                                               <div class="ui-card ui-card-service app-border">
+                                                       <div class="ui-header">
+                                                               <div class="ui-title">Game</div>
+                                                               <div class="ui-icon app-game-control-icon"></div>
+                                                       </div>
+                                                       <div class="ui-content">
+                                                               <div class="app-game-buttons">
+                                                                       <div class="app-game-4way-direction">
+                                                                               <button data-icon="up" data-style="flat"></button>
+                                                                               <button data-icon="left" data-style="flat"></button>
+                                                                               <button data-icon="right" data-style="flat"></button>
+                                                                               <button data-icon="down" data-style="flat"></button>
+                                                                       </div>
+                                                                       <div class="app-game-4buttons">
+                                                                               <button class="ui-btn ui-btn-icon app-game-4buttons-Y" data-style="flat"></button>
+                                                                               <button class="ui-btn ui-btn-icon app-game-4buttons-X" data-style="flat"></button>
+                                                                               <button class="ui-btn ui-btn-icon app-game-4buttons-B" data-style="flat"></button>
+                                                                               <button class="ui-btn ui-btn-icon app-game-4buttons-A" data-style="flat"></button>
+                                                                       </div>
+                                                               </div>
+                                                       </div>
+                                               </div>
+                                       </section>
+                               </div>
+                       </div>
+               </div>
+
+       </div>
+</body>
+</html>
diff --git a/d2d_app/client/css/app-remote-control-basic.css b/d2d_app/client/css/app-remote-control-basic.css
new file mode 100644 (file)
index 0000000..f7d49c8
--- /dev/null
@@ -0,0 +1,478 @@
+.app-remote-control {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    text-align: center;
+    padding: 5px 0;
+    flex-direction: column;
+}
+
+@media (max-height:641px) {
+    .app-home-buttons {
+        display: flex;
+        justify-content: space-between;
+        height: 28px;
+        padding: 0 20px;
+    }
+}
+@media (min-height:642px) {
+    .app-home-buttons {
+        display: flex;
+        justify-content: space-between;
+        height: 38px;
+        padding: 0 20px;
+    }
+}
+
+.ui-icon-home::after {
+    mask-image: url(../images/control/ic_home.png);
+    -webkit-mask-image: url(../images/control/ic_home.png);
+    mask-size: 24px !important;
+    -webkit-mask-size: 24px !important;
+}
+.ui-icon-enter::after {
+    mask-size: 26px 18px;
+    mask-image: url(../images/control/ic_source.png);
+    -webkit-mask-size: 26px 18px !important;
+    -webkit-mask-image: url(../images/control/ic_source.png);
+}
+.ui-icon-backward::after {
+    mask-size: 25px 23px !important;
+    -webkit-mask-size: 25px 23px !important;
+    mask-image: url(../images/ic_back.png);
+    -webkit-mask-image: url(../images/ic_back.png);
+}
+
+.app-volume-channel {
+    flex-direction: row;
+    width: calc(100% - 148px);
+    display: flex;
+    justify-content: space-between;
+}
+@media (max-height:641px) {
+    .app-volume-control {
+        display: flex;
+        flex-direction: column;
+        font-size: 16px;
+        background-image: linear-gradient(180deg,
+            transparent, transparent 25px, #ebebeb 25px,
+            #ebebeb 100px, transparent 100%);
+        width: 53px;
+        align-items: center;
+        height: 125px;
+        justify-content: space-between;
+    }
+}
+@media (min-height:642px) {
+    .app-volume-control {
+        display: flex;
+        flex-direction: column;
+        font-size: 16px;
+        background-image: linear-gradient(180deg,
+         transparent, transparent 25px, #ebebeb 25px,
+         #ebebeb 125px, transparent 100%);
+        width: 53px;
+        align-items: center;
+        height: 173px;
+        justify-content: space-between;
+    }
+}
+.app-btn-icon-volume-up {
+    background-image: url(../images/control/btn_plus.png);
+    background-size: 100%;
+    background-position-y: 2px;
+}
+.app-btn-icon-volume-up::after {
+    display: none;
+}
+.app-btn-icon-volume-down {
+    background-image: url(../images/control/btn_minus.png);
+    background-size: 100%;
+    background-position-y: 2px;
+}
+.app-btn-icon-volume-down::after {
+    display: none;
+}
+@media (max-height:641px) {
+    .app-channel-control {
+        display: flex;
+        flex-direction: column;
+        font-size: 16px;
+        background-image: linear-gradient(180deg,
+            transparent, transparent 25px, #ebebeb 25px,
+            #ebebeb 100px, transparent 100%);
+        width: 53px;
+        align-items: center;
+        height: 125px;
+        justify-content: space-between;
+    }
+}
+@media (min-height:642px) {
+    .app-channel-control {
+        display: flex;
+        flex-direction: column;
+        font-size: 16px;
+        background-image: linear-gradient(180deg,
+            transparent, transparent 25px, #ebebeb 25px,
+            #ebebeb 125px, transparent 100%);
+        width: 53px;
+        align-items: center;
+        height: 173px;
+        justify-content: space-between;
+    }
+}
+
+.app-btn-icon-channel-up {
+    background-image: url(../images/control/btn_up.png);
+    background-size: 100%;
+    background-position-y: 2px;
+}
+.app-btn-icon-channel-up::after {
+    display: none;
+}
+.app-btn-icon-channel-down {
+    background-image: url(../images/control/btn_down.png);
+    background-size: 100%;
+    background-position-y: 2px;
+}
+.app-btn-icon-channel-down::after {
+    display: none;
+}
+@media (max-height:641px) {
+    .app-4way-direction {
+        display: grid;
+        grid-template-columns: 25px 1fr 25px;
+        grid-template-rows: 25px 1fr 25px;
+        grid-gap: 5px;
+        width: 100%;
+        height: 130px;
+        justify-items: center;
+        background-color: #ebebeb;
+        border-radius: 32px;
+        margin-top: 10px;
+    }
+}
+@media (min-height:642px) {
+    .app-4way-direction {
+        display: grid;
+        grid-template-columns: 25px 1fr 25px;
+        grid-template-rows: 25px 1fr 25px;
+        grid-gap: 5px;
+        width: 100%;
+        height: 210px;
+        justify-items: center;
+        background-color: #ebebeb;
+        border-radius: 32px;
+        margin-top: 10px;
+    }
+}
+.app-remote-control .app-4way-direction .ui-btn.ui-btn-flat.ui-btn-icon {
+    max-width: 100%;
+    width: 100%;
+    height: 100%;
+    min-width: 32px;
+}
+
+.app-remote-control-icon {
+    background-color: var(--primary-color);
+    border-radius: 6px;
+    position: relative;
+}
+
+.app-remote-control-icon::after{
+    content: "";
+    width: 100%;
+    height: 100%;
+    position: absolute;
+    background-color: var(--color-white);
+    mask-size: 100%;
+    mask-image: url(../images/control/tw_list_icon_connections.svg);
+    -webkit-mask-size: 100%;
+    -webkit-mask-image: url(../images/control/tw_list_icon_connections.svg);
+}
+
+.app-4way-btn-up {
+    grid-column: 2 / 2;
+    grid-row: 1;
+    align-self: center;
+}
+
+.app-4way-btn-left {
+    grid-column: 1 / 1;
+    grid-row: 2;
+    align-self: center;
+}
+
+.app-4way-btn-right {
+    grid-column: 3 / 3;
+    grid-row: 2;
+    align-self: center;
+}
+
+.app-4way-btn-down {
+    grid-column: 2 / 2;
+    grid-row: 3;
+    align-self: center;
+}
+
+.app-4way-touchpad {
+    grid-column: 2 / 2;
+    grid-row: 2 / 2;
+    width: 100%;
+    border-radius: 28px;
+    background-color: #f4f4f4;
+}
+
+.app-remote-num-pad {
+    display: grid;
+    grid-gap: 5px;
+    width: 100%;
+    justify-items: center;
+    border-radius: 28px;
+    margin-top: 10px;
+    overflow: hidden;
+    grid-template-columns: 1fr 1fr 1fr;
+}
+.app-remote-num-pad .ui-btn {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: var(--text-color);
+    width: 100% !important;
+    height: 100%;
+    background-color: #ebebeb;
+    border-radius: 0;
+}
+.app-num-pad-1 {
+    grid-column: 1 / 1;
+    grid-row: 1;
+}
+.app-num-pad-2 {
+    grid-column: 2 / 2;
+    grid-row: 1;
+}
+.app-num-pad-3 {
+    grid-column: 3 / 3;
+    grid-row: 1;
+}
+.app-num-pad-4 {
+    grid-column: 1 / 1;
+    grid-row: 2;
+}
+.app-num-pad-5 {
+    grid-column: 2 / 2;
+    grid-row: 2;
+}
+.app-num-pad-6 {
+    grid-column: 3 / 3;
+    grid-row: 2;
+}
+
+.app-remote-control .ui-btn.ui-btn-flat.ui-btn-icon {
+    width: 58px;
+    height: 58px;
+    min-width: 58px;
+}
+.ui-btn.ui-icon-right::after {
+    -webkit-transform: translate(-50%, -50%) rotateZ(-90deg);
+    -ms-transform: translate(-50%, -50%) rotate(-90deg);
+    transform: translate(-50%, -50%) rotateZ(-90deg);
+}
+.ui-btn.ui-icon-left::after {
+    -webkit-transform: translate(-50%, -50%) rotateZ(90deg);
+    -ms-transform: translate(-50%, -50%) rotate(90deg);
+    transform: translate(-50%, -50%) rotateZ(90deg);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon::before {
+    width: 48px;
+    height: 48px;
+}
+
+.app-border {
+    box-shadow: 0 0 0 0.25px var(--content-area-line-color) inset;
+}
+
+/* Typing control */
+.app-typing-control-icon {
+    background-image: url(../images/control/squarcle_bg.png);
+    background-size: 100%;
+}
+.app-voice-button {
+    background-image: url(../images/control/default.png);
+    background-size: 100%;
+    width: 43px !important;
+    height: 43px !important;
+    display: inline-block;
+    max-width: 43px;
+    max-height: 43px;
+    background-repeat: no-repeat;
+    background-position: center;
+}
+.app-input-with-button {
+    display: flex;
+}
+
+/* media control */
+.app-media-buttons {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    height: 51px;
+    color: var(--color-black);
+}
+.app-media-buttons .ui-icon-prev::after {
+    mask-image: url(../images/control/ic_function_media_prev.svg);
+    -webkit-mask-image: url(../images/control/ic_function_media_prev.svg);
+}
+.app-media-buttons .ui-icon-next::after {
+    mask-image: url(../images/control/ic_function_media_next.svg);
+    -webkit-mask-image: url(../images/control/ic_function_media_next.svg);
+    transform: translate(-50%, -50%);
+}
+.app-media-buttons .ui-icon-pause::after {
+    mask-image: url(../images/control/ic_function_media_stop.svg);
+    -webkit-mask-image: url(../images/control/ic_function_media_stop.svg);
+}
+.app-media-buttons .ui-icon-play::after {
+    mask-image: url(../images/control/ic_control1_right.png);
+    -webkit-mask-image: url(../images/control/ic_control1_right.png);
+    mask-size: 20px !important;
+    -webkit-mask-size: 20px !important;
+}
+.app-media-buttons .ui-btn:not(.ui-btn-icon) {
+    width: 50px !important;
+    line-height: 32px;
+    color: var(--color-black);
+    font-size: 17px;
+}
+.app-media-progress .ui-slider-handler::after {
+    content: attr(data-value);
+    position: absolute;
+    left: -20%;
+    bottom: -18px;
+    font-size: 12px;
+    color: #999999;
+}
+.app-media-control-icon {
+    background-image: url(../images/control/squarcle_bg.png);
+    background-size: 100%;
+}
+
+/** game pad **/
+.app-game-4way-direction {
+    background-image: url("../images/control/control1_bg .png");
+    width: 157px;
+    height: 157px;
+    background-position: center;
+    background-size: 100%;
+    display: inline-grid;
+    grid-template-columns: 48px 1fr 48px;
+    grid-template-rows: 48px 1fr 48px;
+}
+.app-game-4way-direction .ui-icon-up {
+    grid-column: 2;
+    grid-row: 1;
+}
+.app-game-4way-direction .ui-icon-left {
+    grid-column: 1 / 1;
+    grid-row: 2;
+}
+.app-game-4way-direction .ui-icon-right {
+    grid-column: 3 / 3;
+    grid-row: 2;
+}
+.app-game-4way-direction .ui-icon-down {
+    grid-column: 2;
+    grid-row: 3;
+}
+.app-game-4way-direction .ui-btn {
+    justify-self: center;
+}
+.app-game-4way-direction .ui-btn::after {
+    justify-self: center;
+    mask-size: 12px !important;
+    -webkit-mask-size: 12px !important;
+    transform: translate(-50%, -50%);
+}
+
+.app-game-4way-direction .ui-icon-up::after {
+    mask-image: url(../images/control/ic_control1_top.png);
+    -webkit-mask-image: url(../images/control/ic_control1_top.png);
+}
+.app-game-4way-direction .ui-icon-down::after {
+    mask-image: url(../images/control/ic_control1_bottom.png);
+    -webkit-mask-image: url(../images/control/ic_control1_bottom.png);
+}
+.app-game-4way-direction .ui-icon-left::after {
+    mask-image: url(../images/control/ic_control1_left.png);
+    -webkit-mask-image: url(../images/control/ic_control1_left.png);
+}
+.app-game-4way-direction .ui-icon-right::after {
+    mask-image: url(../images/control/ic_control1_right.png);
+    -webkit-mask-image: url(../images/control/ic_control1_right.png);
+}
+.app-game-4buttons {
+    width: 157px;
+    height: 157px;
+    background-position: center;
+    background-size: 100%;
+    display: inline-grid;
+    grid-template-columns: 58px 35px 58px;
+    grid-template-rows: 58px 35px 58px;
+}
+.app-game-4buttons .ui-btn.ui-btn-icon {
+    background-image: url(../images/control/control2_bg\ .png);
+    background-size: 100%;
+    background-position-y: 2px;
+    min-width: 58px;
+    min-height: 58px;
+}
+.app-game-4buttons-Y {
+    grid-column: 2;
+    grid-row: 1;
+    justify-self: center;
+}
+.app-game-4buttons-X {
+    grid-column: 1;
+    grid-row: 2;
+    align-self: center;
+}
+.app-game-4buttons-B {
+    grid-column: 3;
+    grid-row: 2;
+    align-self: center;
+}
+.app-game-4buttons-A {
+    grid-column: 2;
+    grid-row: 3;
+    justify-self: center;
+}
+
+.app-game-4buttons .ui-btn.ui-btn-icon::after {
+    mask-image: none;
+    -webkit-mask-image: none;
+    background-color: transparent;
+    font-size: 16px;
+    text-align: center;
+    height: auto;
+}
+.app-game-4buttons-Y::after {
+    content: "Y";
+    color: #ffb100;
+}
+.app-game-4buttons-X::after {
+    content: "X";
+    color: #18a3ff;
+}
+.app-game-4buttons-B::after {
+    content: "B";
+    color: #ed3c36;
+}
+.app-game-4buttons-A::after {
+    content: "A";
+    color: #67ce2b;
+}
+.app-game-control-icon {
+    background-image: url(../images/control/squarcle_bg.png);
+    background-size: 100%;
+}
\ No newline at end of file
diff --git a/d2d_app/client/css/pincode.css b/d2d_app/client/css/pincode.css
new file mode 100644 (file)
index 0000000..7b5dbf8
--- /dev/null
@@ -0,0 +1,302 @@
+body {
+    height: 100%;
+    background: white;
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+    -ms-flex-align: center;
+    align-items: center;
+    -webkit-box-pack: center;
+    -webkit-justify-content: center;
+    -ms-flex-pack: center;
+    justify-content: center;
+    font-family: Open Sans;
+}
+
+body.wrong {
+    -webkit-animation: bg-red 1s ease-in;
+    animation: bg-red 1s ease-in;
+}
+
+body.correct {
+    -webkit-animation: bg-green 1s ease-in;
+    animation: bg-green 1s ease-in;
+}
+
+#pin {
+    background: #212121;
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-box-pack: center;
+    -webkit-justify-content: center;
+    -ms-flex-pack: center;
+    justify-content: center;
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+    -ms-flex-align: center;
+    align-items: center;
+    -webkit-box-orient: vertical;
+    -webkit-box-direction: normal;
+    -webkit-flex-direction: column;
+    -ms-flex-direction: column;
+    flex-direction: column;
+    padding: 1em;
+    border-radius: .3em;
+    box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3);
+    margin-top: 12px;
+    color: rgba(255, 255, 255, 1.0);
+}
+
+.dots {
+    width: 50%;
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-justify-content: space-around;
+    -ms-flex-pack: distribute;
+    justify-content: space-around;
+    padding: 1em;
+    padding-top: 3em;
+}
+
+.dot {
+    position: relative;
+    background: rgba(255, 255, 255, 0.2);
+    border-radius: 0.8em;
+    width: 0.8em;
+    height: 0.8em;
+    -webkit-transform: scale3d(0.7, 0.7, 0.7);
+    transform: scale3d(0.7, 0.7, 0.7);
+}
+
+.dot.active {
+    -webkit-animation: growDot .5s ease;
+    animation: growDot .5s ease;
+    -webkit-animation-fill-mode: forwards;
+    animation-fill-mode: forwards;
+}
+
+.dot.wrong {
+    -webkit-animation: wrong .9s ease;
+    animation: wrong .9s ease;
+}
+
+.dot.correct {
+    -webkit-animation: correct .9s ease;
+    animation: correct .9s ease;
+}
+
+#pin p { font-size: 1.0em; }
+
+.numbers {
+    display: -webkit-box;
+    display: -webkit-flex;
+    display: -ms-flexbox;
+    display: flex;
+    -webkit-flex-flow: row wrap;
+    -ms-flex-flow: row wrap;
+    flex-flow: row wrap;
+    -webkit-box-align: center;
+    -webkit-align-items: center;
+    -ms-flex-align: center;
+    align-items: center;
+    -webkit-justify-content: space-around;
+    -ms-flex-pack: distribute;
+    justify-content: space-around;
+    -webkit-align-content: flex-end;
+    -ms-flex-line-pack: end;
+    align-content: flex-end;
+    margin: 2em 0;
+}
+
+.number {
+    position: relative;
+    width: 2.5em;
+    height: 2.5em;
+    margin: 0.3em;
+    border-radius: 2.5em;
+    border: 2px solid rgba(255, 255, 255, 0);
+    text-align: center;
+    line-height: 2.5em;
+    font-weight: 400;
+    font-size: 1.8em;
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    -webkit-transition: all .5s ease;
+    transition: all .5s ease;
+}
+
+.number:hover { color: rgba(255, 255, 255, 0.5); }
+
+.number:hover:before { border: 2px solid rgba(255, 255, 255, 0.5); }
+
+.number:before {
+    content: "";
+    position: absolute;
+    left: -2px;
+    width: 2.5em;
+    height: 2.5em;
+    border: 2px solid rgba(255, 255, 255, 0.1);
+    border-radius: 2.5em;
+    -webkit-transition: all .5s ease;
+    transition: all .5s ease;
+}
+
+.number.grow:before {
+    -webkit-animation: grow .4s ease;
+    animation: grow .4s ease;
+}
+
+@-webkit-keyframes 
+growDot {
+    100% {
+        background: white;
+        -webkit-transform: scale3d(0.9, 0.9, 0.9);
+        transform: scale3d(0.9, 0.9, 0.9);
+    }
+}
+
+@keyframes 
+growDot {
+    100% {
+        background: white;
+        -webkit-transform: scale3d(0.9, 0.9, 0.9);
+        transform: scale3d(0.9, 0.9, 0.9);
+    }
+}
+
+@-webkit-keyframes 
+grow {
+    50% {
+        -webkit-transform: scale3d(1.5, 1.5, 1.5);
+        transform: scale3d(1.5, 1.5, 1.5);
+    }
+    100% {
+        -webkit-transform: scale3d(1, 1, 1);
+        transform: scale3d(1, 1, 1);
+    }
+}
+
+@keyframes 
+grow {
+    50% {
+        -webkit-transform: scale3d(1.5, 1.5, 1.5);
+        transform: scale3d(1.5, 1.5, 1.5);
+    }
+    100% {
+        -webkit-transform: scale3d(1, 1, 1);
+        transform: scale3d(1, 1, 1);
+    }
+}
+
+@-webkit-keyframes 
+wrong {
+    20% {
+        background: crimson;
+    }
+    40% {
+        -webkit-transform: translate(-15px, 0);
+        transform: translate(-15px, 0);
+    }
+    60% {
+        -webkit-transform: translate(10px, 0);
+        transform: translate(10px, 0);
+    }
+    80% {
+        -webkit-transform: translate(-5px, 0);
+        transform: translate(-5px, 0);
+    }
+}
+
+@keyframes 
+wrong {
+    20% {
+        background: crimson;
+    }
+    40% {
+        -webkit-transform: translate(-15px, 0);
+        transform: translate(-15px, 0);
+    }
+    60% {
+        -webkit-transform: translate(10px, 0);
+        transform: translate(10px, 0);
+    }
+    80% {
+        -webkit-transform: translate(-5px, 0);
+        transform: translate(-5px, 0);
+    }
+}
+
+@-webkit-keyframes 
+correct {
+    20% {
+        background: #1c72ad;
+    }
+    40% {
+        -webkit-transform: translate(0, -15px);
+        transform: translate(0, -15px);
+    }
+    60% {
+        -webkit-transform: translate(0, 10px);
+        transform: translate(0, 10px);
+    }
+    80% {
+        -webkit-transform: translate(0, -5px);
+        transform: translate(0, -5px);
+    }
+}
+
+@keyframes 
+correct {
+    20% {
+        background: #1c72ad;
+    }
+    40% {
+        -webkit-transform: translate(0, -15px);
+        transform: translate(0, -15px);
+    }
+    60% {
+        -webkit-transform: translate(0, 10px);
+        transform: translate(0, 10px);
+    }
+    80% {
+        -webkit-transform: translate(0, -5px);
+        transform: translate(0, -5px);
+    }
+}
+
+@-webkit-keyframes 
+bg-red {
+    50% {
+        background: crimson;
+    }
+}
+
+@keyframes 
+bg-red {
+    50% {
+        background: crimson;
+    }
+}
+
+@-webkit-keyframes 
+bg-green {
+    50% {
+        background: #1c72ad;
+    }
+}
+
+@keyframes 
+bg-green {
+    50% {
+        background: #1c72ad;
+    }
+}
index 583efde..c9c1750 100755 (executable)
-html, body {
-    width: 100%;
-    height: 100%;
-    margin: 0 auto;
-    padding: 0;
+.app-image-grid {
+    margin: auto;
+    display: grid;
+    grid-template-columns: repeat(3, 100px [col-start]);
+    grid-template-rows: auto;
+    gap: 10px;
+    justify-items: center;
+    justify-content: center;
+    padding: 20px;
 }
 
-#container {
-    width: 100%;
-    height: 100%;
-    display: table;
+.app-image-big-grid {
+    margin: auto;
+    display: grid;
+    grid-template-columns: repeat(1, 100px [col-start]);
+    grid-template-rows: auto;
+    gap: 10px;
+    justify-items: center;
+    justify-content: center;
+    padding: 20px;
 }
 
-.page {
-    width: 100%;
-    height: 100%;
-    padding-top: 50px;
-    display: block;
+.app-icon-img {
+    width: 100px;
+    height: 100px;
 }
 
-.header {
-    position: relative;
-    width: 100%;
-    height: 50px;
-    margin-top: -50px;
-    background-color: rgba(0, 80, 179, 1);
-    z-index: 999;
-    display: table;
+.app-icon-big-img {
+    width: 150px;
+    height: 150px;
 }
 
-.text-header {
-    color: #ffffff;
-    font-size: 1.5em;
-    vertical-align: middle;
-    text-align: center;
-    display: table-cell;
+.app-btn-icon-burger {
+    margin-left: 20px;
+    margin-right: 12px;
 }
 
-.contents {
-    width: 100%;
-    height: 100%;
-}
-
-.contents-name-detail {
-    font-size: 1.5em;
-    padding: 10px;
-}
-
-.icon-folder {
-    vertical-align: middle;
-}
-
-.detail {
-    width: 100%;
-    height: 100%;
+.app-btn-icon-burger::after {
+    -webkit-mask-image: url(../images/Hamburger_icon.svg);
+    mask-image: url(../images/Hamburger_icon.svg);
 }
 
-.result-table {
-    display: table;
-    text-align: center;
-    width: 100%;
-    height: 100%;
-    vertical-align: middle;
-}
-
-.result-table-row {
-    display: table;
+.app-dummy-payment input {
+    display: block;
+    font-size: 18px;
+    padding: 8px;
+    margin: 4px 0;
+    border-radius: 8px;
+    border: 1px solid #ddd;
+    box-sizing: border-box;
     width: 100%;
-    height: 60px;
-    vertical-align: middle;
-    border-bottom: 1px solid black;
-}
-
-.result-table-error {
-    display: table-cell;
-    font-size: 1.8em;
-    vertical-align: middle;
-    text-align: center;
 }
-
-.d2dApp-detail {
-    display: table-cell;
-    font-size: 1.2em;
-    vertical-align: middle;
-    text-align: left;
-    padding-left: 10px;
-    width: 100%;
+.app-dummy-payment input.ui-inline {
+    width: auto;
+    display: inline;
 }
 
-.text-error {
-    text-align: center;
-    color: rgba(0, 0, 0, 1);
-    font-size: 1.5em;
+body {
+    /*disable-pull-to-refresh-effect*/
+    overscroll-behavior: contain;
 }
 
-.spinner {
-    position:absolute;
-    top:50%;
-    left:50%;
-    transform:translate(-50%, -50%);
+.app-display-none {
     display: none;
 }
-
-.spinner-img {
-    border: 16px solid #f3f3f3;
-    border-top: 16px solid #3498db;
-    border-radius: 50%;
-    width: 120px;
-    height: 120px;
-    animation: spin 2s linear infinite;
-}
-
-@keyframes spin {
-    0% { transform: rotate(0deg); }
-    100% { transform: rotate(360deg); }
-}
diff --git a/d2d_app/client/images/Hamburger_icon.svg b/d2d_app/client/images/Hamburger_icon.svg
new file mode 100644 (file)
index 0000000..233bf21
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" ?><!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="32px" id="Layer_1" style="enable-background:new 0 0 32 32;" version="1.1" viewBox="0 0 32 32" width="32px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M4,10h24c1.104,0,2-0.896,2-2s-0.896-2-2-2H4C2.896,6,2,6.896,2,8S2.896,10,4,10z M28,14H4c-1.104,0-2,0.896-2,2  s0.896,2,2,2h24c1.104,0,2-0.896,2-2S29.104,14,28,14z M28,22H4c-1.104,0-2,0.896-2,2s0.896,2,2,2h24c1.104,0,2-0.896,2-2  S29.104,22,28,22z"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/images/control/btn_down.png b/d2d_app/client/images/control/btn_down.png
new file mode 100644 (file)
index 0000000..d00eaef
Binary files /dev/null and b/d2d_app/client/images/control/btn_down.png differ
diff --git a/d2d_app/client/images/control/btn_minus.png b/d2d_app/client/images/control/btn_minus.png
new file mode 100644 (file)
index 0000000..69e5b88
Binary files /dev/null and b/d2d_app/client/images/control/btn_minus.png differ
diff --git a/d2d_app/client/images/control/btn_plus.png b/d2d_app/client/images/control/btn_plus.png
new file mode 100644 (file)
index 0000000..303aacf
Binary files /dev/null and b/d2d_app/client/images/control/btn_plus.png differ
diff --git a/d2d_app/client/images/control/btn_up.png b/d2d_app/client/images/control/btn_up.png
new file mode 100644 (file)
index 0000000..f7012e3
Binary files /dev/null and b/d2d_app/client/images/control/btn_up.png differ
diff --git a/d2d_app/client/images/control/control1_bg .png b/d2d_app/client/images/control/control1_bg .png
new file mode 100644 (file)
index 0000000..5ebcc5b
Binary files /dev/null and b/d2d_app/client/images/control/control1_bg .png differ
diff --git a/d2d_app/client/images/control/control2_bg .png b/d2d_app/client/images/control/control2_bg .png
new file mode 100644 (file)
index 0000000..67920ef
Binary files /dev/null and b/d2d_app/client/images/control/control2_bg .png differ
diff --git a/d2d_app/client/images/control/cta/oval/default.png b/d2d_app/client/images/control/cta/oval/default.png
new file mode 100644 (file)
index 0000000..43818ea
Binary files /dev/null and b/d2d_app/client/images/control/cta/oval/default.png differ
diff --git a/d2d_app/client/images/control/default.png b/d2d_app/client/images/control/default.png
new file mode 100644 (file)
index 0000000..43818ea
Binary files /dev/null and b/d2d_app/client/images/control/default.png differ
diff --git a/d2d_app/client/images/control/ic_control1_bottom.png b/d2d_app/client/images/control/ic_control1_bottom.png
new file mode 100644 (file)
index 0000000..a9b8d11
Binary files /dev/null and b/d2d_app/client/images/control/ic_control1_bottom.png differ
diff --git a/d2d_app/client/images/control/ic_control1_left.png b/d2d_app/client/images/control/ic_control1_left.png
new file mode 100644 (file)
index 0000000..a26d81d
Binary files /dev/null and b/d2d_app/client/images/control/ic_control1_left.png differ
diff --git a/d2d_app/client/images/control/ic_control1_right.png b/d2d_app/client/images/control/ic_control1_right.png
new file mode 100644 (file)
index 0000000..657944d
Binary files /dev/null and b/d2d_app/client/images/control/ic_control1_right.png differ
diff --git a/d2d_app/client/images/control/ic_control1_top.png b/d2d_app/client/images/control/ic_control1_top.png
new file mode 100644 (file)
index 0000000..1ffd392
Binary files /dev/null and b/d2d_app/client/images/control/ic_control1_top.png differ
diff --git a/d2d_app/client/images/control/ic_function_media_next.svg b/d2d_app/client/images/control/ic_function_media_next.svg
new file mode 100644 (file)
index 0000000..e3be188
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 64 (93537) - https://sketch.com -->
+    <title>SVG/ic/ic_function_media_next</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M14.8063777,5.3 L14.8063777,11.1849791 L8.6458754,6.21236149 C8.47759173,6.07707461 8.28950997,6.00530657 8.10390298,6.00530657 C7.73433883,6.00530657 7.35982517,6.29732824 7.35982517,6.85414922 L7.35982517,17.1450259 C7.35982517,17.7043216 7.73433883,17.9938685 8.10390298,17.9938685 C8.29033489,17.9938685 8.47759173,17.9229254 8.64670032,17.7876385 L14.8063777,12.8158459 L14.8063777,18.7 L16.6401748,18.7 L16.6401748,5.3 L14.8063777,5.3 Z" id="path-1"></path>
+    </defs>
+    <g id="ic/ic_function_media_next" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <mask id="mask-2" fill="white">
+            <use xlink:href="#path-1"></use>
+        </mask>
+        <use id="mask" fill="#252525" xlink:href="#path-1"></use>
+    </g>
+</svg>
\ No newline at end of file
diff --git a/d2d_app/client/images/control/ic_function_media_prev.svg b/d2d_app/client/images/control/ic_function_media_prev.svg
new file mode 100644 (file)
index 0000000..3375154
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 64 (93537) - https://sketch.com -->
+    <title>SVG/ic/ic_function_media_prev</title>
+    <desc>Created with Sketch.</desc>
+    <defs>
+        <path d="M9.19262452,18.7 L9.19262452,12.8154836 L15.3535061,17.7875823 C15.5226251,17.9228775 15.7098935,17.993825 15.8963369,17.993825 C16.2650988,17.993825 16.6404605,17.7017854 16.6404605,17.1449301 L16.6404605,6.85424491 C16.6404605,6.29656467 16.2650988,6.00535 15.8963369,6.00535 C15.7090685,6.00535 15.5226251,6.07712245 15.3535061,6.21324263 L9.19262452,11.1845164 L9.19262452,5.3 L7.35953949,5.3 L7.35953949,18.7 L9.19262452,18.7 Z" id="path-1"></path>
+    </defs>
+    <g id="ic/ic_function_media_prev" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <mask id="mask-2" fill="white">
+            <use xlink:href="#path-1"></use>
+        </mask>
+        <use id="mask" fill="#252525" xlink:href="#path-1"></use>
+    </g>
+</svg>
\ No newline at end of file
diff --git a/d2d_app/client/images/control/ic_function_media_stop.svg b/d2d_app/client/images/control/ic_function_media_stop.svg
new file mode 100644 (file)
index 0000000..941c24b
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 64 (93537) - https://sketch.com -->
+    <title>SVG/ic/ic_function_media_stop</title>
+    <desc>Created with Sketch.</desc>
+    <g id="ic/ic_function_media_stop" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <rect id="Rectangle" fill="#252525" x="7" y="6" width="3" height="12"></rect>
+        <rect id="Rectangle" fill="#252525" x="14" y="6" width="3" height="12"></rect>
+    </g>
+</svg>
\ No newline at end of file
diff --git a/d2d_app/client/images/control/ic_home.png b/d2d_app/client/images/control/ic_home.png
new file mode 100644 (file)
index 0000000..d0127de
Binary files /dev/null and b/d2d_app/client/images/control/ic_home.png differ
diff --git a/d2d_app/client/images/control/ic_source.png b/d2d_app/client/images/control/ic_source.png
new file mode 100644 (file)
index 0000000..a7cda54
Binary files /dev/null and b/d2d_app/client/images/control/ic_source.png differ
diff --git a/d2d_app/client/images/control/squarcle_bg.png b/d2d_app/client/images/control/squarcle_bg.png
new file mode 100644 (file)
index 0000000..e101dff
Binary files /dev/null and b/d2d_app/client/images/control/squarcle_bg.png differ
diff --git a/d2d_app/client/images/control/tw_list_icon_connections.svg b/d2d_app/client/images/control/tw_list_icon_connections.svg
new file mode 100644 (file)
index 0000000..a08d6b6
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve" fill="#53a4ff">
+<title>settings/main_icon/01_connections copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_01_x5F_connections-copy">
+       <g id="Settings_x2F_Menu-tree_x2F_connections" transform="translate(8.000000, 8.000000)">
+               <path id="Connections" d="M52,68.4c1.2,0,2.4,0.5,3.3,1.4c0.7,0.7,1.1,1.6,1.3,2.5c0,0.2,0.1,0.3,0.1,0.5c0.1,1.3-0.4,2.6-1.3,3.6
+                       c-0.9,0.9-2.1,1.4-3.3,1.4c-1.2,0-2.4-0.5-3.3-1.4c-1-1.1-1.5-2.5-1.3-4c0-0.1,0-0.2,0.1-0.3c0.2-0.9,0.6-1.7,1.2-2.3
+                       C49.5,68.8,50.7,68.4,52,68.4z M51.9,55.1c6,0,11.4,2.5,15.2,6.5l0,0l-4.8,4.8c-2.6-2.8-6.3-4.5-10.5-4.5c-4.1,0-7.7,1.7-10.3,4.4
+                       l0,0l-4.8-4.8C40.7,57.5,46,55.1,51.9,55.1z M51.9,40.6c10,0,19,4.1,25.5,10.7l0,0l-4.7,4.7c-5.3-5.4-12.6-8.8-20.7-8.8
+                       c-8.1,0-15.4,3.3-20.6,8.6l0,0l-4.7-4.7C33,44.7,42,40.6,51.9,40.6z M51.9,26.3c13.9,0,26.5,5.7,35.6,14.9l0,0L82.8,46
+                       C74.9,38,64,33,51.9,33c-12,0-22.9,4.9-30.7,12.8l0,0l-4.7-4.7C25.5,32,38.1,26.3,51.9,26.3z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/images/folder.png b/d2d_app/client/images/folder.png
deleted file mode 100755 (executable)
index c8395f5..0000000
Binary files a/d2d_app/client/images/folder.png and /dev/null differ
diff --git a/d2d_app/client/images/ic_back.png b/d2d_app/client/images/ic_back.png
new file mode 100644 (file)
index 0000000..ab49ba8
Binary files /dev/null and b/d2d_app/client/images/ic_back.png differ
diff --git a/d2d_app/client/images/icon.png b/d2d_app/client/images/icon.png
new file mode 100755 (executable)
index 0000000..9765b1b
Binary files /dev/null and b/d2d_app/client/images/icon.png differ
diff --git a/d2d_app/client/images/tw_list_icon_wallpaper.svg b/d2d_app/client/images/tw_list_icon_wallpaper.svg
new file mode 100644 (file)
index 0000000..bb27344
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve" fill="#e87092">
+<title>settings/main_icon/05_wallpaper copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_05_x5F_wallpaper-copy">
+       <g id="Homescreen_x2F_wallpaper" transform="translate(8.000000, 8.000000)">
+               <g id="Aod_x2F_style_x28_theme_x29_">
+                       <path id="style_x28_theme_x29_" d="M69,75c0,0.7-0.6,1.3-1.3,1.3H36.3c-0.7,0-1.3-0.6-1.3-1.3v-7.6c0-1.2,0.8-1.9,0.8-2l7.4-6.9
+                               c0.5-0.5,1.3-0.5,1.8,0l3.6,3.5c0.5,0.5,1.3,0.5,1.7,0l9.1-8.9c0.5-0.5,1.2-0.5,1.7,0l7.2,7.4c0,0,0.7,0.6,0.7,1.5V75z
+                                M44.7,34.6c2.6,0,4.7,2.1,4.7,4.7c0,2.6-2.1,4.7-4.7,4.7c-2.6,0-4.7-2.1-4.7-4.7C40,36.7,42.1,34.6,44.7,34.6L44.7,34.6z
+                                M70,21.9H34c-2.8,0-5,2.2-5,5v50.2c0,2.8,2.2,5,5,5h36c2.8,0,5-2.3,5-5V26.9C75,24.1,72.8,21.9,70,21.9L70,21.9z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/invited.html b/d2d_app/client/invited.html
new file mode 100644 (file)
index 0000000..332e212
--- /dev/null
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+       <meta charset="UTF-8">
+       <meta name="viewport" content="width=device-width, user-scalable=no">
+       <title>My Device App</title>
+       <link href="lib/tau/mobile/theme/default/tau.css" rel="stylesheet" />
+       <link rel="stylesheet" href="css/style.css" />
+       <script data-build-remove="false" src="lib/tau/mobile/js/tau.js"></script>
+       <script src="js/app.js" type="module"></script>
+       <script src="js/invited.js" type="module"></script>
+</head>
+
+<body>
+       <div class="ui-page ui-page-active" id="main">
+               <header>
+               </header>
+               <div class="ui-content" id="page-invited">
+                       <div class="ui-content-area" id="d2dApps" style="background-color:snow;">
+                               <div style="margin-top: 70px; margin-left: 20px; margin-bottom: 20px;">
+                                       <h3>Would you like to join the room?</h3>
+                               </div>
+                               <div class="app-image-big-grid" id="d2dAppList">
+                               </div>
+                       </div>
+               </div>
+       </div>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/d2d_app/client/js/actions.js b/d2d_app/client/js/actions.js
new file mode 100644 (file)
index 0000000..b158f2c
--- /dev/null
@@ -0,0 +1,58 @@
+const serverPort = 9000;
+const serverURL = window.location.protocol + '//' + window.location.hostname;
+
+class Actions {
+    /**
+     * Launch App on TV
+     * This method creates function for onclick listener
+     * @param {string} appPkgID
+     * @param {string} appAppID
+     * @param {Function} callback
+     * @returns {Function}
+     */
+
+    launchAppOnTV(appPkgID, appAppID, callback) {
+        const xhr = new XMLHttpRequest();
+
+        var self = this;
+        var retFunc = function() {
+            var data = {
+                appPkgID: appPkgID,
+                appAppID: appAppID
+            };
+            self.sendDataToApp(appAppID, data, callback);
+        };
+        return retFunc;
+    };
+
+    /**
+     * Send data to host
+     * @param {string} appID
+     * @param {Object} data
+     * @param {Function} callback
+     */
+    sendDataToApp(appID, data, callback) {
+        const xhr = new XMLHttpRequest();
+        // add tv app id
+        data.appAppID = appID;
+        data.appPkgID = appID.replace(/\..+$/, "");
+
+        xhr.onreadystatechange = function() {
+            if (xhr.readyState === xhr.DONE) {
+                if (xhr.status === 200 || xhr.status === 201) {
+                    var response = JSON.parse(xhr.responseText);
+                    if (typeof callback === "function") {
+                        callback(response);
+                    }
+                } else {
+                    console.error(xhr.responseText);
+                }
+            }
+        }
+        xhr.open('POST', serverURL + ':' + serverPort + '/app');
+        xhr.setRequestHeader('Content-Type', 'application/json');
+        xhr.send(JSON.stringify(data));
+    };
+}
+
+export default Actions;
diff --git a/d2d_app/client/js/app.js b/d2d_app/client/js/app.js
new file mode 100644 (file)
index 0000000..d717a9a
--- /dev/null
@@ -0,0 +1,513 @@
+import Storage from "./clipping-storage.js";
+import Actions from './actions.js';
+import { openAppWindow } from './myApps.js';
+
+const moduleapp = {};
+
+(function () {
+       "use strict";
+       var tau = window.tau,
+               HomeApp = function () {
+                       this.version = "0.1";
+                       this.appsList = [];
+               },
+               prototype = HomeApp.prototype,
+               storage = new Storage(),
+               actions = new Actions(),
+               appsList = [],
+               socket = null,
+               homeApp;
+
+       const defaultList = [],
+               getAppsList = new Promise((resolve, reject) => {
+                       const requestURL = "client/updateWebclip";
+
+                       fetch(requestURL)
+                               .then((response) => response.json())
+                               .then((response) => {
+                                       //addWSListener(data.wsPort);
+                                       resolve(response.data.apps);
+                               })
+                               .catch((e) => {
+                                       reject(e);
+                               })
+               });
+
+       function updateAppsList(message) {
+               if (message.type === "full") {
+                       return updateAppsListFull(message.data);
+               } else if (message.type === "diff") {
+                       updateAppsListDiff(message.data);
+                       return true;
+               } else {
+                       console.warn("app.js: unsupported type of applist.");
+               }
+               return false;
+       }
+
+       function updateAppsListDiff(apps) {
+               apps.forEach(function (remoteApp) {
+                       if (remoteApp.action === "add") { // add (or update if app already added)
+                               let localApp = appsList.filter(function (localApp) {
+                                       return remoteApp.appID === localApp.appID;
+                               })[0];
+                               delete remoteApp.action;
+
+                               if (!localApp) { // add new
+                                       appsList.push(remoteApp);
+                               } else { // update local app
+                                       /**
+                                        * @todo
+                                        * Which properties we need update
+                                        */
+                                       localApp.isActive = remoteApp.isActive;
+                               }
+                       } else if (remoteApp.action === "remove") { // remove local app
+                               appsList = appsList.filter(function (localApp) {
+                                       return remoteApp.appID !== localApp.appID;
+                               });
+                       } else {
+                               console.warn("Unsupported action:", remoteApp.action);
+                       }
+
+               });
+
+               updateOrderOfApplist();
+       }
+
+       function updateOrderOfApplist() {
+               var change = false,
+                       currentOrder = "";
+
+               currentOrder = appsList.reduce(function (prev, app) {
+                       return prev + app.appID;
+               }, "");
+
+               // check apps order
+               appsList = appsList.sort(function (app1, app2) {
+                       return (app1.isActive) ?
+                               (app2.isActive) ? 0 : -1 : 1
+               });
+
+               // order has been changed
+               if (currentOrder !== appsList.reduce(function (prev, app) {
+                       return prev + app.appID;
+               }, "")) {
+                       change = true;
+               }
+
+               return change;
+       }
+
+       function updateAppsListFull(apps) {
+               var change = false,
+                       appsCount = appsList.length;
+
+               // remove app from local apps list if not exists on remote host
+               appsList = appsList.filter(function (localApp) {
+                       return apps.some(function (remoteApp) {
+                               return remoteApp.appID === localApp.appID;
+                       });
+               });
+
+               if (appsCount !== appsList.length) {
+                       change = true;
+               }
+
+               // filter app which should be add to local apps list
+               const added = apps.filter(function (remoteApp) {
+                       return !appsList.some(function (localApp) {
+                               return localApp.appID === remoteApp.appID;
+                       });
+               });
+
+               if (added.length) {
+                       change = true;
+               }
+
+               // add apps to local apps list
+               added.forEach(function (remoteApp) {
+                       appsList.push(remoteApp);
+               });
+
+               // update active items
+               appsList.forEach(function (localApp) {
+                       apps.forEach(function (remoteApp) {
+                               if (remoteApp.appID === localApp.appID) {
+                                       if (localApp.isActive !== remoteApp.isActive) {
+                                               localApp.isActive = remoteApp.isActive;
+                                               change = true;
+                                       }
+                               }
+                       })
+               });
+
+               if (updateOrderOfApplist()) {
+                       change = true;
+               };
+
+               return change;
+       }
+       function onWSMessage(message) {
+               if (updateAppsList(message)) {
+                       tau.log("change");
+                       storage.refreshStorage(Storage.elements.APPSLIST, appsList);
+
+                       updateWebClipsUI();
+                       updateWebClipListPopup();
+               } else {
+                       tau.log("nothing change");
+               }
+       }
+       async function getManifests() {
+               const promisesList = [],
+                       indexesList = [];
+
+               let responses = [];
+
+               appsList.forEach(function (app, appIndex) {
+                       app.webClipsList.forEach(function (webClip, webClipIndex) {
+                               promisesList.push(
+                                       fetch(webClip.url + "\\manifest.json")
+                               );
+                               indexesList.push({ appIndex: appIndex, webClipIndex: webClipIndex });
+                       });
+               });
+
+               responses = await Promise.allSettled(promisesList);
+
+               for (let responseIndex = 0; responseIndex < responses.length; responseIndex++) {
+                       const response = responses[responseIndex];
+
+                       if (response.status === "rejected" || !response.value.ok) {
+                               appsList[indexesList[responseIndex].appIndex].webClipsList.splice(indexesList[responseIndex].webClipIndex, 1);
+                       } else {
+                               const contentPromise = await response.value.json();
+
+                               appsList[indexesList[responseIndex].appIndex].webClipsList[indexesList[responseIndex].webClipIndex].manifest = contentPromise;
+                       }
+               }
+       }
+
+       function changeTheme(event) {
+               tau.theme.setTheme(event.target.value);
+       }
+
+       function onPopupSubmit() {
+               appsList.forEach(function (app) {
+                       app.webClipsList.forEach(function (webclip) {
+                               const webClipName = getWebClipName(webclip.url),
+                                       checkbox = document.getElementById("popup-checkbox-" + webClipName);
+
+                               webclip.isSelected = checkbox.checked;
+                       })
+               });
+               storage.refreshStorage(Storage.elements.APPSLIST, appsList);
+
+               updateWebClipsUI();
+               tau.history.back();
+       }
+
+       /**
+     * Click button event handler
+     * Opens drawer
+     */
+       function onButtonClick() {
+               var drawerWidget = tau.widget.Drawer(document.querySelector(".ui-drawer"));
+
+               drawerWidget.open();
+       }
+       function onDone(result) {
+               console.log("onDone", result);
+       }
+       function createWebClipCard(webClip, appID) {
+               var card = document.createElement("div"),
+                       webClipUrl = webClip.url;
+
+               // add slash for name of webClip
+               if (!webClipUrl.match(/\/$/)) {
+                       webClipUrl += "/";
+               }
+               webClipUrl += "webclip.html";
+
+               card.classList.add("ui-card");
+               card.setAttribute("data-src", webClipUrl);
+               card.addEventListener("webclip-message", function (ev) {
+                       if (ev.detail.remoteui)
+                               actions.sendDataToApp(appID, ev.detail, openAppWindow);
+                       else
+                               actions.sendDataToApp(appID, ev.detail, onDone);
+               });
+
+               return card;
+       }
+
+
+       homeApp = new HomeApp();
+
+       prototype.createControlCard = function (data) {
+               var controlCard = document.createElement("div"),
+                       title = document.createElement("span"),
+                       icon = document.createElement("div"),
+                       img = document.createElement("img"),
+                       a = document.createElement("a");
+
+               controlCard.classList.add("ui-content-area");
+               icon.classList.add("ui-icon");
+               title.classList.add("ui-title");
+               title.textContent = data.title;
+               img.src = data.icon;
+               a.href = data.href || "#next-control";
+               a.setAttribute("data-style", "flat");
+               a.setAttribute("data-inline", true);
+               a.setAttribute("data-icon", "next");
+               a.classList.add("ui-btn");
+
+               icon.appendChild(img);
+
+               controlCard.appendChild(icon);
+               controlCard.appendChild(title);
+               controlCard.appendChild(a);
+
+               return controlCard;
+       }
+
+       prototype.addControlCard = function (data) {
+               var controlCard = this.createControlCard(data),
+                       appBarElement = document.querySelector(".ui-page-active header"),
+                       appBar = tau.widget.Appbar(appBarElement);
+
+               controlCard.setAttribute("data-title", data.title);
+
+               appBar.addInstantContainer(controlCard);
+       }
+
+       prototype.removeControlCard = function (card) {
+               var appBarElement = document.querySelector(".ui-page-active header"),
+                       appBar = tau.widget.Appbar(appBarElement);
+
+               appBar.removeInstantContainer(card);
+       }
+
+       function updateWebClipsUI() {
+               var webclipsContainer = document.getElementById("web-clips"),
+                       // get Cards elements and convert NodeList to array
+                       currentWebClipsCards = [].slice.call(webclipsContainer.querySelectorAll(".ui-card[data-url],.ui-card[data-src]")),
+                       // list of webClips url in order
+                       webClipsUrlList = appsList.reduce(function (prev, app) {
+                               return prev.concat(
+                                       app.webClipsList.filter((webClip) => webClip.isSelected)
+                                               .map((webClip) => webClip.url));
+                       }, []);
+
+               // remove card
+               currentWebClipsCards.forEach(function (card) {
+                       const found = webClipsUrlList.filter(function (webClipUrl) {
+                               return card.dataset.url && card.dataset.url.indexOf(webClipUrl) > -1 ||
+                                       card.dataset.src && card.dataset.src.indexOf(webClipUrl) > -1;
+                       });
+
+                       // remove card from UI if not exists on list
+                       if (found.length === 0) {
+                               card.parentElement.removeChild(card);
+                       }
+               });
+
+               // add card
+               appsList.forEach(function (app) {
+                       app.webClipsList.forEach((webClip) => {
+                               const found = currentWebClipsCards.filter(function (card) {
+                                       return card.dataset.url && card.dataset.url.indexOf(webClip.url) > -1 ||
+                                               card.dataset.src && card.dataset.src.indexOf(webClip.url) > -1;
+                               });
+
+                               if (found.length === 0) {
+                                       if (webClip.isSelected) {
+                                               webclipsContainer.appendChild(
+                                                       createWebClipCard(webClip, app.appID)
+                                               );
+                                       }
+                               }
+                       });
+               });
+
+               // set proper order of cards
+               // @todo change inline styles to css class after merge HomeApp branches
+               webclipsContainer.style.display = "flex";
+               webclipsContainer.style.flexDirection = "column";
+               currentWebClipsCards = [].slice.call(webclipsContainer.querySelectorAll(".ui-card[data-url],.ui-card[data-src]"));
+
+               webClipsUrlList.forEach(function (url, order) {
+                       const card = currentWebClipsCards.filter(function (card) {
+                               return card.dataset.url && card.dataset.url.indexOf(url) > -1 ||
+                                       card.dataset.src && card.dataset.src.indexOf(url) > -1;
+                       })[0];
+
+                       if (card) {
+                               card.style.order = order;
+                       }
+               });
+
+               // add/remove mini control cards
+               appsList.forEach(function (app) {
+                       app.webClipsList.forEach((webClip) => {
+                               if (webClip.manifest && webClip.manifest.cardType === "control") {
+                                       if (webClip.isSelected) {
+                                               if (!document.querySelector("[data-title='" + webClip.manifest.description + "']")) {
+                                                       homeApp.addControlCard({
+                                                               title: webClip.manifest.description,
+                                                               href: "#open-control-card",
+                                                               icon: "images/Icon.png"
+                                                       }
+                                                       );
+                                               }
+                                       } else if (document.querySelector("[data-title='" + webClip.manifest.description + "']")) {
+                                               // remove mini controll card
+                                               homeApp.removeControlCard(document.querySelector("[data-title='" + webClip.manifest.description + "']"));
+                                       }
+                               }
+                       });
+               });
+
+               tau.engine.createWidgets(webclipsContainer);
+       }
+
+       //TODO: provide mechanism for getting web clip name from webClip meta data
+       //              and separate from getting ID
+       function getWebClipName(webClip) {
+               // remove all text to the last \
+               return webClip.replace(/.*\//, "");
+       }
+
+       function updateWebClipListPopup() {
+
+               var popupList = document.getElementById("popup-list");
+
+               // remove previous li items
+               while (popupList.firstChild) {
+                       popupList.firstChild.remove()
+               }
+
+               appsList.forEach(function (app) {
+                       app.webClipsList.forEach(function (webclip) {
+                               var li = document.createElement("li"),
+                                       input = document.createElement("input"),
+                                       label = document.createElement("label"),
+                                       webClipName = getWebClipName(webclip.url);
+
+                               li.classList.add("ui-li-has-checkbox");
+                               li.classList.add("ui-group-index");
+
+                               input.setAttribute("type", "checkbox");
+                               input.setAttribute("id", "popup-checkbox-" + webClipName);
+
+                               label.setAttribute("for", "popup-checkbox-" + webClipName);
+                               label.classList.add("ui-li-text");
+                               label.innerHTML = webclip.manifest && webclip.manifest.description || webClipName;
+
+                               li.appendChild(input);
+                               li.appendChild(label);
+                               popupList.appendChild(li);
+                       });
+               });
+
+               tau.engine.createWidgets(popupList);
+
+               appsList.forEach(function (app) {
+                       app.webClipsList.forEach(function (webclip) {
+                               if (webclip.isSelected) {
+                                       const webClipName = getWebClipName(webclip.url),
+                                               checkbox = document.getElementById("popup-checkbox-" + webClipName);
+
+                                       if (checkbox) {
+                                               checkbox.checked = true;
+                                       }
+                               }
+                       });
+               });
+       }
+
+       function init() {
+               var themeChanger = document.querySelector("#theme-selector"),
+                       page = document.querySelector(".ui-page"),
+                       themeChangerButton = page.querySelector("#selector-opener"),
+                       burgerButton = page.querySelector(".app-btn-icon-burger"),
+                       popupButton = page.querySelector("#popup-submit");
+
+               themeChanger.addEventListener("change", changeTheme);
+
+               themeChangerButton.addEventListener("vclick", function () {
+                       var dropdownmenuWidget = tau.widget.DropdownMenu(themeChanger);
+
+                       dropdownmenuWidget.open();
+               });
+
+               burgerButton.addEventListener("click", onButtonClick);
+               popupButton.addEventListener("click", onPopupSubmit);
+
+               // use apps list from storage or default apps list if sth wrong
+               appsList = storage.readAllFromStorage(Storage.elements.APPSLIST);
+
+               // check webclips on remote server
+               getAppsList.then((apps) => {
+                       updateAppsListFull(apps);
+               }).catch((e) => {
+                       console.warn("Error getting app lits: " + e.message);
+                       if (appsList.length === 0) {
+                               updateAppsListFull(defaultList);
+                       }
+               }).finally(() => {
+                       // check webclips access
+                       getManifests().then(() => {
+                               storage.refreshStorage(Storage.elements.APPSLIST, appsList);
+                               updateWebClipsUI();
+                               updateWebClipListPopup();
+                       });
+               });
+       }
+
+       function onPageBeforeShow(event) {
+               if (event.target.id === "main") {
+                       init();
+               }
+       }
+
+       /**
+        * Map array of D2D apps to webclip list
+        * @param {Array} dataApps 
+        */
+       function d2dAppsToWebClipsList(dataApps) {
+               var result = [];
+               var webclips = [];
+
+               dataApps.forEach(function (app) {
+                       webclips = [];
+                       if (app.webclip && app.webclip.manifest) {
+                               webclips.push({
+                                       url: 'client/webclip/' + app.webclip.manifest.name,
+                                       isSelected: true
+                               });
+                       }
+                       result.push({
+                               appID: app.d2dApp.appAppID,
+                               pkgID: app.d2dApp.appPkgID,
+                               isInstalled: true,
+                               isActive: false,
+                               webClipsList: webclips
+                       });
+               });
+               return result;
+       }
+
+       document.addEventListener("pagebeforeshow", onPageBeforeShow);
+       moduleapp.onWSMessage = onWSMessage;
+       moduleapp.d2dAppsToWebClipsList = d2dAppsToWebClipsList;
+}());
+
+export function UpdateWebClip(message) {
+       var data = {
+               type: "full",
+               data: moduleapp.d2dAppsToWebClipsList(message)
+       }
+       moduleapp.onWSMessage(data);
+};
index ea2b591..3e1a6a1 100755 (executable)
@@ -1,134 +1,5 @@
-/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-"use strict";
-
-const serverPort = 9000;
-const serverURL = window.location.protocol + '//' + window.location.hostname;
-(function() {
-    var xhr ;
-    function emptyElement(elm) {
-        while (elm.firstChild) {
-            elm.removeChild(elm.firstChild);
-        }
-        return elm;
-    }
-
-    function showListView(dataArray) {
-        var objResult = emptyElement(document.querySelector("#detail-main")),
-            objTable,
-            objRow,
-            objCol,
-            i,
-            prop;
-
-        objTable = document.createElement("div");
-        objTable.className = "result-table";
-
-        if (dataArray.length > 0) {
-            for (i = 0; i < dataArray.length; i++) {
-                objRow = document.createElement("div");
-
-                objRow.className = "result-table-row";
-                for (prop in dataArray[i]) {
-                    if (dataArray[i].hasOwnProperty(prop)) {
-                        objCol = document.createElement("div");
-                        objCol.className = prop + "-detail";
-                        if (dataArray[i][prop].hasOwnProperty("appName")) {
-                            objCol.appendChild(document.createTextNode(dataArray[i][prop].appName));
-                        }
-                        objCol.addEventListener("click", sendAppID(dataArray[i][prop].appPkgID, dataArray[i][prop].appAppID));
-                        objRow.appendChild(objCol);
-                    }
-                }
-                objTable.appendChild(objRow);
-            }
-        } else {
-            objRow = document.createElement("div");
-            objRow.className = "result-table-error";
-            objRow.appendChild(document.createTextNode("No Data"));
-            objTable.appendChild(objRow);
-        }
-
-        objResult.appendChild(objTable);
-    }
-
-    function showList() {
-        xhr = new XMLHttpRequest();
-        xhr.onreadystatechange = function() {
-          if (xhr.readyState === xhr.DONE) {
-            if (xhr.status === 200 || xhr.status === 201) {
-              showListView(JSON.parse(xhr.responseText));
-            } else {
-              console.error(xhr.responseText);
-            }
-          }
-        };
-        xhr.open('GET', serverURL + ':' + serverPort + '/appList');
-        xhr.send();
-    }
-
-    function sendAppID(appPkgID, appAppID) {
-        var retFunc = function() {
-            var data = {
-                appPkgID: appPkgID,
-                appAppID: appAppID
-            };
-            xhr.onreadystatechange = function() {
-                if (xhr.readyState === xhr.DONE) {
-                    if (xhr.status === 200 || xhr.status === 201) {
-                        var res = JSON.parse(xhr.responseText);
-                        document.getElementById("page-main").style.display = "none";
-                        document.getElementById("spinner-main").style.display = "block";
-                        var timer = setTimeout(function(){
-                            clearTimeout(timer);
-                            document.getElementById("page-main").style.display = "block";
-                            document.getElementById("spinner-main").style.display = "none";
-                            window.open(serverURL + ':' + res.port + '/app', 'newWindow');
-                        }, 1000);
-                    } else {
-                        console.error(xhr.responseText);
-                    }
-                }
-            }
-            xhr.open('POST', serverURL + ':' + serverPort + '/app');
-            xhr.setRequestHeader('Content-Type', 'application/json');
-            xhr.send(JSON.stringify(data));
-        };
-        return retFunc;
-    }
-
-    function init() {
-        var eventSource = new EventSource(serverURL + ':' + serverPort + '/updateAppList');
-        eventSource.addEventListener('message', evt => {
-            showListView(JSON.parse(evt.data));
-        }, false);
-        eventSource.addEventListener('open', evt => {
-           console.log("Connected to...");
-        }, false);
-        eventSource.addEventListener('error', evt => {
-            if (evt.target.readyState == EventSource.CLOSED) {
-                console.log("Disconnected from...");
-            } else if (evt.target.readyState == EventSource.CONNECTING) {
-                console.log('Connecting to...');
-            }
-        }, false);
-        showList();
-    }
-
-    /**
+(function () {
+       /**
         * Back key event handler
         */
        window.addEventListener("tizenhwkey", function (ev) {
@@ -156,7 +27,4 @@ const serverURL = window.location.protocol + '//' + window.location.hostname;
                        }
                }
        });
-
-    window.onload = init;
 }());
-
diff --git a/d2d_app/client/js/clipping-storage.js b/d2d_app/client/js/clipping-storage.js
new file mode 100644 (file)
index 0000000..02af624
--- /dev/null
@@ -0,0 +1,24 @@
+class Storage {
+       constructor() {
+               this.appsList = JSON.parse(localStorage.getItem("appsList")) || [];
+       }
+
+       refreshStorage(element, data = []) {
+               this[element] = data;
+               localStorage.setItem(element, JSON.stringify(this[element]));
+       }
+
+       writeToStorage(element, link) {
+               this[element].push(link);
+               localStorage.setItem(element, JSON.stringify(this[element]));
+       }
+
+       readAllFromStorage(element) {
+               return this[element];
+       }
+
+}
+
+Storage.elements = {APPSLIST: "appsList"};
+
+export default Storage;
\ No newline at end of file
diff --git a/d2d_app/client/js/control.js b/d2d_app/client/js/control.js
new file mode 100644 (file)
index 0000000..79f82ec
--- /dev/null
@@ -0,0 +1,211 @@
+const KeyCode = {
+       BACK: 9,
+       _1: 10,
+       _2: 11,
+       _3: 12,
+       _4: 13,
+       _5: 14,
+       _6: 15,
+       _7: 16,
+       _8: 17,
+       _9: 18,
+       _0: 19,
+       RETURN: 36,
+       HOME: 71,
+       VOLUME_DOWN: 75,
+       VOLUME_UP: 76,
+       CHANNEL_DOWN: 95,
+       CHANNEL_UP: 96,
+       UP: 111,
+       LEFT: 113,
+       RIGHT: 114,
+       DOWN: 116,
+       //POWER: 124,
+       EXIT: 182,
+};
+
+var websocket;
+
+(function () {
+       var page = document.getElementById("open-control-app-1");
+
+       function onPageShow() {
+               var x = window.innerWidth / 2;
+               var y = window.innerHeight / 2;
+
+               var id;
+               var SERVER = -1;
+               var link = document.location.href;
+               var pkgId = "2FUI52kIJP";
+               var wsUri = "ws://" + link.split("/")[2] + "/" + pkgId;
+
+               websocket = new WebSocket(wsUri);
+               websocket.onmessage = function(evt) {
+                       var json = JSON.parse(evt.data);
+                       if (json.id == SERVER && json.type == "id")
+                               id = json.data;
+               };
+
+               function sendMessage(type, data) {
+                       var packet = {type: type, data: data, id: id};
+                       websocket.send(JSON.stringify(packet));
+               }
+
+               var volup= page.querySelector(".app-btn-icon-volume-up"),
+                       voldown= page.querySelector(".app-btn-icon-volume-down"),
+                       channelup= page.querySelector(".app-btn-icon-channel-up"),
+                       channeldown= page.querySelector(".app-btn-icon-channel-down"),
+                       up= page.querySelector(".app-4way-btn-up"),
+                       down= page.querySelector(".app-4way-btn-down"),
+                       right= page.querySelector(".app-4way-btn-right"),
+                       left= page.querySelector(".app-4way-btn-left"),
+                       enter= page.querySelector(".app-btn-enter"),
+                       home= page.querySelector(".app-btn-home"),
+                       backward= page.querySelector(".app-btn-backward"),
+                       touchpad= page.querySelector(".app-4way-touchpad"),
+                       num1 = page.querySelector(".app-num-pad-1"),
+                       num2 = page.querySelector(".app-num-pad-2"),
+                       num3 = page.querySelector(".app-num-pad-3"),
+                       num4 = page.querySelector(".app-num-pad-4"),
+                       num5 = page.querySelector(".app-num-pad-5"),
+                       num6 = page.querySelector(".app-num-pad-6"),
+                       num7 = page.querySelector(".app-num-pad-7"),
+                       num8 = page.querySelector(".app-num-pad-8"),
+                       num9 = page.querySelector(".app-num-pad-9"),
+                       num0 = page.querySelector(".app-num-pad-0"),
+                       mediaProgress = page.querySelector(".app-media-progress input"),
+                       progressHandler = page.querySelector(".app-media-progress .ui-slider-handler"),
+                       labelMin = page.querySelector(".app-media-progress .ui-slider-label-min"),
+                       labelMax = page.querySelector(".app-media-progress .ui-slider-label-max");
+
+               volup.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.VOLUME_UP});
+               });
+               voldown.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.VOLUME_DOWN});
+               });
+               channelup.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.CHANNEL_UP});
+               });
+               channeldown.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.CHANNEL_DOWN});
+               });
+               up.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.UP});
+               });
+               down.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.DOWN});
+               });
+               right.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.RIGHT});
+               });
+               left.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.LEFT});
+               });
+               enter.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.RETURN});
+               });
+               backward.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.BACK});
+               });
+               home.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode.HOME});
+               });
+               num1.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._1});
+               });
+               num2.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._2});
+               });
+               num3.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._3});
+               });
+               num4.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._4});
+               });
+               num5.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._5});
+               });
+               num6.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._6});
+               });
+               num7.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._7});
+               });
+               num8.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._8});
+               });
+               num9.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._9});
+               });
+               num0.addEventListener("click", function () {
+                       sendMessage("keypress", {keycode: KeyCode._0});
+               });
+
+               var ontouch = function (ev) {
+                       switch (ev.type) {
+                               case "click" :
+                                       sendMessage("click");
+                                       break;
+                               case "touchstart" :
+                                       x = ev.touches[0].pageX;
+                                       y = ev.touches[0].pageY;
+                                       break;
+                               case "touchmove" :
+                                       ev.stopPropagation();
+                                       // lock the default web engine behaviour eg. scrolling
+                                       ev.preventDefault();
+                                       sendMessage("touchmove", {x: ev.touches[0].pageX - x, y: ev.touches[0].pageY - y});
+                                       x = ev.touches[0].pageX;
+                                       y = ev.touches[0].pageY;
+                                       break;
+                               case "touchend" :
+                                       break;
+                       }
+               },
+               onProgressTouchmove = function (ev) {
+                       // lock the section change event listener
+                       ev.stopPropagation();
+               },
+               toTimeString = function (value) {
+                       return Math.floor(value / 60) + ":" +
+                               ((value % 60 < 10) ? ("0" + value % 60) : value % 60);
+               },
+               onProgressInput = function () {
+                       progressHandler.setAttribute("data-value", toTimeString(this.value));
+               };
+
+               tau.event.on(touchpad, ["click", "touchstart", "touchmove", "touchend"], ontouch);
+               tau.event.on(mediaProgress, ["touchmove"], onProgressTouchmove);
+               tau.event.on(mediaProgress, ["input"], onProgressInput);
+
+               // update slider labels
+               labelMin.innerText = toTimeString(mediaProgress.min);
+               labelMax.innerText = toTimeString(mediaProgress.max);
+               progressHandler.setAttribute("data-value", toTimeString(mediaProgress.value));
+       };
+
+       function onPageHide() {
+               websocket.close();
+               if (volup) volup.removeEventListener("click");
+               if (voldown) voldown.removeEventListener("click");
+               if (channelup) channelup.removeEventListener("click");
+               if (channeldown) channeldown.removeEventListener("click");
+               if (up) up.removeEventListener("click");
+               if (down) down.removeEventListener("click");
+               if (right) right.removeEventListener("click");
+               if (left) left.removeEventListener("click");
+               if (enter) enter.removeEventListener("click");
+               if (backward) backward.removeEventListener("click");
+               if (home) home.removeEventListener("click");
+               if (touchpad) {
+                       touchpad.removeEventListener("click");
+                       touchpad.removeEventListener("touchstart");
+                       touchpad.removeEventListener("touchmove");
+                       touchpad.removeEventListener("touchend");
+               }
+       };
+
+       page.addEventListener("pagebeforeshow", onPageShow);
+       page.addEventListener("pagebeforehide", onPageHide);
+}());
\ No newline at end of file
diff --git a/d2d_app/client/js/invited.js b/d2d_app/client/js/invited.js
new file mode 100755 (executable)
index 0000000..a0130ed
--- /dev/null
@@ -0,0 +1,131 @@
+"use strict";
+import Actions from './actions.js';
+
+const serverPort = 9000;
+const serverURL = window.location.protocol + '//' + window.location.hostname;
+const actions = new Actions();
+const NEW_WINDOW_TIMEOUT = 1000;
+const myappsmodule = {};
+
+(function () {
+    var xhr;
+    function emptyElement(elm) {
+        while (elm.firstChild) {
+            elm.removeChild(elm.firstChild);
+        }
+        return elm;
+    }
+    /**
+     * Open app in new window
+     * @param {Object} response
+     * @private
+     */
+    function openAppWindow(response) {
+        document.getElementById("page-invited").style.display = "none";
+        var timer = setTimeout(function () {
+            clearTimeout(timer);
+            document.getElementById("page-invited").style.display = "block";
+            window.open(serverURL + ':' + response.port + '/app', 'newWindow');
+        }, NEW_WINDOW_TIMEOUT);
+    };
+
+    function showListView(dataArray) {
+        var formResult = document.getElementById("d2dApps"),
+            imgResult = document.getElementById("d2dAppList"),
+            formObj,
+            imgObj,
+            textObj,
+            objTable,
+            objRow,
+            i,
+            d2dApp,
+            icon;
+
+        emptyElement(imgResult);
+
+        objTable = document.createElement("div");
+        objTable.className = "result-table";
+
+        if (dataArray.length > 0) {
+            for (i = 0; i < dataArray.length; i++) {
+                if (dataArray[i]['d2dApp'].appName === 'Watch Together') {
+                    formObj = document.createElement("div");
+                    imgObj = document.createElement("img");
+                    textObj = document.createElement("p");
+                    formObj.style.textAlign = "center";
+                    d2dApp = dataArray[i]['d2dApp'];
+                    if (d2dApp.hasOwnProperty("appName")) {
+                        if (d2dApp.iconPath) {
+                            icon = d2dApp.iconPath.substring(d2dApp.iconPath.indexOf('/', 10) + 1);
+                            imgObj.src = `/d2dIcon/${icon}`;
+                        } else {
+                            imgObj.src = `./images/icon.png`;
+                        }
+                        imgObj.className = "app-icon-big-img";
+                        imgObj.alt = d2dApp.appName;
+                        textObj.style.display = "block";
+                        textObj.style.marginBottom = "60px";
+                        textObj.style.fontSize = "16px";
+                        textObj.innerHTML = d2dApp.appName;
+                    }
+                    imgObj.addEventListener("click", actions.launchAppOnTV(
+                        d2dApp.appPkgID,
+                        d2dApp.appAppID,
+                        function (response) {
+                            openAppWindow(response);
+                        }));
+                    formObj.appendChild(imgObj);
+                    formObj.appendChild(textObj);
+
+                    imgResult.appendChild(formObj);
+                }
+            }
+            formResult.appendChild(imgResult);
+        } else {
+            objRow = document.createElement("div");
+            objRow.className = "result-table-error";
+            objRow.appendChild(document.createTextNode("No Data"));
+            objTable.appendChild(objRow);
+        }
+    }
+
+    function showList() {
+        xhr = new XMLHttpRequest();
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState === xhr.DONE) {
+                if (xhr.status === 200 || xhr.status === 201) {
+                    showListView(JSON.parse(xhr.responseText));
+                } else {
+                    console.error(xhr.responseText);
+                }
+            }
+        };
+        xhr.open('GET', serverURL + ':' + serverPort + '/appList');
+        xhr.send();
+    }
+
+    function init() {
+        var eventSource = new EventSource(serverURL + ':' + serverPort + '/updateAppList');
+        eventSource.addEventListener('message', evt => {
+            showListView(JSON.parse(evt.data));
+        }, false);
+        eventSource.addEventListener('open', evt => {
+            console.log("Connected to...");
+        }, false);
+        eventSource.addEventListener('error', evt => {
+            if (evt.target.readyState == EventSource.CLOSED) {
+                console.log("Disconnected from...");
+            } else if (evt.target.readyState == EventSource.CONNECTING) {
+                console.log('Connecting to...');
+            }
+        }, false);
+        showList();
+    }
+    window.onload = init;
+    myappsmodule.openAppWindow = openAppWindow;
+}());
+
+export function openAppWindow(response) {
+    myappsmodule.openAppWindow(response);
+};
+
diff --git a/d2d_app/client/js/jsencrypt.js b/d2d_app/client/js/jsencrypt.js
new file mode 100644 (file)
index 0000000..de5a14f
--- /dev/null
@@ -0,0 +1,5371 @@
+(function (global, factory) {
+       typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+       typeof define === 'function' && define.amd ? define(['exports'], factory) :
+       (factory((global.JSEncrypt = {})));
+}(this, (function (exports) { 'use strict';
+
+var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+function int2char(n) {
+    return BI_RM.charAt(n);
+}
+//#region BIT_OPERATIONS
+// (public) this & a
+function op_and(x, y) {
+    return x & y;
+}
+// (public) this | a
+function op_or(x, y) {
+    return x | y;
+}
+// (public) this ^ a
+function op_xor(x, y) {
+    return x ^ y;
+}
+// (public) this & ~a
+function op_andnot(x, y) {
+    return x & ~y;
+}
+// return index of lowest 1-bit in x, x < 2^31
+function lbit(x) {
+    if (x == 0) {
+        return -1;
+    }
+    var r = 0;
+    if ((x & 0xffff) == 0) {
+        x >>= 16;
+        r += 16;
+    }
+    if ((x & 0xff) == 0) {
+        x >>= 8;
+        r += 8;
+    }
+    if ((x & 0xf) == 0) {
+        x >>= 4;
+        r += 4;
+    }
+    if ((x & 3) == 0) {
+        x >>= 2;
+        r += 2;
+    }
+    if ((x & 1) == 0) {
+        ++r;
+    }
+    return r;
+}
+// return number of 1 bits in x
+function cbit(x) {
+    var r = 0;
+    while (x != 0) {
+        x &= x - 1;
+        ++r;
+    }
+    return r;
+}
+//#endregion BIT_OPERATIONS
+
+var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var b64pad = "=";
+function hex2b64(h) {
+    var i;
+    var c;
+    var ret = "";
+    for (i = 0; i + 3 <= h.length; i += 3) {
+        c = parseInt(h.substring(i, i + 3), 16);
+        ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
+    }
+    if (i + 1 == h.length) {
+        c = parseInt(h.substring(i, i + 1), 16);
+        ret += b64map.charAt(c << 2);
+    }
+    else if (i + 2 == h.length) {
+        c = parseInt(h.substring(i, i + 2), 16);
+        ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
+    }
+    while ((ret.length & 3) > 0) {
+        ret += b64pad;
+    }
+    return ret;
+}
+// convert a base64 string to hex
+function b64tohex(s) {
+    var ret = "";
+    var i;
+    var k = 0; // b64 state, 0-3
+    var slop = 0;
+    for (i = 0; i < s.length; ++i) {
+        if (s.charAt(i) == b64pad) {
+            break;
+        }
+        var v = b64map.indexOf(s.charAt(i));
+        if (v < 0) {
+            continue;
+        }
+        if (k == 0) {
+            ret += int2char(v >> 2);
+            slop = v & 3;
+            k = 1;
+        }
+        else if (k == 1) {
+            ret += int2char((slop << 2) | (v >> 4));
+            slop = v & 0xf;
+            k = 2;
+        }
+        else if (k == 2) {
+            ret += int2char(slop);
+            ret += int2char(v >> 2);
+            slop = v & 3;
+            k = 3;
+        }
+        else {
+            ret += int2char((slop << 2) | (v >> 4));
+            ret += int2char(v & 0xf);
+            k = 0;
+        }
+    }
+    if (k == 1) {
+        ret += int2char(slop << 2);
+    }
+    return ret;
+}
+
+/*! *****************************************************************************
+Copyright (c) Microsoft Corporation. All rights reserved.
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at http://www.apache.org/licenses/LICENSE-2.0
+THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+MERCHANTABLITY OR NON-INFRINGEMENT.
+See the Apache Version 2.0 License for specific language governing permissions
+and limitations under the License.
+***************************************************************************** */
+/* global Reflect, Promise */
+
+var extendStatics = function(d, b) {
+    extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return extendStatics(d, b);
+};
+
+function __extends(d, b) {
+    extendStatics(d, b);
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+}
+
+// Hex JavaScript decoder
+// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
+var decoder;
+var Hex = {
+    decode: function (a) {
+        var i;
+        if (decoder === undefined) {
+            var hex = "0123456789ABCDEF";
+            var ignore = " \f\n\r\t\u00A0\u2028\u2029";
+            decoder = {};
+            for (i = 0; i < 16; ++i) {
+                decoder[hex.charAt(i)] = i;
+            }
+            hex = hex.toLowerCase();
+            for (i = 10; i < 16; ++i) {
+                decoder[hex.charAt(i)] = i;
+            }
+            for (i = 0; i < ignore.length; ++i) {
+                decoder[ignore.charAt(i)] = -1;
+            }
+        }
+        var out = [];
+        var bits = 0;
+        var char_count = 0;
+        for (i = 0; i < a.length; ++i) {
+            var c = a.charAt(i);
+            if (c == "=") {
+                break;
+            }
+            c = decoder[c];
+            if (c == -1) {
+                continue;
+            }
+            if (c === undefined) {
+                throw new Error("Illegal character at offset " + i);
+            }
+            bits |= c;
+            if (++char_count >= 2) {
+                out[out.length] = bits;
+                bits = 0;
+                char_count = 0;
+            }
+            else {
+                bits <<= 4;
+            }
+        }
+        if (char_count) {
+            throw new Error("Hex encoding incomplete: 4 bits missing");
+        }
+        return out;
+    }
+};
+
+// Base64 JavaScript decoder
+// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
+var decoder$1;
+var Base64 = {
+    decode: function (a) {
+        var i;
+        if (decoder$1 === undefined) {
+            var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+            var ignore = "= \f\n\r\t\u00A0\u2028\u2029";
+            decoder$1 = Object.create(null);
+            for (i = 0; i < 64; ++i) {
+                decoder$1[b64.charAt(i)] = i;
+            }
+            for (i = 0; i < ignore.length; ++i) {
+                decoder$1[ignore.charAt(i)] = -1;
+            }
+        }
+        var out = [];
+        var bits = 0;
+        var char_count = 0;
+        for (i = 0; i < a.length; ++i) {
+            var c = a.charAt(i);
+            if (c == "=") {
+                break;
+            }
+            c = decoder$1[c];
+            if (c == -1) {
+                continue;
+            }
+            if (c === undefined) {
+                throw new Error("Illegal character at offset " + i);
+            }
+            bits |= c;
+            if (++char_count >= 4) {
+                out[out.length] = (bits >> 16);
+                out[out.length] = (bits >> 8) & 0xFF;
+                out[out.length] = bits & 0xFF;
+                bits = 0;
+                char_count = 0;
+            }
+            else {
+                bits <<= 6;
+            }
+        }
+        switch (char_count) {
+            case 1:
+                throw new Error("Base64 encoding incomplete: at least 2 bits missing");
+            case 2:
+                out[out.length] = (bits >> 10);
+                break;
+            case 3:
+                out[out.length] = (bits >> 16);
+                out[out.length] = (bits >> 8) & 0xFF;
+                break;
+        }
+        return out;
+    },
+    re: /-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/,
+    unarmor: function (a) {
+        var m = Base64.re.exec(a);
+        if (m) {
+            if (m[1]) {
+                a = m[1];
+            }
+            else if (m[2]) {
+                a = m[2];
+            }
+            else {
+                throw new Error("RegExp out of sync");
+            }
+        }
+        return Base64.decode(a);
+    }
+};
+
+// Big integer base-10 printing library
+// Copyright (c) 2014 Lapo Luchini <lapo@lapo.it>
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
+var max = 10000000000000; // biggest integer that can still fit 2^53 when multiplied by 256
+var Int10 = /** @class */ (function () {
+    function Int10(value) {
+        this.buf = [+value || 0];
+    }
+    Int10.prototype.mulAdd = function (m, c) {
+        // assert(m <= 256)
+        var b = this.buf;
+        var l = b.length;
+        var i;
+        var t;
+        for (i = 0; i < l; ++i) {
+            t = b[i] * m + c;
+            if (t < max) {
+                c = 0;
+            }
+            else {
+                c = 0 | (t / max);
+                t -= c * max;
+            }
+            b[i] = t;
+        }
+        if (c > 0) {
+            b[i] = c;
+        }
+    };
+    Int10.prototype.sub = function (c) {
+        // assert(m <= 256)
+        var b = this.buf;
+        var l = b.length;
+        var i;
+        var t;
+        for (i = 0; i < l; ++i) {
+            t = b[i] - c;
+            if (t < 0) {
+                t += max;
+                c = 1;
+            }
+            else {
+                c = 0;
+            }
+            b[i] = t;
+        }
+        while (b[b.length - 1] === 0) {
+            b.pop();
+        }
+    };
+    Int10.prototype.toString = function (base) {
+        if ((base || 10) != 10) {
+            throw new Error("only base 10 is supported");
+        }
+        var b = this.buf;
+        var s = b[b.length - 1].toString();
+        for (var i = b.length - 2; i >= 0; --i) {
+            s += (max + b[i]).toString().substring(1);
+        }
+        return s;
+    };
+    Int10.prototype.valueOf = function () {
+        var b = this.buf;
+        var v = 0;
+        for (var i = b.length - 1; i >= 0; --i) {
+            v = v * max + b[i];
+        }
+        return v;
+    };
+    Int10.prototype.simplify = function () {
+        var b = this.buf;
+        return (b.length == 1) ? b[0] : this;
+    };
+    return Int10;
+}());
+
+// ASN.1 JavaScript decoder
+var ellipsis = "\u2026";
+var reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
+var reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
+function stringCut(str, len) {
+    if (str.length > len) {
+        str = str.substring(0, len) + ellipsis;
+    }
+    return str;
+}
+var Stream = /** @class */ (function () {
+    function Stream(enc, pos) {
+        this.hexDigits = "0123456789ABCDEF";
+        if (enc instanceof Stream) {
+            this.enc = enc.enc;
+            this.pos = enc.pos;
+        }
+        else {
+            // enc should be an array or a binary string
+            this.enc = enc;
+            this.pos = pos;
+        }
+    }
+    Stream.prototype.get = function (pos) {
+        if (pos === undefined) {
+            pos = this.pos++;
+        }
+        if (pos >= this.enc.length) {
+            throw new Error("Requesting byte offset " + pos + " on a stream of length " + this.enc.length);
+        }
+        return ("string" === typeof this.enc) ? this.enc.charCodeAt(pos) : this.enc[pos];
+    };
+    Stream.prototype.hexByte = function (b) {
+        return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF);
+    };
+    Stream.prototype.hexDump = function (start, end, raw) {
+        var s = "";
+        for (var i = start; i < end; ++i) {
+            s += this.hexByte(this.get(i));
+            if (raw !== true) {
+                switch (i & 0xF) {
+                    case 0x7:
+                        s += "  ";
+                        break;
+                    case 0xF:
+                        s += "\n";
+                        break;
+                    default:
+                        s += " ";
+                }
+            }
+        }
+        return s;
+    };
+    Stream.prototype.isASCII = function (start, end) {
+        for (var i = start; i < end; ++i) {
+            var c = this.get(i);
+            if (c < 32 || c > 176) {
+                return false;
+            }
+        }
+        return true;
+    };
+    Stream.prototype.parseStringISO = function (start, end) {
+        var s = "";
+        for (var i = start; i < end; ++i) {
+            s += String.fromCharCode(this.get(i));
+        }
+        return s;
+    };
+    Stream.prototype.parseStringUTF = function (start, end) {
+        var s = "";
+        for (var i = start; i < end;) {
+            var c = this.get(i++);
+            if (c < 128) {
+                s += String.fromCharCode(c);
+            }
+            else if ((c > 191) && (c < 224)) {
+                s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F));
+            }
+            else {
+                s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F));
+            }
+        }
+        return s;
+    };
+    Stream.prototype.parseStringBMP = function (start, end) {
+        var str = "";
+        var hi;
+        var lo;
+        for (var i = start; i < end;) {
+            hi = this.get(i++);
+            lo = this.get(i++);
+            str += String.fromCharCode((hi << 8) | lo);
+        }
+        return str;
+    };
+    Stream.prototype.parseTime = function (start, end, shortYear) {
+        var s = this.parseStringISO(start, end);
+        var m = (shortYear ? reTimeS : reTimeL).exec(s);
+        if (!m) {
+            return "Unrecognized time: " + s;
+        }
+        if (shortYear) {
+            // to avoid querying the timer, use the fixed range [1970, 2069]
+            // it will conform with ITU X.400 [-10, +40] sliding window until 2030
+            m[1] = +m[1];
+            m[1] += (+m[1] < 70) ? 2000 : 1900;
+        }
+        s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4];
+        if (m[5]) {
+            s += ":" + m[5];
+            if (m[6]) {
+                s += ":" + m[6];
+                if (m[7]) {
+                    s += "." + m[7];
+                }
+            }
+        }
+        if (m[8]) {
+            s += " UTC";
+            if (m[8] != "Z") {
+                s += m[8];
+                if (m[9]) {
+                    s += ":" + m[9];
+                }
+            }
+        }
+        return s;
+    };
+    Stream.prototype.parseInteger = function (start, end) {
+        var v = this.get(start);
+        var neg = (v > 127);
+        var pad = neg ? 255 : 0;
+        var len;
+        var s = "";
+        // skip unuseful bits (not allowed in DER)
+        while (v == pad && ++start < end) {
+            v = this.get(start);
+        }
+        len = end - start;
+        if (len === 0) {
+            return neg ? -1 : 0;
+        }
+        // show bit length of huge integers
+        if (len > 4) {
+            s = v;
+            len <<= 3;
+            while (((+s ^ pad) & 0x80) == 0) {
+                s = +s << 1;
+                --len;
+            }
+            s = "(" + len + " bit)\n";
+        }
+        // decode the integer
+        if (neg) {
+            v = v - 256;
+        }
+        var n = new Int10(v);
+        for (var i = start + 1; i < end; ++i) {
+            n.mulAdd(256, this.get(i));
+        }
+        return s + n.toString();
+    };
+    Stream.prototype.parseBitString = function (start, end, maxLength) {
+        var unusedBit = this.get(start);
+        var lenBit = ((end - start - 1) << 3) - unusedBit;
+        var intro = "(" + lenBit + " bit)\n";
+        var s = "";
+        for (var i = start + 1; i < end; ++i) {
+            var b = this.get(i);
+            var skip = (i == end - 1) ? unusedBit : 0;
+            for (var j = 7; j >= skip; --j) {
+                s += (b >> j) & 1 ? "1" : "0";
+            }
+            if (s.length > maxLength) {
+                return intro + stringCut(s, maxLength);
+            }
+        }
+        return intro + s;
+    };
+    Stream.prototype.parseOctetString = function (start, end, maxLength) {
+        if (this.isASCII(start, end)) {
+            return stringCut(this.parseStringISO(start, end), maxLength);
+        }
+        var len = end - start;
+        var s = "(" + len + " byte)\n";
+        maxLength /= 2; // we work in bytes
+        if (len > maxLength) {
+            end = start + maxLength;
+        }
+        for (var i = start; i < end; ++i) {
+            s += this.hexByte(this.get(i));
+        }
+        if (len > maxLength) {
+            s += ellipsis;
+        }
+        return s;
+    };
+    Stream.prototype.parseOID = function (start, end, maxLength) {
+        var s = "";
+        var n = new Int10();
+        var bits = 0;
+        for (var i = start; i < end; ++i) {
+            var v = this.get(i);
+            n.mulAdd(128, v & 0x7F);
+            bits += 7;
+            if (!(v & 0x80)) { // finished
+                if (s === "") {
+                    n = n.simplify();
+                    if (n instanceof Int10) {
+                        n.sub(80);
+                        s = "2." + n.toString();
+                    }
+                    else {
+                        var m = n < 80 ? n < 40 ? 0 : 1 : 2;
+                        s = m + "." + (n - m * 40);
+                    }
+                }
+                else {
+                    s += "." + n.toString();
+                }
+                if (s.length > maxLength) {
+                    return stringCut(s, maxLength);
+                }
+                n = new Int10();
+                bits = 0;
+            }
+        }
+        if (bits > 0) {
+            s += ".incomplete";
+        }
+        return s;
+    };
+    return Stream;
+}());
+var ASN1 = /** @class */ (function () {
+    function ASN1(stream, header, length, tag, sub) {
+        if (!(tag instanceof ASN1Tag)) {
+            throw new Error("Invalid tag value.");
+        }
+        this.stream = stream;
+        this.header = header;
+        this.length = length;
+        this.tag = tag;
+        this.sub = sub;
+    }
+    ASN1.prototype.typeName = function () {
+        switch (this.tag.tagClass) {
+            case 0: // universal
+                switch (this.tag.tagNumber) {
+                    case 0x00:
+                        return "EOC";
+                    case 0x01:
+                        return "BOOLEAN";
+                    case 0x02:
+                        return "INTEGER";
+                    case 0x03:
+                        return "BIT_STRING";
+                    case 0x04:
+                        return "OCTET_STRING";
+                    case 0x05:
+                        return "NULL";
+                    case 0x06:
+                        return "OBJECT_IDENTIFIER";
+                    case 0x07:
+                        return "ObjectDescriptor";
+                    case 0x08:
+                        return "EXTERNAL";
+                    case 0x09:
+                        return "REAL";
+                    case 0x0A:
+                        return "ENUMERATED";
+                    case 0x0B:
+                        return "EMBEDDED_PDV";
+                    case 0x0C:
+                        return "UTF8String";
+                    case 0x10:
+                        return "SEQUENCE";
+                    case 0x11:
+                        return "SET";
+                    case 0x12:
+                        return "NumericString";
+                    case 0x13:
+                        return "PrintableString"; // ASCII subset
+                    case 0x14:
+                        return "TeletexString"; // aka T61String
+                    case 0x15:
+                        return "VideotexString";
+                    case 0x16:
+                        return "IA5String"; // ASCII
+                    case 0x17:
+                        return "UTCTime";
+                    case 0x18:
+                        return "GeneralizedTime";
+                    case 0x19:
+                        return "GraphicString";
+                    case 0x1A:
+                        return "VisibleString"; // ASCII subset
+                    case 0x1B:
+                        return "GeneralString";
+                    case 0x1C:
+                        return "UniversalString";
+                    case 0x1E:
+                        return "BMPString";
+                }
+                return "Universal_" + this.tag.tagNumber.toString();
+            case 1:
+                return "Application_" + this.tag.tagNumber.toString();
+            case 2:
+                return "[" + this.tag.tagNumber.toString() + "]"; // Context
+            case 3:
+                return "Private_" + this.tag.tagNumber.toString();
+        }
+    };
+    ASN1.prototype.content = function (maxLength) {
+        if (this.tag === undefined) {
+            return null;
+        }
+        if (maxLength === undefined) {
+            maxLength = Infinity;
+        }
+        var content = this.posContent();
+        var len = Math.abs(this.length);
+        if (!this.tag.isUniversal()) {
+            if (this.sub !== null) {
+                return "(" + this.sub.length + " elem)";
+            }
+            return this.stream.parseOctetString(content, content + len, maxLength);
+        }
+        switch (this.tag.tagNumber) {
+            case 0x01: // BOOLEAN
+                return (this.stream.get(content) === 0) ? "false" : "true";
+            case 0x02: // INTEGER
+                return this.stream.parseInteger(content, content + len);
+            case 0x03: // BIT_STRING
+                return this.sub ? "(" + this.sub.length + " elem)" :
+                    this.stream.parseBitString(content, content + len, maxLength);
+            case 0x04: // OCTET_STRING
+                return this.sub ? "(" + this.sub.length + " elem)" :
+                    this.stream.parseOctetString(content, content + len, maxLength);
+            // case 0x05: // NULL
+            case 0x06: // OBJECT_IDENTIFIER
+                return this.stream.parseOID(content, content + len, maxLength);
+            // case 0x07: // ObjectDescriptor
+            // case 0x08: // EXTERNAL
+            // case 0x09: // REAL
+            // case 0x0A: // ENUMERATED
+            // case 0x0B: // EMBEDDED_PDV
+            case 0x10: // SEQUENCE
+            case 0x11: // SET
+                if (this.sub !== null) {
+                    return "(" + this.sub.length + " elem)";
+                }
+                else {
+                    return "(no elem)";
+                }
+            case 0x0C: // UTF8String
+                return stringCut(this.stream.parseStringUTF(content, content + len), maxLength);
+            case 0x12: // NumericString
+            case 0x13: // PrintableString
+            case 0x14: // TeletexString
+            case 0x15: // VideotexString
+            case 0x16: // IA5String
+            // case 0x19: // GraphicString
+            case 0x1A: // VisibleString
+                // case 0x1B: // GeneralString
+                // case 0x1C: // UniversalString
+                return stringCut(this.stream.parseStringISO(content, content + len), maxLength);
+            case 0x1E: // BMPString
+                return stringCut(this.stream.parseStringBMP(content, content + len), maxLength);
+            case 0x17: // UTCTime
+            case 0x18: // GeneralizedTime
+                return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17));
+        }
+        return null;
+    };
+    ASN1.prototype.toString = function () {
+        return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? "null" : this.sub.length) + "]";
+    };
+    ASN1.prototype.toPrettyString = function (indent) {
+        if (indent === undefined) {
+            indent = "";
+        }
+        var s = indent + this.typeName() + " @" + this.stream.pos;
+        if (this.length >= 0) {
+            s += "+";
+        }
+        s += this.length;
+        if (this.tag.tagConstructed) {
+            s += " (constructed)";
+        }
+        else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null)) {
+            s += " (encapsulates)";
+        }
+        s += "\n";
+        if (this.sub !== null) {
+            indent += "  ";
+            for (var i = 0, max = this.sub.length; i < max; ++i) {
+                s += this.sub[i].toPrettyString(indent);
+            }
+        }
+        return s;
+    };
+    ASN1.prototype.posStart = function () {
+        return this.stream.pos;
+    };
+    ASN1.prototype.posContent = function () {
+        return this.stream.pos + this.header;
+    };
+    ASN1.prototype.posEnd = function () {
+        return this.stream.pos + this.header + Math.abs(this.length);
+    };
+    ASN1.prototype.toHexString = function () {
+        return this.stream.hexDump(this.posStart(), this.posEnd(), true);
+    };
+    ASN1.decodeLength = function (stream) {
+        var buf = stream.get();
+        var len = buf & 0x7F;
+        if (len == buf) {
+            return len;
+        }
+        // no reason to use Int10, as it would be a huge buffer anyways
+        if (len > 6) {
+            throw new Error("Length over 48 bits not supported at position " + (stream.pos - 1));
+        }
+        if (len === 0) {
+            return null;
+        } // undefined
+        buf = 0;
+        for (var i = 0; i < len; ++i) {
+            buf = (buf * 256) + stream.get();
+        }
+        return buf;
+    };
+    /**
+     * Retrieve the hexadecimal value (as a string) of the current ASN.1 element
+     * @returns {string}
+     * @public
+     */
+    ASN1.prototype.getHexStringValue = function () {
+        var hexString = this.toHexString();
+        var offset = this.header * 2;
+        var length = this.length * 2;
+        return hexString.substr(offset, length);
+    };
+    ASN1.decode = function (str) {
+        var stream;
+        if (!(str instanceof Stream)) {
+            stream = new Stream(str, 0);
+        }
+        else {
+            stream = str;
+        }
+        var streamStart = new Stream(stream);
+        var tag = new ASN1Tag(stream);
+        var len = ASN1.decodeLength(stream);
+        var start = stream.pos;
+        var header = start - streamStart.pos;
+        var sub = null;
+        var getSub = function () {
+            var ret = [];
+            if (len !== null) {
+                // definite length
+                var end = start + len;
+                while (stream.pos < end) {
+                    ret[ret.length] = ASN1.decode(stream);
+                }
+                if (stream.pos != end) {
+                    throw new Error("Content size is not correct for container starting at offset " + start);
+                }
+            }
+            else {
+                // undefined length
+                try {
+                    for (;;) {
+                        var s = ASN1.decode(stream);
+                        if (s.tag.isEOC()) {
+                            break;
+                        }
+                        ret[ret.length] = s;
+                    }
+                    len = start - stream.pos; // undefined lengths are represented as negative values
+                }
+                catch (e) {
+                    throw new Error("Exception while decoding undefined length content: " + e);
+                }
+            }
+            return ret;
+        };
+        if (tag.tagConstructed) {
+            // must have valid content
+            sub = getSub();
+        }
+        else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) {
+            // sometimes BitString and OctetString are used to encapsulate ASN.1
+            try {
+                if (tag.tagNumber == 0x03) {
+                    if (stream.get() != 0) {
+                        throw new Error("BIT STRINGs with unused bits cannot encapsulate.");
+                    }
+                }
+                sub = getSub();
+                for (var i = 0; i < sub.length; ++i) {
+                    if (sub[i].tag.isEOC()) {
+                        throw new Error("EOC is not supposed to be actual content.");
+                    }
+                }
+            }
+            catch (e) {
+                // but silently ignore when they don't
+                sub = null;
+            }
+        }
+        if (sub === null) {
+            if (len === null) {
+                throw new Error("We can't skip over an invalid tag with undefined length at offset " + start);
+            }
+            stream.pos = start + Math.abs(len);
+        }
+        return new ASN1(streamStart, header, len, tag, sub);
+    };
+    return ASN1;
+}());
+var ASN1Tag = /** @class */ (function () {
+    function ASN1Tag(stream) {
+        var buf = stream.get();
+        this.tagClass = buf >> 6;
+        this.tagConstructed = ((buf & 0x20) !== 0);
+        this.tagNumber = buf & 0x1F;
+        if (this.tagNumber == 0x1F) { // long tag
+            var n = new Int10();
+            do {
+                buf = stream.get();
+                n.mulAdd(128, buf & 0x7F);
+            } while (buf & 0x80);
+            this.tagNumber = n.simplify();
+        }
+    }
+    ASN1Tag.prototype.isUniversal = function () {
+        return this.tagClass === 0x00;
+    };
+    ASN1Tag.prototype.isEOC = function () {
+        return this.tagClass === 0x00 && this.tagNumber === 0x00;
+    };
+    return ASN1Tag;
+}());
+
+// Copyright (c) 2005  Tom Wu
+// Bits per digit
+var dbits;
+// JavaScript engine analysis
+var canary = 0xdeadbeefcafe;
+var j_lm = ((canary & 0xffffff) == 0xefcafe);
+//#region
+var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
+var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
+//#endregion
+// (public) Constructor
+var BigInteger = /** @class */ (function () {
+    function BigInteger(a, b, c) {
+        if (a != null) {
+            if ("number" == typeof a) {
+                this.fromNumber(a, b, c);
+            }
+            else if (b == null && "string" != typeof a) {
+                this.fromString(a, 256);
+            }
+            else {
+                this.fromString(a, b);
+            }
+        }
+    }
+    //#region PUBLIC
+    // BigInteger.prototype.toString = bnToString;
+    // (public) return string representation in given radix
+    BigInteger.prototype.toString = function (b) {
+        if (this.s < 0) {
+            return "-" + this.negate().toString(b);
+        }
+        var k;
+        if (b == 16) {
+            k = 4;
+        }
+        else if (b == 8) {
+            k = 3;
+        }
+        else if (b == 2) {
+            k = 1;
+        }
+        else if (b == 32) {
+            k = 5;
+        }
+        else if (b == 4) {
+            k = 2;
+        }
+        else {
+            return this.toRadix(b);
+        }
+        var km = (1 << k) - 1;
+        var d;
+        var m = false;
+        var r = "";
+        var i = this.t;
+        var p = this.DB - (i * this.DB) % k;
+        if (i-- > 0) {
+            if (p < this.DB && (d = this[i] >> p) > 0) {
+                m = true;
+                r = int2char(d);
+            }
+            while (i >= 0) {
+                if (p < k) {
+                    d = (this[i] & ((1 << p) - 1)) << (k - p);
+                    d |= this[--i] >> (p += this.DB - k);
+                }
+                else {
+                    d = (this[i] >> (p -= k)) & km;
+                    if (p <= 0) {
+                        p += this.DB;
+                        --i;
+                    }
+                }
+                if (d > 0) {
+                    m = true;
+                }
+                if (m) {
+                    r += int2char(d);
+                }
+            }
+        }
+        return m ? r : "0";
+    };
+    // BigInteger.prototype.negate = bnNegate;
+    // (public) -this
+    BigInteger.prototype.negate = function () {
+        var r = nbi();
+        BigInteger.ZERO.subTo(this, r);
+        return r;
+    };
+    // BigInteger.prototype.abs = bnAbs;
+    // (public) |this|
+    BigInteger.prototype.abs = function () {
+        return (this.s < 0) ? this.negate() : this;
+    };
+    // BigInteger.prototype.compareTo = bnCompareTo;
+    // (public) return + if this > a, - if this < a, 0 if equal
+    BigInteger.prototype.compareTo = function (a) {
+        var r = this.s - a.s;
+        if (r != 0) {
+            return r;
+        }
+        var i = this.t;
+        r = i - a.t;
+        if (r != 0) {
+            return (this.s < 0) ? -r : r;
+        }
+        while (--i >= 0) {
+            if ((r = this[i] - a[i]) != 0) {
+                return r;
+            }
+        }
+        return 0;
+    };
+    // BigInteger.prototype.bitLength = bnBitLength;
+    // (public) return the number of bits in "this"
+    BigInteger.prototype.bitLength = function () {
+        if (this.t <= 0) {
+            return 0;
+        }
+        return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
+    };
+    // BigInteger.prototype.mod = bnMod;
+    // (public) this mod a
+    BigInteger.prototype.mod = function (a) {
+        var r = nbi();
+        this.abs().divRemTo(a, null, r);
+        if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) {
+            a.subTo(r, r);
+        }
+        return r;
+    };
+    // BigInteger.prototype.modPowInt = bnModPowInt;
+    // (public) this^e % m, 0 <= e < 2^32
+    BigInteger.prototype.modPowInt = function (e, m) {
+        var z;
+        if (e < 256 || m.isEven()) {
+            z = new Classic(m);
+        }
+        else {
+            z = new Montgomery(m);
+        }
+        return this.exp(e, z);
+    };
+    // BigInteger.prototype.clone = bnClone;
+    // (public)
+    BigInteger.prototype.clone = function () {
+        var r = nbi();
+        this.copyTo(r);
+        return r;
+    };
+    // BigInteger.prototype.intValue = bnIntValue;
+    // (public) return value as integer
+    BigInteger.prototype.intValue = function () {
+        if (this.s < 0) {
+            if (this.t == 1) {
+                return this[0] - this.DV;
+            }
+            else if (this.t == 0) {
+                return -1;
+            }
+        }
+        else if (this.t == 1) {
+            return this[0];
+        }
+        else if (this.t == 0) {
+            return 0;
+        }
+        // assumes 16 < DB < 32
+        return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0];
+    };
+    // BigInteger.prototype.byteValue = bnByteValue;
+    // (public) return value as byte
+    BigInteger.prototype.byteValue = function () {
+        return (this.t == 0) ? this.s : (this[0] << 24) >> 24;
+    };
+    // BigInteger.prototype.shortValue = bnShortValue;
+    // (public) return value as short (assumes DB>=16)
+    BigInteger.prototype.shortValue = function () {
+        return (this.t == 0) ? this.s : (this[0] << 16) >> 16;
+    };
+    // BigInteger.prototype.signum = bnSigNum;
+    // (public) 0 if this == 0, 1 if this > 0
+    BigInteger.prototype.signum = function () {
+        if (this.s < 0) {
+            return -1;
+        }
+        else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) {
+            return 0;
+        }
+        else {
+            return 1;
+        }
+    };
+    // BigInteger.prototype.toByteArray = bnToByteArray;
+    // (public) convert to bigendian byte array
+    BigInteger.prototype.toByteArray = function () {
+        var i = this.t;
+        var r = [];
+        r[0] = this.s;
+        var p = this.DB - (i * this.DB) % 8;
+        var d;
+        var k = 0;
+        if (i-- > 0) {
+            if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) {
+                r[k++] = d | (this.s << (this.DB - p));
+            }
+            while (i >= 0) {
+                if (p < 8) {
+                    d = (this[i] & ((1 << p) - 1)) << (8 - p);
+                    d |= this[--i] >> (p += this.DB - 8);
+                }
+                else {
+                    d = (this[i] >> (p -= 8)) & 0xff;
+                    if (p <= 0) {
+                        p += this.DB;
+                        --i;
+                    }
+                }
+                if ((d & 0x80) != 0) {
+                    d |= -256;
+                }
+                if (k == 0 && (this.s & 0x80) != (d & 0x80)) {
+                    ++k;
+                }
+                if (k > 0 || d != this.s) {
+                    r[k++] = d;
+                }
+            }
+        }
+        return r;
+    };
+    // BigInteger.prototype.equals = bnEquals;
+    BigInteger.prototype.equals = function (a) {
+        return (this.compareTo(a) == 0);
+    };
+    // BigInteger.prototype.min = bnMin;
+    BigInteger.prototype.min = function (a) {
+        return (this.compareTo(a) < 0) ? this : a;
+    };
+    // BigInteger.prototype.max = bnMax;
+    BigInteger.prototype.max = function (a) {
+        return (this.compareTo(a) > 0) ? this : a;
+    };
+    // BigInteger.prototype.and = bnAnd;
+    BigInteger.prototype.and = function (a) {
+        var r = nbi();
+        this.bitwiseTo(a, op_and, r);
+        return r;
+    };
+    // BigInteger.prototype.or = bnOr;
+    BigInteger.prototype.or = function (a) {
+        var r = nbi();
+        this.bitwiseTo(a, op_or, r);
+        return r;
+    };
+    // BigInteger.prototype.xor = bnXor;
+    BigInteger.prototype.xor = function (a) {
+        var r = nbi();
+        this.bitwiseTo(a, op_xor, r);
+        return r;
+    };
+    // BigInteger.prototype.andNot = bnAndNot;
+    BigInteger.prototype.andNot = function (a) {
+        var r = nbi();
+        this.bitwiseTo(a, op_andnot, r);
+        return r;
+    };
+    // BigInteger.prototype.not = bnNot;
+    // (public) ~this
+    BigInteger.prototype.not = function () {
+        var r = nbi();
+        for (var i = 0; i < this.t; ++i) {
+            r[i] = this.DM & ~this[i];
+        }
+        r.t = this.t;
+        r.s = ~this.s;
+        return r;
+    };
+    // BigInteger.prototype.shiftLeft = bnShiftLeft;
+    // (public) this << n
+    BigInteger.prototype.shiftLeft = function (n) {
+        var r = nbi();
+        if (n < 0) {
+            this.rShiftTo(-n, r);
+        }
+        else {
+            this.lShiftTo(n, r);
+        }
+        return r;
+    };
+    // BigInteger.prototype.shiftRight = bnShiftRight;
+    // (public) this >> n
+    BigInteger.prototype.shiftRight = function (n) {
+        var r = nbi();
+        if (n < 0) {
+            this.lShiftTo(-n, r);
+        }
+        else {
+            this.rShiftTo(n, r);
+        }
+        return r;
+    };
+    // BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
+    // (public) returns index of lowest 1-bit (or -1 if none)
+    BigInteger.prototype.getLowestSetBit = function () {
+        for (var i = 0; i < this.t; ++i) {
+            if (this[i] != 0) {
+                return i * this.DB + lbit(this[i]);
+            }
+        }
+        if (this.s < 0) {
+            return this.t * this.DB;
+        }
+        return -1;
+    };
+    // BigInteger.prototype.bitCount = bnBitCount;
+    // (public) return number of set bits
+    BigInteger.prototype.bitCount = function () {
+        var r = 0;
+        var x = this.s & this.DM;
+        for (var i = 0; i < this.t; ++i) {
+            r += cbit(this[i] ^ x);
+        }
+        return r;
+    };
+    // BigInteger.prototype.testBit = bnTestBit;
+    // (public) true iff nth bit is set
+    BigInteger.prototype.testBit = function (n) {
+        var j = Math.floor(n / this.DB);
+        if (j >= this.t) {
+            return (this.s != 0);
+        }
+        return ((this[j] & (1 << (n % this.DB))) != 0);
+    };
+    // BigInteger.prototype.setBit = bnSetBit;
+    // (public) this | (1<<n)
+    BigInteger.prototype.setBit = function (n) {
+        return this.changeBit(n, op_or);
+    };
+    // BigInteger.prototype.clearBit = bnClearBit;
+    // (public) this & ~(1<<n)
+    BigInteger.prototype.clearBit = function (n) {
+        return this.changeBit(n, op_andnot);
+    };
+    // BigInteger.prototype.flipBit = bnFlipBit;
+    // (public) this ^ (1<<n)
+    BigInteger.prototype.flipBit = function (n) {
+        return this.changeBit(n, op_xor);
+    };
+    // BigInteger.prototype.add = bnAdd;
+    // (public) this + a
+    BigInteger.prototype.add = function (a) {
+        var r = nbi();
+        this.addTo(a, r);
+        return r;
+    };
+    // BigInteger.prototype.subtract = bnSubtract;
+    // (public) this - a
+    BigInteger.prototype.subtract = function (a) {
+        var r = nbi();
+        this.subTo(a, r);
+        return r;
+    };
+    // BigInteger.prototype.multiply = bnMultiply;
+    // (public) this * a
+    BigInteger.prototype.multiply = function (a) {
+        var r = nbi();
+        this.multiplyTo(a, r);
+        return r;
+    };
+    // BigInteger.prototype.divide = bnDivide;
+    // (public) this / a
+    BigInteger.prototype.divide = function (a) {
+        var r = nbi();
+        this.divRemTo(a, r, null);
+        return r;
+    };
+    // BigInteger.prototype.remainder = bnRemainder;
+    // (public) this % a
+    BigInteger.prototype.remainder = function (a) {
+        var r = nbi();
+        this.divRemTo(a, null, r);
+        return r;
+    };
+    // BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
+    // (public) [this/a,this%a]
+    BigInteger.prototype.divideAndRemainder = function (a) {
+        var q = nbi();
+        var r = nbi();
+        this.divRemTo(a, q, r);
+        return [q, r];
+    };
+    // BigInteger.prototype.modPow = bnModPow;
+    // (public) this^e % m (HAC 14.85)
+    BigInteger.prototype.modPow = function (e, m) {
+        var i = e.bitLength();
+        var k;
+        var r = nbv(1);
+        var z;
+        if (i <= 0) {
+            return r;
+        }
+        else if (i < 18) {
+            k = 1;
+        }
+        else if (i < 48) {
+            k = 3;
+        }
+        else if (i < 144) {
+            k = 4;
+        }
+        else if (i < 768) {
+            k = 5;
+        }
+        else {
+            k = 6;
+        }
+        if (i < 8) {
+            z = new Classic(m);
+        }
+        else if (m.isEven()) {
+            z = new Barrett(m);
+        }
+        else {
+            z = new Montgomery(m);
+        }
+        // precomputation
+        var g = [];
+        var n = 3;
+        var k1 = k - 1;
+        var km = (1 << k) - 1;
+        g[1] = z.convert(this);
+        if (k > 1) {
+            var g2 = nbi();
+            z.sqrTo(g[1], g2);
+            while (n <= km) {
+                g[n] = nbi();
+                z.mulTo(g2, g[n - 2], g[n]);
+                n += 2;
+            }
+        }
+        var j = e.t - 1;
+        var w;
+        var is1 = true;
+        var r2 = nbi();
+        var t;
+        i = nbits(e[j]) - 1;
+        while (j >= 0) {
+            if (i >= k1) {
+                w = (e[j] >> (i - k1)) & km;
+            }
+            else {
+                w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
+                if (j > 0) {
+                    w |= e[j - 1] >> (this.DB + i - k1);
+                }
+            }
+            n = k;
+            while ((w & 1) == 0) {
+                w >>= 1;
+                --n;
+            }
+            if ((i -= n) < 0) {
+                i += this.DB;
+                --j;
+            }
+            if (is1) { // ret == 1, don't bother squaring or multiplying it
+                g[w].copyTo(r);
+                is1 = false;
+            }
+            else {
+                while (n > 1) {
+                    z.sqrTo(r, r2);
+                    z.sqrTo(r2, r);
+                    n -= 2;
+                }
+                if (n > 0) {
+                    z.sqrTo(r, r2);
+                }
+                else {
+                    t = r;
+                    r = r2;
+                    r2 = t;
+                }
+                z.mulTo(r2, g[w], r);
+            }
+            while (j >= 0 && (e[j] & (1 << i)) == 0) {
+                z.sqrTo(r, r2);
+                t = r;
+                r = r2;
+                r2 = t;
+                if (--i < 0) {
+                    i = this.DB - 1;
+                    --j;
+                }
+            }
+        }
+        return z.revert(r);
+    };
+    // BigInteger.prototype.modInverse = bnModInverse;
+    // (public) 1/this % m (HAC 14.61)
+    BigInteger.prototype.modInverse = function (m) {
+        var ac = m.isEven();
+        if ((this.isEven() && ac) || m.signum() == 0) {
+            return BigInteger.ZERO;
+        }
+        var u = m.clone();
+        var v = this.clone();
+        var a = nbv(1);
+        var b = nbv(0);
+        var c = nbv(0);
+        var d = nbv(1);
+        while (u.signum() != 0) {
+            while (u.isEven()) {
+                u.rShiftTo(1, u);
+                if (ac) {
+                    if (!a.isEven() || !b.isEven()) {
+                        a.addTo(this, a);
+                        b.subTo(m, b);
+                    }
+                    a.rShiftTo(1, a);
+                }
+                else if (!b.isEven()) {
+                    b.subTo(m, b);
+                }
+                b.rShiftTo(1, b);
+            }
+            while (v.isEven()) {
+                v.rShiftTo(1, v);
+                if (ac) {
+                    if (!c.isEven() || !d.isEven()) {
+                        c.addTo(this, c);
+                        d.subTo(m, d);
+                    }
+                    c.rShiftTo(1, c);
+                }
+                else if (!d.isEven()) {
+                    d.subTo(m, d);
+                }
+                d.rShiftTo(1, d);
+            }
+            if (u.compareTo(v) >= 0) {
+                u.subTo(v, u);
+                if (ac) {
+                    a.subTo(c, a);
+                }
+                b.subTo(d, b);
+            }
+            else {
+                v.subTo(u, v);
+                if (ac) {
+                    c.subTo(a, c);
+                }
+                d.subTo(b, d);
+            }
+        }
+        if (v.compareTo(BigInteger.ONE) != 0) {
+            return BigInteger.ZERO;
+        }
+        if (d.compareTo(m) >= 0) {
+            return d.subtract(m);
+        }
+        if (d.signum() < 0) {
+            d.addTo(m, d);
+        }
+        else {
+            return d;
+        }
+        if (d.signum() < 0) {
+            return d.add(m);
+        }
+        else {
+            return d;
+        }
+    };
+    // BigInteger.prototype.pow = bnPow;
+    // (public) this^e
+    BigInteger.prototype.pow = function (e) {
+        return this.exp(e, new NullExp());
+    };
+    // BigInteger.prototype.gcd = bnGCD;
+    // (public) gcd(this,a) (HAC 14.54)
+    BigInteger.prototype.gcd = function (a) {
+        var x = (this.s < 0) ? this.negate() : this.clone();
+        var y = (a.s < 0) ? a.negate() : a.clone();
+        if (x.compareTo(y) < 0) {
+            var t = x;
+            x = y;
+            y = t;
+        }
+        var i = x.getLowestSetBit();
+        var g = y.getLowestSetBit();
+        if (g < 0) {
+            return x;
+        }
+        if (i < g) {
+            g = i;
+        }
+        if (g > 0) {
+            x.rShiftTo(g, x);
+            y.rShiftTo(g, y);
+        }
+        while (x.signum() > 0) {
+            if ((i = x.getLowestSetBit()) > 0) {
+                x.rShiftTo(i, x);
+            }
+            if ((i = y.getLowestSetBit()) > 0) {
+                y.rShiftTo(i, y);
+            }
+            if (x.compareTo(y) >= 0) {
+                x.subTo(y, x);
+                x.rShiftTo(1, x);
+            }
+            else {
+                y.subTo(x, y);
+                y.rShiftTo(1, y);
+            }
+        }
+        if (g > 0) {
+            y.lShiftTo(g, y);
+        }
+        return y;
+    };
+    // BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
+    // (public) test primality with certainty >= 1-.5^t
+    BigInteger.prototype.isProbablePrime = function (t) {
+        var i;
+        var x = this.abs();
+        if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
+            for (i = 0; i < lowprimes.length; ++i) {
+                if (x[0] == lowprimes[i]) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        if (x.isEven()) {
+            return false;
+        }
+        i = 1;
+        while (i < lowprimes.length) {
+            var m = lowprimes[i];
+            var j = i + 1;
+            while (j < lowprimes.length && m < lplim) {
+                m *= lowprimes[j++];
+            }
+            m = x.modInt(m);
+            while (i < j) {
+                if (m % lowprimes[i++] == 0) {
+                    return false;
+                }
+            }
+        }
+        return x.millerRabin(t);
+    };
+    //#endregion PUBLIC
+    //#region PROTECTED
+    // BigInteger.prototype.copyTo = bnpCopyTo;
+    // (protected) copy this to r
+    BigInteger.prototype.copyTo = function (r) {
+        for (var i = this.t - 1; i >= 0; --i) {
+            r[i] = this[i];
+        }
+        r.t = this.t;
+        r.s = this.s;
+    };
+    // BigInteger.prototype.fromInt = bnpFromInt;
+    // (protected) set from integer value x, -DV <= x < DV
+    BigInteger.prototype.fromInt = function (x) {
+        this.t = 1;
+        this.s = (x < 0) ? -1 : 0;
+        if (x > 0) {
+            this[0] = x;
+        }
+        else if (x < -1) {
+            this[0] = x + this.DV;
+        }
+        else {
+            this.t = 0;
+        }
+    };
+    // BigInteger.prototype.fromString = bnpFromString;
+    // (protected) set from string and radix
+    BigInteger.prototype.fromString = function (s, b) {
+        var k;
+        if (b == 16) {
+            k = 4;
+        }
+        else if (b == 8) {
+            k = 3;
+        }
+        else if (b == 256) {
+            k = 8;
+            /* byte array */
+        }
+        else if (b == 2) {
+            k = 1;
+        }
+        else if (b == 32) {
+            k = 5;
+        }
+        else if (b == 4) {
+            k = 2;
+        }
+        else {
+            this.fromRadix(s, b);
+            return;
+        }
+        this.t = 0;
+        this.s = 0;
+        var i = s.length;
+        var mi = false;
+        var sh = 0;
+        while (--i >= 0) {
+            var x = (k == 8) ? (+s[i]) & 0xff : intAt(s, i);
+            if (x < 0) {
+                if (s.charAt(i) == "-") {
+                    mi = true;
+                }
+                continue;
+            }
+            mi = false;
+            if (sh == 0) {
+                this[this.t++] = x;
+            }
+            else if (sh + k > this.DB) {
+                this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
+                this[this.t++] = (x >> (this.DB - sh));
+            }
+            else {
+                this[this.t - 1] |= x << sh;
+            }
+            sh += k;
+            if (sh >= this.DB) {
+                sh -= this.DB;
+            }
+        }
+        if (k == 8 && ((+s[0]) & 0x80) != 0) {
+            this.s = -1;
+            if (sh > 0) {
+                this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
+            }
+        }
+        this.clamp();
+        if (mi) {
+            BigInteger.ZERO.subTo(this, this);
+        }
+    };
+    // BigInteger.prototype.clamp = bnpClamp;
+    // (protected) clamp off excess high words
+    BigInteger.prototype.clamp = function () {
+        var c = this.s & this.DM;
+        while (this.t > 0 && this[this.t - 1] == c) {
+            --this.t;
+        }
+    };
+    // BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
+    // (protected) r = this << n*DB
+    BigInteger.prototype.dlShiftTo = function (n, r) {
+        var i;
+        for (i = this.t - 1; i >= 0; --i) {
+            r[i + n] = this[i];
+        }
+        for (i = n - 1; i >= 0; --i) {
+            r[i] = 0;
+        }
+        r.t = this.t + n;
+        r.s = this.s;
+    };
+    // BigInteger.prototype.drShiftTo = bnpDRShiftTo;
+    // (protected) r = this >> n*DB
+    BigInteger.prototype.drShiftTo = function (n, r) {
+        for (var i = n; i < this.t; ++i) {
+            r[i - n] = this[i];
+        }
+        r.t = Math.max(this.t - n, 0);
+        r.s = this.s;
+    };
+    // BigInteger.prototype.lShiftTo = bnpLShiftTo;
+    // (protected) r = this << n
+    BigInteger.prototype.lShiftTo = function (n, r) {
+        var bs = n % this.DB;
+        var cbs = this.DB - bs;
+        var bm = (1 << cbs) - 1;
+        var ds = Math.floor(n / this.DB);
+        var c = (this.s << bs) & this.DM;
+        for (var i = this.t - 1; i >= 0; --i) {
+            r[i + ds + 1] = (this[i] >> cbs) | c;
+            c = (this[i] & bm) << bs;
+        }
+        for (var i = ds - 1; i >= 0; --i) {
+            r[i] = 0;
+        }
+        r[ds] = c;
+        r.t = this.t + ds + 1;
+        r.s = this.s;
+        r.clamp();
+    };
+    // BigInteger.prototype.rShiftTo = bnpRShiftTo;
+    // (protected) r = this >> n
+    BigInteger.prototype.rShiftTo = function (n, r) {
+        r.s = this.s;
+        var ds = Math.floor(n / this.DB);
+        if (ds >= this.t) {
+            r.t = 0;
+            return;
+        }
+        var bs = n % this.DB;
+        var cbs = this.DB - bs;
+        var bm = (1 << bs) - 1;
+        r[0] = this[ds] >> bs;
+        for (var i = ds + 1; i < this.t; ++i) {
+            r[i - ds - 1] |= (this[i] & bm) << cbs;
+            r[i - ds] = this[i] >> bs;
+        }
+        if (bs > 0) {
+            r[this.t - ds - 1] |= (this.s & bm) << cbs;
+        }
+        r.t = this.t - ds;
+        r.clamp();
+    };
+    // BigInteger.prototype.subTo = bnpSubTo;
+    // (protected) r = this - a
+    BigInteger.prototype.subTo = function (a, r) {
+        var i = 0;
+        var c = 0;
+        var m = Math.min(a.t, this.t);
+        while (i < m) {
+            c += this[i] - a[i];
+            r[i++] = c & this.DM;
+            c >>= this.DB;
+        }
+        if (a.t < this.t) {
+            c -= a.s;
+            while (i < this.t) {
+                c += this[i];
+                r[i++] = c & this.DM;
+                c >>= this.DB;
+            }
+            c += this.s;
+        }
+        else {
+            c += this.s;
+            while (i < a.t) {
+                c -= a[i];
+                r[i++] = c & this.DM;
+                c >>= this.DB;
+            }
+            c -= a.s;
+        }
+        r.s = (c < 0) ? -1 : 0;
+        if (c < -1) {
+            r[i++] = this.DV + c;
+        }
+        else if (c > 0) {
+            r[i++] = c;
+        }
+        r.t = i;
+        r.clamp();
+    };
+    // BigInteger.prototype.multiplyTo = bnpMultiplyTo;
+    // (protected) r = this * a, r != this,a (HAC 14.12)
+    // "this" should be the larger one if appropriate.
+    BigInteger.prototype.multiplyTo = function (a, r) {
+        var x = this.abs();
+        var y = a.abs();
+        var i = x.t;
+        r.t = i + y.t;
+        while (--i >= 0) {
+            r[i] = 0;
+        }
+        for (i = 0; i < y.t; ++i) {
+            r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
+        }
+        r.s = 0;
+        r.clamp();
+        if (this.s != a.s) {
+            BigInteger.ZERO.subTo(r, r);
+        }
+    };
+    // BigInteger.prototype.squareTo = bnpSquareTo;
+    // (protected) r = this^2, r != this (HAC 14.16)
+    BigInteger.prototype.squareTo = function (r) {
+        var x = this.abs();
+        var i = r.t = 2 * x.t;
+        while (--i >= 0) {
+            r[i] = 0;
+        }
+        for (i = 0; i < x.t - 1; ++i) {
+            var c = x.am(i, x[i], r, 2 * i, 0, 1);
+            if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
+                r[i + x.t] -= x.DV;
+                r[i + x.t + 1] = 1;
+            }
+        }
+        if (r.t > 0) {
+            r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
+        }
+        r.s = 0;
+        r.clamp();
+    };
+    // BigInteger.prototype.divRemTo = bnpDivRemTo;
+    // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+    // r != q, this != m.  q or r may be null.
+    BigInteger.prototype.divRemTo = function (m, q, r) {
+        var pm = m.abs();
+        if (pm.t <= 0) {
+            return;
+        }
+        var pt = this.abs();
+        if (pt.t < pm.t) {
+            if (q != null) {
+                q.fromInt(0);
+            }
+            if (r != null) {
+                this.copyTo(r);
+            }
+            return;
+        }
+        if (r == null) {
+            r = nbi();
+        }
+        var y = nbi();
+        var ts = this.s;
+        var ms = m.s;
+        var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
+        if (nsh > 0) {
+            pm.lShiftTo(nsh, y);
+            pt.lShiftTo(nsh, r);
+        }
+        else {
+            pm.copyTo(y);
+            pt.copyTo(r);
+        }
+        var ys = y.t;
+        var y0 = y[ys - 1];
+        if (y0 == 0) {
+            return;
+        }
+        var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
+        var d1 = this.FV / yt;
+        var d2 = (1 << this.F1) / yt;
+        var e = 1 << this.F2;
+        var i = r.t;
+        var j = i - ys;
+        var t = (q == null) ? nbi() : q;
+        y.dlShiftTo(j, t);
+        if (r.compareTo(t) >= 0) {
+            r[r.t++] = 1;
+            r.subTo(t, r);
+        }
+        BigInteger.ONE.dlShiftTo(ys, t);
+        t.subTo(y, y); // "negative" y so we can replace sub with am later
+        while (y.t < ys) {
+            y[y.t++] = 0;
+        }
+        while (--j >= 0) {
+            // Estimate quotient digit
+            var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
+            if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out
+                y.dlShiftTo(j, t);
+                r.subTo(t, r);
+                while (r[i] < --qd) {
+                    r.subTo(t, r);
+                }
+            }
+        }
+        if (q != null) {
+            r.drShiftTo(ys, q);
+            if (ts != ms) {
+                BigInteger.ZERO.subTo(q, q);
+            }
+        }
+        r.t = ys;
+        r.clamp();
+        if (nsh > 0) {
+            r.rShiftTo(nsh, r);
+        } // Denormalize remainder
+        if (ts < 0) {
+            BigInteger.ZERO.subTo(r, r);
+        }
+    };
+    // BigInteger.prototype.invDigit = bnpInvDigit;
+    // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+    // justification:
+    //         xy == 1 (mod m)
+    //         xy =  1+km
+    //   xy(2-xy) = (1+km)(1-km)
+    // x[y(2-xy)] = 1-k^2m^2
+    // x[y(2-xy)] == 1 (mod m^2)
+    // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+    // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+    // JS multiply "overflows" differently from C/C++, so care is needed here.
+    BigInteger.prototype.invDigit = function () {
+        if (this.t < 1) {
+            return 0;
+        }
+        var x = this[0];
+        if ((x & 1) == 0) {
+            return 0;
+        }
+        var y = x & 3; // y == 1/x mod 2^2
+        y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
+        y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
+        y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
+        // last step - calculate inverse mod DV directly;
+        // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+        y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits
+        // we really want the negative inverse, and -DV < y < DV
+        return (y > 0) ? this.DV - y : -y;
+    };
+    // BigInteger.prototype.isEven = bnpIsEven;
+    // (protected) true iff this is even
+    BigInteger.prototype.isEven = function () {
+        return ((this.t > 0) ? (this[0] & 1) : this.s) == 0;
+    };
+    // BigInteger.prototype.exp = bnpExp;
+    // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+    BigInteger.prototype.exp = function (e, z) {
+        if (e > 0xffffffff || e < 1) {
+            return BigInteger.ONE;
+        }
+        var r = nbi();
+        var r2 = nbi();
+        var g = z.convert(this);
+        var i = nbits(e) - 1;
+        g.copyTo(r);
+        while (--i >= 0) {
+            z.sqrTo(r, r2);
+            if ((e & (1 << i)) > 0) {
+                z.mulTo(r2, g, r);
+            }
+            else {
+                var t = r;
+                r = r2;
+                r2 = t;
+            }
+        }
+        return z.revert(r);
+    };
+    // BigInteger.prototype.chunkSize = bnpChunkSize;
+    // (protected) return x s.t. r^x < DV
+    BigInteger.prototype.chunkSize = function (r) {
+        return Math.floor(Math.LN2 * this.DB / Math.log(r));
+    };
+    // BigInteger.prototype.toRadix = bnpToRadix;
+    // (protected) convert to radix string
+    BigInteger.prototype.toRadix = function (b) {
+        if (b == null) {
+            b = 10;
+        }
+        if (this.signum() == 0 || b < 2 || b > 36) {
+            return "0";
+        }
+        var cs = this.chunkSize(b);
+        var a = Math.pow(b, cs);
+        var d = nbv(a);
+        var y = nbi();
+        var z = nbi();
+        var r = "";
+        this.divRemTo(d, y, z);
+        while (y.signum() > 0) {
+            r = (a + z.intValue()).toString(b).substr(1) + r;
+            y.divRemTo(d, y, z);
+        }
+        return z.intValue().toString(b) + r;
+    };
+    // BigInteger.prototype.fromRadix = bnpFromRadix;
+    // (protected) convert from radix string
+    BigInteger.prototype.fromRadix = function (s, b) {
+        this.fromInt(0);
+        if (b == null) {
+            b = 10;
+        }
+        var cs = this.chunkSize(b);
+        var d = Math.pow(b, cs);
+        var mi = false;
+        var j = 0;
+        var w = 0;
+        for (var i = 0; i < s.length; ++i) {
+            var x = intAt(s, i);
+            if (x < 0) {
+                if (s.charAt(i) == "-" && this.signum() == 0) {
+                    mi = true;
+                }
+                continue;
+            }
+            w = b * w + x;
+            if (++j >= cs) {
+                this.dMultiply(d);
+                this.dAddOffset(w, 0);
+                j = 0;
+                w = 0;
+            }
+        }
+        if (j > 0) {
+            this.dMultiply(Math.pow(b, j));
+            this.dAddOffset(w, 0);
+        }
+        if (mi) {
+            BigInteger.ZERO.subTo(this, this);
+        }
+    };
+    // BigInteger.prototype.fromNumber = bnpFromNumber;
+    // (protected) alternate constructor
+    BigInteger.prototype.fromNumber = function (a, b, c) {
+        if ("number" == typeof b) {
+            // new BigInteger(int,int,RNG)
+            if (a < 2) {
+                this.fromInt(1);
+            }
+            else {
+                this.fromNumber(a, c);
+                if (!this.testBit(a - 1)) {
+                    // force MSB set
+                    this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
+                }
+                if (this.isEven()) {
+                    this.dAddOffset(1, 0);
+                } // force odd
+                while (!this.isProbablePrime(b)) {
+                    this.dAddOffset(2, 0);
+                    if (this.bitLength() > a) {
+                        this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
+                    }
+                }
+            }
+        }
+        else {
+            // new BigInteger(int,RNG)
+            var x = [];
+            var t = a & 7;
+            x.length = (a >> 3) + 1;
+            b.nextBytes(x);
+            if (t > 0) {
+                x[0] &= ((1 << t) - 1);
+            }
+            else {
+                x[0] = 0;
+            }
+            this.fromString(x, 256);
+        }
+    };
+    // BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
+    // (protected) r = this op a (bitwise)
+    BigInteger.prototype.bitwiseTo = function (a, op, r) {
+        var i;
+        var f;
+        var m = Math.min(a.t, this.t);
+        for (i = 0; i < m; ++i) {
+            r[i] = op(this[i], a[i]);
+        }
+        if (a.t < this.t) {
+            f = a.s & this.DM;
+            for (i = m; i < this.t; ++i) {
+                r[i] = op(this[i], f);
+            }
+            r.t = this.t;
+        }
+        else {
+            f = this.s & this.DM;
+            for (i = m; i < a.t; ++i) {
+                r[i] = op(f, a[i]);
+            }
+            r.t = a.t;
+        }
+        r.s = op(this.s, a.s);
+        r.clamp();
+    };
+    // BigInteger.prototype.changeBit = bnpChangeBit;
+    // (protected) this op (1<<n)
+    BigInteger.prototype.changeBit = function (n, op) {
+        var r = BigInteger.ONE.shiftLeft(n);
+        this.bitwiseTo(r, op, r);
+        return r;
+    };
+    // BigInteger.prototype.addTo = bnpAddTo;
+    // (protected) r = this + a
+    BigInteger.prototype.addTo = function (a, r) {
+        var i = 0;
+        var c = 0;
+        var m = Math.min(a.t, this.t);
+        while (i < m) {
+            c += this[i] + a[i];
+            r[i++] = c & this.DM;
+            c >>= this.DB;
+        }
+        if (a.t < this.t) {
+            c += a.s;
+            while (i < this.t) {
+                c += this[i];
+                r[i++] = c & this.DM;
+                c >>= this.DB;
+            }
+            c += this.s;
+        }
+        else {
+            c += this.s;
+            while (i < a.t) {
+                c += a[i];
+                r[i++] = c & this.DM;
+                c >>= this.DB;
+            }
+            c += a.s;
+        }
+        r.s = (c < 0) ? -1 : 0;
+        if (c > 0) {
+            r[i++] = c;
+        }
+        else if (c < -1) {
+            r[i++] = this.DV + c;
+        }
+        r.t = i;
+        r.clamp();
+    };
+    // BigInteger.prototype.dMultiply = bnpDMultiply;
+    // (protected) this *= n, this >= 0, 1 < n < DV
+    BigInteger.prototype.dMultiply = function (n) {
+        this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
+        ++this.t;
+        this.clamp();
+    };
+    // BigInteger.prototype.dAddOffset = bnpDAddOffset;
+    // (protected) this += n << w words, this >= 0
+    BigInteger.prototype.dAddOffset = function (n, w) {
+        if (n == 0) {
+            return;
+        }
+        while (this.t <= w) {
+            this[this.t++] = 0;
+        }
+        this[w] += n;
+        while (this[w] >= this.DV) {
+            this[w] -= this.DV;
+            if (++w >= this.t) {
+                this[this.t++] = 0;
+            }
+            ++this[w];
+        }
+    };
+    // BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
+    // (protected) r = lower n words of "this * a", a.t <= n
+    // "this" should be the larger one if appropriate.
+    BigInteger.prototype.multiplyLowerTo = function (a, n, r) {
+        var i = Math.min(this.t + a.t, n);
+        r.s = 0; // assumes a,this >= 0
+        r.t = i;
+        while (i > 0) {
+            r[--i] = 0;
+        }
+        for (var j = r.t - this.t; i < j; ++i) {
+            r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
+        }
+        for (var j = Math.min(a.t, n); i < j; ++i) {
+            this.am(0, a[i], r, i, 0, n - i);
+        }
+        r.clamp();
+    };
+    // BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
+    // (protected) r = "this * a" without lower n words, n > 0
+    // "this" should be the larger one if appropriate.
+    BigInteger.prototype.multiplyUpperTo = function (a, n, r) {
+        --n;
+        var i = r.t = this.t + a.t - n;
+        r.s = 0; // assumes a,this >= 0
+        while (--i >= 0) {
+            r[i] = 0;
+        }
+        for (i = Math.max(n - this.t, 0); i < a.t; ++i) {
+            r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
+        }
+        r.clamp();
+        r.drShiftTo(1, r);
+    };
+    // BigInteger.prototype.modInt = bnpModInt;
+    // (protected) this % n, n < 2^26
+    BigInteger.prototype.modInt = function (n) {
+        if (n <= 0) {
+            return 0;
+        }
+        var d = this.DV % n;
+        var r = (this.s < 0) ? n - 1 : 0;
+        if (this.t > 0) {
+            if (d == 0) {
+                r = this[0] % n;
+            }
+            else {
+                for (var i = this.t - 1; i >= 0; --i) {
+                    r = (d * r + this[i]) % n;
+                }
+            }
+        }
+        return r;
+    };
+    // BigInteger.prototype.millerRabin = bnpMillerRabin;
+    // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
+    BigInteger.prototype.millerRabin = function (t) {
+        var n1 = this.subtract(BigInteger.ONE);
+        var k = n1.getLowestSetBit();
+        if (k <= 0) {
+            return false;
+        }
+        var r = n1.shiftRight(k);
+        t = (t + 1) >> 1;
+        if (t > lowprimes.length) {
+            t = lowprimes.length;
+        }
+        var a = nbi();
+        for (var i = 0; i < t; ++i) {
+            // Pick bases at random, instead of starting at 2
+            a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
+            var y = a.modPow(r, this);
+            if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
+                var j = 1;
+                while (j++ < k && y.compareTo(n1) != 0) {
+                    y = y.modPowInt(2, this);
+                    if (y.compareTo(BigInteger.ONE) == 0) {
+                        return false;
+                    }
+                }
+                if (y.compareTo(n1) != 0) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    };
+    // BigInteger.prototype.square = bnSquare;
+    // (public) this^2
+    BigInteger.prototype.square = function () {
+        var r = nbi();
+        this.squareTo(r);
+        return r;
+    };
+    //#region ASYNC
+    // Public API method
+    BigInteger.prototype.gcda = function (a, callback) {
+        var x = (this.s < 0) ? this.negate() : this.clone();
+        var y = (a.s < 0) ? a.negate() : a.clone();
+        if (x.compareTo(y) < 0) {
+            var t = x;
+            x = y;
+            y = t;
+        }
+        var i = x.getLowestSetBit();
+        var g = y.getLowestSetBit();
+        if (g < 0) {
+            callback(x);
+            return;
+        }
+        if (i < g) {
+            g = i;
+        }
+        if (g > 0) {
+            x.rShiftTo(g, x);
+            y.rShiftTo(g, y);
+        }
+        // Workhorse of the algorithm, gets called 200 - 800 times per 512 bit keygen.
+        var gcda1 = function () {
+            if ((i = x.getLowestSetBit()) > 0) {
+                x.rShiftTo(i, x);
+            }
+            if ((i = y.getLowestSetBit()) > 0) {
+                y.rShiftTo(i, y);
+            }
+            if (x.compareTo(y) >= 0) {
+                x.subTo(y, x);
+                x.rShiftTo(1, x);
+            }
+            else {
+                y.subTo(x, y);
+                y.rShiftTo(1, y);
+            }
+            if (!(x.signum() > 0)) {
+                if (g > 0) {
+                    y.lShiftTo(g, y);
+                }
+                setTimeout(function () { callback(y); }, 0); // escape
+            }
+            else {
+                setTimeout(gcda1, 0);
+            }
+        };
+        setTimeout(gcda1, 10);
+    };
+    // (protected) alternate constructor
+    BigInteger.prototype.fromNumberAsync = function (a, b, c, callback) {
+        if ("number" == typeof b) {
+            if (a < 2) {
+                this.fromInt(1);
+            }
+            else {
+                this.fromNumber(a, c);
+                if (!this.testBit(a - 1)) {
+                    this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
+                }
+                if (this.isEven()) {
+                    this.dAddOffset(1, 0);
+                }
+                var bnp_1 = this;
+                var bnpfn1_1 = function () {
+                    bnp_1.dAddOffset(2, 0);
+                    if (bnp_1.bitLength() > a) {
+                        bnp_1.subTo(BigInteger.ONE.shiftLeft(a - 1), bnp_1);
+                    }
+                    if (bnp_1.isProbablePrime(b)) {
+                        setTimeout(function () { callback(); }, 0); // escape
+                    }
+                    else {
+                        setTimeout(bnpfn1_1, 0);
+                    }
+                };
+                setTimeout(bnpfn1_1, 0);
+            }
+        }
+        else {
+            var x = [];
+            var t = a & 7;
+            x.length = (a >> 3) + 1;
+            b.nextBytes(x);
+            if (t > 0) {
+                x[0] &= ((1 << t) - 1);
+            }
+            else {
+                x[0] = 0;
+            }
+            this.fromString(x, 256);
+        }
+    };
+    return BigInteger;
+}());
+//#region REDUCERS
+//#region NullExp
+var NullExp = /** @class */ (function () {
+    function NullExp() {
+    }
+    // NullExp.prototype.convert = nNop;
+    NullExp.prototype.convert = function (x) {
+        return x;
+    };
+    // NullExp.prototype.revert = nNop;
+    NullExp.prototype.revert = function (x) {
+        return x;
+    };
+    // NullExp.prototype.mulTo = nMulTo;
+    NullExp.prototype.mulTo = function (x, y, r) {
+        x.multiplyTo(y, r);
+    };
+    // NullExp.prototype.sqrTo = nSqrTo;
+    NullExp.prototype.sqrTo = function (x, r) {
+        x.squareTo(r);
+    };
+    return NullExp;
+}());
+// Modular reduction using "classic" algorithm
+var Classic = /** @class */ (function () {
+    function Classic(m) {
+        this.m = m;
+    }
+    // Classic.prototype.convert = cConvert;
+    Classic.prototype.convert = function (x) {
+        if (x.s < 0 || x.compareTo(this.m) >= 0) {
+            return x.mod(this.m);
+        }
+        else {
+            return x;
+        }
+    };
+    // Classic.prototype.revert = cRevert;
+    Classic.prototype.revert = function (x) {
+        return x;
+    };
+    // Classic.prototype.reduce = cReduce;
+    Classic.prototype.reduce = function (x) {
+        x.divRemTo(this.m, null, x);
+    };
+    // Classic.prototype.mulTo = cMulTo;
+    Classic.prototype.mulTo = function (x, y, r) {
+        x.multiplyTo(y, r);
+        this.reduce(r);
+    };
+    // Classic.prototype.sqrTo = cSqrTo;
+    Classic.prototype.sqrTo = function (x, r) {
+        x.squareTo(r);
+        this.reduce(r);
+    };
+    return Classic;
+}());
+//#endregion
+//#region Montgomery
+// Montgomery reduction
+var Montgomery = /** @class */ (function () {
+    function Montgomery(m) {
+        this.m = m;
+        this.mp = m.invDigit();
+        this.mpl = this.mp & 0x7fff;
+        this.mph = this.mp >> 15;
+        this.um = (1 << (m.DB - 15)) - 1;
+        this.mt2 = 2 * m.t;
+    }
+    // Montgomery.prototype.convert = montConvert;
+    // xR mod m
+    Montgomery.prototype.convert = function (x) {
+        var r = nbi();
+        x.abs().dlShiftTo(this.m.t, r);
+        r.divRemTo(this.m, null, r);
+        if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) {
+            this.m.subTo(r, r);
+        }
+        return r;
+    };
+    // Montgomery.prototype.revert = montRevert;
+    // x/R mod m
+    Montgomery.prototype.revert = function (x) {
+        var r = nbi();
+        x.copyTo(r);
+        this.reduce(r);
+        return r;
+    };
+    // Montgomery.prototype.reduce = montReduce;
+    // x = x/R mod m (HAC 14.32)
+    Montgomery.prototype.reduce = function (x) {
+        while (x.t <= this.mt2) {
+            // pad x so am has enough room later
+            x[x.t++] = 0;
+        }
+        for (var i = 0; i < this.m.t; ++i) {
+            // faster way of calculating u0 = x[i]*mp mod DV
+            var j = x[i] & 0x7fff;
+            var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
+            // use am to combine the multiply-shift-add into one call
+            j = i + this.m.t;
+            x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
+            // propagate carry
+            while (x[j] >= x.DV) {
+                x[j] -= x.DV;
+                x[++j]++;
+            }
+        }
+        x.clamp();
+        x.drShiftTo(this.m.t, x);
+        if (x.compareTo(this.m) >= 0) {
+            x.subTo(this.m, x);
+        }
+    };
+    // Montgomery.prototype.mulTo = montMulTo;
+    // r = "xy/R mod m"; x,y != r
+    Montgomery.prototype.mulTo = function (x, y, r) {
+        x.multiplyTo(y, r);
+        this.reduce(r);
+    };
+    // Montgomery.prototype.sqrTo = montSqrTo;
+    // r = "x^2/R mod m"; x != r
+    Montgomery.prototype.sqrTo = function (x, r) {
+        x.squareTo(r);
+        this.reduce(r);
+    };
+    return Montgomery;
+}());
+//#endregion Montgomery
+//#region Barrett
+// Barrett modular reduction
+var Barrett = /** @class */ (function () {
+    function Barrett(m) {
+        this.m = m;
+        // setup Barrett
+        this.r2 = nbi();
+        this.q3 = nbi();
+        BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
+        this.mu = this.r2.divide(m);
+    }
+    // Barrett.prototype.convert = barrettConvert;
+    Barrett.prototype.convert = function (x) {
+        if (x.s < 0 || x.t > 2 * this.m.t) {
+            return x.mod(this.m);
+        }
+        else if (x.compareTo(this.m) < 0) {
+            return x;
+        }
+        else {
+            var r = nbi();
+            x.copyTo(r);
+            this.reduce(r);
+            return r;
+        }
+    };
+    // Barrett.prototype.revert = barrettRevert;
+    Barrett.prototype.revert = function (x) {
+        return x;
+    };
+    // Barrett.prototype.reduce = barrettReduce;
+    // x = x mod m (HAC 14.42)
+    Barrett.prototype.reduce = function (x) {
+        x.drShiftTo(this.m.t - 1, this.r2);
+        if (x.t > this.m.t + 1) {
+            x.t = this.m.t + 1;
+            x.clamp();
+        }
+        this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
+        this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
+        while (x.compareTo(this.r2) < 0) {
+            x.dAddOffset(1, this.m.t + 1);
+        }
+        x.subTo(this.r2, x);
+        while (x.compareTo(this.m) >= 0) {
+            x.subTo(this.m, x);
+        }
+    };
+    // Barrett.prototype.mulTo = barrettMulTo;
+    // r = x*y mod m; x,y != r
+    Barrett.prototype.mulTo = function (x, y, r) {
+        x.multiplyTo(y, r);
+        this.reduce(r);
+    };
+    // Barrett.prototype.sqrTo = barrettSqrTo;
+    // r = x^2 mod m; x != r
+    Barrett.prototype.sqrTo = function (x, r) {
+        x.squareTo(r);
+        this.reduce(r);
+    };
+    return Barrett;
+}());
+//#endregion
+//#endregion REDUCERS
+// return new, unset BigInteger
+function nbi() { return new BigInteger(null); }
+function parseBigInt(str, r) {
+    return new BigInteger(str, r);
+}
+// am: Compute w_j += (x*this_i), propagate carries,
+// c is initial carry, returns final carry.
+// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+// We need to select the fastest one that works in this environment.
+// am1: use a single mult and divide to get the high bits,
+// max digit bits should be 26 because
+// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+function am1(i, x, w, j, c, n) {
+    while (--n >= 0) {
+        var v = x * this[i++] + w[j] + c;
+        c = Math.floor(v / 0x4000000);
+        w[j++] = v & 0x3ffffff;
+    }
+    return c;
+}
+// am2 avoids a big mult-and-extract completely.
+// Max digit bits should be <= 30 because we do bitwise ops
+// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+function am2(i, x, w, j, c, n) {
+    var xl = x & 0x7fff;
+    var xh = x >> 15;
+    while (--n >= 0) {
+        var l = this[i] & 0x7fff;
+        var h = this[i++] >> 15;
+        var m = xh * l + h * xl;
+        l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
+        c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
+        w[j++] = l & 0x3fffffff;
+    }
+    return c;
+}
+// Alternately, set max digit bits to 28 since some
+// browsers slow down when dealing with 32-bit numbers.
+function am3(i, x, w, j, c, n) {
+    var xl = x & 0x3fff;
+    var xh = x >> 14;
+    while (--n >= 0) {
+        var l = this[i] & 0x3fff;
+        var h = this[i++] >> 14;
+        var m = xh * l + h * xl;
+        l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
+        c = (l >> 28) + (m >> 14) + xh * h;
+        w[j++] = l & 0xfffffff;
+    }
+    return c;
+}
+// if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+//     BigInteger.prototype.am = am2;
+//     dbits = 30;
+// }
+// else if (j_lm && (navigator.appName != "Netscape")) {
+//     BigInteger.prototype.am = am1;
+//     dbits = 26;
+// }
+// else { // Mozilla/Netscape seems to prefer am3
+//     BigInteger.prototype.am = am3;
+//     dbits = 28;
+// }
+BigInteger.prototype.am = am1;
+dbits = 26;
+
+BigInteger.prototype.DB = dbits;
+BigInteger.prototype.DM = ((1 << dbits) - 1);
+BigInteger.prototype.DV = (1 << dbits);
+var BI_FP = 52;
+BigInteger.prototype.FV = Math.pow(2, BI_FP);
+BigInteger.prototype.F1 = BI_FP - dbits;
+BigInteger.prototype.F2 = 2 * dbits - BI_FP;
+// Digit conversions
+var BI_RC = [];
+var rr;
+var vv;
+rr = "0".charCodeAt(0);
+for (vv = 0; vv <= 9; ++vv) {
+    BI_RC[rr++] = vv;
+}
+rr = "a".charCodeAt(0);
+for (vv = 10; vv < 36; ++vv) {
+    BI_RC[rr++] = vv;
+}
+rr = "A".charCodeAt(0);
+for (vv = 10; vv < 36; ++vv) {
+    BI_RC[rr++] = vv;
+}
+function intAt(s, i) {
+    var c = BI_RC[s.charCodeAt(i)];
+    return (c == null) ? -1 : c;
+}
+// return bigint initialized to value
+function nbv(i) {
+    var r = nbi();
+    r.fromInt(i);
+    return r;
+}
+// returns bit length of the integer x
+function nbits(x) {
+    var r = 1;
+    var t;
+    if ((t = x >>> 16) != 0) {
+        x = t;
+        r += 16;
+    }
+    if ((t = x >> 8) != 0) {
+        x = t;
+        r += 8;
+    }
+    if ((t = x >> 4) != 0) {
+        x = t;
+        r += 4;
+    }
+    if ((t = x >> 2) != 0) {
+        x = t;
+        r += 2;
+    }
+    if ((t = x >> 1) != 0) {
+        x = t;
+        r += 1;
+    }
+    return r;
+}
+// "constants"
+BigInteger.ZERO = nbv(0);
+BigInteger.ONE = nbv(1);
+
+// prng4.js - uses Arcfour as a PRNG
+var Arcfour = /** @class */ (function () {
+    function Arcfour() {
+        this.i = 0;
+        this.j = 0;
+        this.S = [];
+    }
+    // Arcfour.prototype.init = ARC4init;
+    // Initialize arcfour context from key, an array of ints, each from [0..255]
+    Arcfour.prototype.init = function (key) {
+        var i;
+        var j;
+        var t;
+        for (i = 0; i < 256; ++i) {
+            this.S[i] = i;
+        }
+        j = 0;
+        for (i = 0; i < 256; ++i) {
+            j = (j + this.S[i] + key[i % key.length]) & 255;
+            t = this.S[i];
+            this.S[i] = this.S[j];
+            this.S[j] = t;
+        }
+        this.i = 0;
+        this.j = 0;
+    };
+    // Arcfour.prototype.next = ARC4next;
+    Arcfour.prototype.next = function () {
+        var t;
+        this.i = (this.i + 1) & 255;
+        this.j = (this.j + this.S[this.i]) & 255;
+        t = this.S[this.i];
+        this.S[this.i] = this.S[this.j];
+        this.S[this.j] = t;
+        return this.S[(t + this.S[this.i]) & 255];
+    };
+    return Arcfour;
+}());
+// Plug in your RNG constructor here
+function prng_newstate() {
+    return new Arcfour();
+}
+// Pool size must be a multiple of 4 and greater than 32.
+// An array of bytes the size of the pool will be passed to init()
+var rng_psize = 256;
+
+// Random number generator - requires a PRNG backend, e.g. prng4.js
+var rng_state;
+var rng_pool = null;
+var rng_pptr;
+// Initialize the pool with junk if needed.
+if (rng_pool == null) {
+    rng_pool = [];
+    rng_pptr = 0;
+    var t = void 0;
+    if (window.crypto && window.crypto.getRandomValues) {
+        // Extract entropy (2048 bits) from RNG if available
+        var z = new Uint32Array(256);
+        window.crypto.getRandomValues(z);
+        for (t = 0; t < z.length; ++t) {
+            rng_pool[rng_pptr++] = z[t] & 255;
+        }
+    }
+    // Use mouse events for entropy, if we do not have enough entropy by the time
+    // we need it, entropy will be generated by Math.random.
+    var onMouseMoveListener_1 = function (ev) {
+        this.count = this.count || 0;
+        if (this.count >= 256 || rng_pptr >= rng_psize) {
+            if (window.removeEventListener) {
+                window.removeEventListener("mousemove", onMouseMoveListener_1, false);
+            }
+            else if (window.detachEvent) {
+                window.detachEvent("onmousemove", onMouseMoveListener_1);
+            }
+            return;
+        }
+        try {
+            var mouseCoordinates = ev.x + ev.y;
+            rng_pool[rng_pptr++] = mouseCoordinates & 255;
+            this.count += 1;
+        }
+        catch (e) {
+            // Sometimes Firefox will deny permission to access event properties for some reason. Ignore.
+        }
+    };
+    if (window.addEventListener) {
+        window.addEventListener("mousemove", onMouseMoveListener_1, false);
+    }
+    else if (window.attachEvent) {
+        window.attachEvent("onmousemove", onMouseMoveListener_1);
+    }
+}
+function rng_get_byte() {
+    if (rng_state == null) {
+        rng_state = prng_newstate();
+        // At this point, we may not have collected enough entropy.  If not, fall back to Math.random
+        while (rng_pptr < rng_psize) {
+            var random = Math.floor(65536 * Math.random());
+            rng_pool[rng_pptr++] = random & 255;
+        }
+        rng_state.init(rng_pool);
+        for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {
+            rng_pool[rng_pptr] = 0;
+        }
+        rng_pptr = 0;
+    }
+    // TODO: allow reseeding after first request
+    return rng_state.next();
+}
+var SecureRandom = /** @class */ (function () {
+    function SecureRandom() {
+    }
+    SecureRandom.prototype.nextBytes = function (ba) {
+        for (var i = 0; i < ba.length; ++i) {
+            ba[i] = rng_get_byte();
+        }
+    };
+    return SecureRandom;
+}());
+
+// Depends on jsbn.js and rng.js
+// function linebrk(s,n) {
+//   var ret = "";
+//   var i = 0;
+//   while(i + n < s.length) {
+//     ret += s.substring(i,i+n) + "\n";
+//     i += n;
+//   }
+//   return ret + s.substring(i,s.length);
+// }
+// function byte2Hex(b) {
+//   if(b < 0x10)
+//     return "0" + b.toString(16);
+//   else
+//     return b.toString(16);
+// }
+function pkcs1pad1(s, n) {
+    if (n < s.length + 22) {
+        console.error("Message too long for RSA");
+        return null;
+    }
+    var len = n - s.length - 6;
+    var filler = "";
+    for (var f = 0; f < len; f += 2) {
+        filler += "ff";
+    }
+    var m = "0001" + filler + "00" + s;
+    return parseBigInt(m, 16);
+}
+// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
+function pkcs1pad2(s, n) {
+    if (n < s.length + 11) { // TODO: fix for utf-8
+        console.error("Message too long for RSA");
+        return null;
+    }
+    var ba = [];
+    var i = s.length - 1;
+    while (i >= 0 && n > 0) {
+        var c = s.charCodeAt(i--);
+        if (c < 128) { // encode using utf-8
+            ba[--n] = c;
+        }
+        else if ((c > 127) && (c < 2048)) {
+            ba[--n] = (c & 63) | 128;
+            ba[--n] = (c >> 6) | 192;
+        }
+        else {
+            ba[--n] = (c & 63) | 128;
+            ba[--n] = ((c >> 6) & 63) | 128;
+            ba[--n] = (c >> 12) | 224;
+        }
+    }
+    ba[--n] = 0;
+    var rng = new SecureRandom();
+    var x = [];
+    while (n > 2) { // random non-zero pad
+        x[0] = 0;
+        while (x[0] == 0) {
+            rng.nextBytes(x);
+        }
+        ba[--n] = x[0];
+    }
+    ba[--n] = 2;
+    ba[--n] = 0;
+    return new BigInteger(ba);
+}
+// "empty" RSA key constructor
+var RSAKey = /** @class */ (function () {
+    function RSAKey() {
+        this.n = null;
+        this.e = 0;
+        this.d = null;
+        this.p = null;
+        this.q = null;
+        this.dmp1 = null;
+        this.dmq1 = null;
+        this.coeff = null;
+    }
+    //#region PROTECTED
+    // protected
+    // RSAKey.prototype.doPublic = RSADoPublic;
+    // Perform raw public operation on "x": return x^e (mod n)
+    RSAKey.prototype.doPublic = function (x) {
+        return x.modPowInt(this.e, this.n);
+    };
+    // RSAKey.prototype.doPrivate = RSADoPrivate;
+    // Perform raw private operation on "x": return x^d (mod n)
+    RSAKey.prototype.doPrivate = function (x) {
+        if (this.p == null || this.q == null) {
+            return x.modPow(this.d, this.n);
+        }
+        // TODO: re-calculate any missing CRT params
+        var xp = x.mod(this.p).modPow(this.dmp1, this.p);
+        var xq = x.mod(this.q).modPow(this.dmq1, this.q);
+        while (xp.compareTo(xq) < 0) {
+            xp = xp.add(this.p);
+        }
+        return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
+    };
+    //#endregion PROTECTED
+    //#region PUBLIC
+    // RSAKey.prototype.setPublic = RSASetPublic;
+    // Set the public key fields N and e from hex strings
+    RSAKey.prototype.setPublic = function (N, E) {
+        if (N != null && E != null && N.length > 0 && E.length > 0) {
+            this.n = parseBigInt(N, 16);
+            this.e = parseInt(E, 16);
+        }
+        else {
+            console.error("Invalid RSA public key");
+        }
+    };
+    // RSAKey.prototype.encrypt = RSAEncrypt;
+    // Return the PKCS#1 RSA encryption of "text" as an even-length hex string
+    RSAKey.prototype.encrypt = function (text) {
+        var m = pkcs1pad2(text, (this.n.bitLength() + 7) >> 3);
+        if (m == null) {
+            return null;
+        }
+        var c = this.doPublic(m);
+        if (c == null) {
+            return null;
+        }
+        var h = c.toString(16);
+        if ((h.length & 1) == 0) {
+            return h;
+        }
+        else {
+            return "0" + h;
+        }
+    };
+    // RSAKey.prototype.setPrivate = RSASetPrivate;
+    // Set the private key fields N, e, and d from hex strings
+    RSAKey.prototype.setPrivate = function (N, E, D) {
+        if (N != null && E != null && N.length > 0 && E.length > 0) {
+            this.n = parseBigInt(N, 16);
+            this.e = parseInt(E, 16);
+            this.d = parseBigInt(D, 16);
+        }
+        else {
+            console.error("Invalid RSA private key");
+        }
+    };
+    // RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
+    // Set the private key fields N, e, d and CRT params from hex strings
+    RSAKey.prototype.setPrivateEx = function (N, E, D, P, Q, DP, DQ, C) {
+        if (N != null && E != null && N.length > 0 && E.length > 0) {
+            this.n = parseBigInt(N, 16);
+            this.e = parseInt(E, 16);
+            this.d = parseBigInt(D, 16);
+            this.p = parseBigInt(P, 16);
+            this.q = parseBigInt(Q, 16);
+            this.dmp1 = parseBigInt(DP, 16);
+            this.dmq1 = parseBigInt(DQ, 16);
+            this.coeff = parseBigInt(C, 16);
+        }
+        else {
+            console.error("Invalid RSA private key");
+        }
+    };
+    // RSAKey.prototype.generate = RSAGenerate;
+    // Generate a new random private key B bits long, using public expt E
+    RSAKey.prototype.generate = function (B, E) {
+        var rng = new SecureRandom();
+        var qs = B >> 1;
+        this.e = parseInt(E, 16);
+        var ee = new BigInteger(E, 16);
+        for (;;) {
+            for (;;) {
+                this.p = new BigInteger(B - qs, 1, rng);
+                if (this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) {
+                    break;
+                }
+            }
+            for (;;) {
+                this.q = new BigInteger(qs, 1, rng);
+                if (this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) {
+                    break;
+                }
+            }
+            if (this.p.compareTo(this.q) <= 0) {
+                var t = this.p;
+                this.p = this.q;
+                this.q = t;
+            }
+            var p1 = this.p.subtract(BigInteger.ONE);
+            var q1 = this.q.subtract(BigInteger.ONE);
+            var phi = p1.multiply(q1);
+            if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
+                this.n = this.p.multiply(this.q);
+                this.d = ee.modInverse(phi);
+                this.dmp1 = this.d.mod(p1);
+                this.dmq1 = this.d.mod(q1);
+                this.coeff = this.q.modInverse(this.p);
+                break;
+            }
+        }
+    };
+    // RSAKey.prototype.decrypt = RSADecrypt;
+    // Return the PKCS#1 RSA decryption of "ctext".
+    // "ctext" is an even-length hex string and the output is a plain string.
+    RSAKey.prototype.decrypt = function (ctext) {
+        var c = parseBigInt(ctext, 16);
+        var m = this.doPrivate(c);
+        if (m == null) {
+            return null;
+        }
+        return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3);
+    };
+    // Generate a new random private key B bits long, using public expt E
+    RSAKey.prototype.generateAsync = function (B, E, callback) {
+        var rng = new SecureRandom();
+        var qs = B >> 1;
+        this.e = parseInt(E, 16);
+        var ee = new BigInteger(E, 16);
+        var rsa = this;
+        // These functions have non-descript names because they were originally for(;;) loops.
+        // I don't know about cryptography to give them better names than loop1-4.
+        var loop1 = function () {
+            var loop4 = function () {
+                if (rsa.p.compareTo(rsa.q) <= 0) {
+                    var t = rsa.p;
+                    rsa.p = rsa.q;
+                    rsa.q = t;
+                }
+                var p1 = rsa.p.subtract(BigInteger.ONE);
+                var q1 = rsa.q.subtract(BigInteger.ONE);
+                var phi = p1.multiply(q1);
+                if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
+                    rsa.n = rsa.p.multiply(rsa.q);
+                    rsa.d = ee.modInverse(phi);
+                    rsa.dmp1 = rsa.d.mod(p1);
+                    rsa.dmq1 = rsa.d.mod(q1);
+                    rsa.coeff = rsa.q.modInverse(rsa.p);
+                    setTimeout(function () { callback(); }, 0); // escape
+                }
+                else {
+                    setTimeout(loop1, 0);
+                }
+            };
+            var loop3 = function () {
+                rsa.q = nbi();
+                rsa.q.fromNumberAsync(qs, 1, rng, function () {
+                    rsa.q.subtract(BigInteger.ONE).gcda(ee, function (r) {
+                        if (r.compareTo(BigInteger.ONE) == 0 && rsa.q.isProbablePrime(10)) {
+                            setTimeout(loop4, 0);
+                        }
+                        else {
+                            setTimeout(loop3, 0);
+                        }
+                    });
+                });
+            };
+            var loop2 = function () {
+                rsa.p = nbi();
+                rsa.p.fromNumberAsync(B - qs, 1, rng, function () {
+                    rsa.p.subtract(BigInteger.ONE).gcda(ee, function (r) {
+                        if (r.compareTo(BigInteger.ONE) == 0 && rsa.p.isProbablePrime(10)) {
+                            setTimeout(loop3, 0);
+                        }
+                        else {
+                            setTimeout(loop2, 0);
+                        }
+                    });
+                });
+            };
+            setTimeout(loop2, 0);
+        };
+        setTimeout(loop1, 0);
+    };
+    RSAKey.prototype.sign = function (text, digestMethod, digestName) {
+        var header = getDigestHeader(digestName);
+        var digest = header + digestMethod(text).toString();
+        var m = pkcs1pad1(digest, this.n.bitLength() / 4);
+        if (m == null) {
+            return null;
+        }
+        var c = this.doPrivate(m);
+        if (c == null) {
+            return null;
+        }
+        var h = c.toString(16);
+        if ((h.length & 1) == 0) {
+            return h;
+        }
+        else {
+            return "0" + h;
+        }
+    };
+    RSAKey.prototype.verify = function (text, signature, digestMethod) {
+        var c = parseBigInt(signature, 16);
+        var m = this.doPublic(c);
+        if (m == null) {
+            return null;
+        }
+        var unpadded = m.toString(16).replace(/^1f+00/, "");
+        var digest = removeDigestHeader(unpadded);
+        return digest == digestMethod(text).toString();
+    };
+    return RSAKey;
+}());
+// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
+function pkcs1unpad2(d, n) {
+    var b = d.toByteArray();
+    var i = 0;
+    while (i < b.length && b[i] == 0) {
+        ++i;
+    }
+    if (b.length - i != n - 1 || b[i] != 2) {
+        return null;
+    }
+    ++i;
+    while (b[i] != 0) {
+        if (++i >= b.length) {
+            return null;
+        }
+    }
+    var ret = "";
+    while (++i < b.length) {
+        var c = b[i] & 255;
+        if (c < 128) { // utf-8 decode
+            ret += String.fromCharCode(c);
+        }
+        else if ((c > 191) && (c < 224)) {
+            ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63));
+            ++i;
+        }
+        else {
+            ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63));
+            i += 2;
+        }
+    }
+    return ret;
+}
+// https://tools.ietf.org/html/rfc3447#page-43
+var DIGEST_HEADERS = {
+    md2: "3020300c06082a864886f70d020205000410",
+    md5: "3020300c06082a864886f70d020505000410",
+    sha1: "3021300906052b0e03021a05000414",
+    sha224: "302d300d06096086480165030402040500041c",
+    sha256: "3031300d060960864801650304020105000420",
+    sha384: "3041300d060960864801650304020205000430",
+    sha512: "3051300d060960864801650304020305000440",
+    ripemd160: "3021300906052b2403020105000414",
+};
+function getDigestHeader(name) {
+    return DIGEST_HEADERS[name] || "";
+}
+function removeDigestHeader(str) {
+    for (var name_1 in DIGEST_HEADERS) {
+        if (DIGEST_HEADERS.hasOwnProperty(name_1)) {
+            var header = DIGEST_HEADERS[name_1];
+            var len = header.length;
+            if (str.substr(0, len) == header) {
+                return str.substr(len);
+            }
+        }
+    }
+    return str;
+}
+// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
+// function RSAEncryptB64(text) {
+//  var h = this.encrypt(text);
+//  if(h) return hex2b64(h); else return null;
+// }
+// public
+// RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
+
+/*!
+Copyright (c) 2011, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.9.0
+*/
+var YAHOO = {};
+YAHOO.lang = {
+    /**
+     * Utility to set up the prototype, constructor and superclass properties to
+     * support an inheritance strategy that can chain constructors and methods.
+     * Static members will not be inherited.
+     *
+     * @method extend
+     * @static
+     * @param {Function} subc   the object to modify
+     * @param {Function} superc the object to inherit
+     * @param {Object} overrides  additional properties/methods to add to the
+     *                              subclass prototype.  These will override the
+     *                              matching items obtained from the superclass
+     *                              if present.
+     */
+    extend: function(subc, superc, overrides) {
+        if (! superc || ! subc) {
+            throw new Error("YAHOO.lang.extend failed, please check that " +
+                "all dependencies are included.");
+        }
+
+        var F = function() {};
+        F.prototype = superc.prototype;
+        subc.prototype = new F();
+        subc.prototype.constructor = subc;
+        subc.superclass = superc.prototype;
+
+        if (superc.prototype.constructor == Object.prototype.constructor) {
+            superc.prototype.constructor = superc;
+        }
+
+        if (overrides) {
+            var i;
+            for (i in overrides) {
+                subc.prototype[i] = overrides[i];
+            }
+
+            /*
+             * IE will not enumerate native functions in a derived object even if the
+             * function was overridden.  This is a workaround for specific functions
+             * we care about on the Object prototype.
+             * @property _IEEnumFix
+             * @param {Function} r  the object to receive the augmentation
+             * @param {Function} s  the object that supplies the properties to augment
+             * @static
+             * @private
+             */
+            var _IEEnumFix = function() {},
+                ADD = ["toString", "valueOf"];
+            try {
+                if (/MSIE/.test(navigator.userAgent)) {
+                    _IEEnumFix = function(r, s) {
+                        for (i = 0; i < ADD.length; i = i + 1) {
+                            var fname = ADD[i], f = s[fname];
+                            if (typeof f === 'function' && f != Object.prototype[fname]) {
+                                r[fname] = f;
+                            }
+                        }
+                    };
+                }
+            } catch (ex) {}            _IEEnumFix(subc.prototype, overrides);
+        }
+    }
+};
+
+/* asn1-1.0.13.js (c) 2013-2017 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+
+/**
+ * @fileOverview
+ * @name asn1-1.0.js
+ * @author Kenji Urushima kenji.urushima@gmail.com
+ * @version asn1 1.0.13 (2017-Jun-02)
+ * @since jsrsasign 2.1
+ * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a>
+ */
+
+/**
+ * kjur's class library name space
+ * <p>
+ * This name space provides following name spaces:
+ * <ul>
+ * <li>{@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder</li>
+ * <li>{@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL</li>
+ * <li>{@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature
+ * class and utilities</li>
+ * </ul>
+ * </p>
+ * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
+ * @name KJUR
+ * @namespace kjur's class library name space
+ */
+var KJUR = {};
+
+/**
+ * kjur's ASN.1 class library name space
+ * <p>
+ * This is ITU-T X.690 ASN.1 DER encoder class library and
+ * class structure and methods is very similar to
+ * org.bouncycastle.asn1 package of
+ * well known BouncyCaslte Cryptography Library.
+ * <h4>PROVIDING ASN.1 PRIMITIVES</h4>
+ * Here are ASN.1 DER primitive classes.
+ * <ul>
+ * <li>0x01 {@link KJUR.asn1.DERBoolean}</li>
+ * <li>0x02 {@link KJUR.asn1.DERInteger}</li>
+ * <li>0x03 {@link KJUR.asn1.DERBitString}</li>
+ * <li>0x04 {@link KJUR.asn1.DEROctetString}</li>
+ * <li>0x05 {@link KJUR.asn1.DERNull}</li>
+ * <li>0x06 {@link KJUR.asn1.DERObjectIdentifier}</li>
+ * <li>0x0a {@link KJUR.asn1.DEREnumerated}</li>
+ * <li>0x0c {@link KJUR.asn1.DERUTF8String}</li>
+ * <li>0x12 {@link KJUR.asn1.DERNumericString}</li>
+ * <li>0x13 {@link KJUR.asn1.DERPrintableString}</li>
+ * <li>0x14 {@link KJUR.asn1.DERTeletexString}</li>
+ * <li>0x16 {@link KJUR.asn1.DERIA5String}</li>
+ * <li>0x17 {@link KJUR.asn1.DERUTCTime}</li>
+ * <li>0x18 {@link KJUR.asn1.DERGeneralizedTime}</li>
+ * <li>0x30 {@link KJUR.asn1.DERSequence}</li>
+ * <li>0x31 {@link KJUR.asn1.DERSet}</li>
+ * </ul>
+ * <h4>OTHER ASN.1 CLASSES</h4>
+ * <ul>
+ * <li>{@link KJUR.asn1.ASN1Object}</li>
+ * <li>{@link KJUR.asn1.DERAbstractString}</li>
+ * <li>{@link KJUR.asn1.DERAbstractTime}</li>
+ * <li>{@link KJUR.asn1.DERAbstractStructured}</li>
+ * <li>{@link KJUR.asn1.DERTaggedObject}</li>
+ * </ul>
+ * <h4>SUB NAME SPACES</h4>
+ * <ul>
+ * <li>{@link KJUR.asn1.cades} - CAdES long term signature format</li>
+ * <li>{@link KJUR.asn1.cms} - Cryptographic Message Syntax</li>
+ * <li>{@link KJUR.asn1.csr} - Certificate Signing Request (CSR/PKCS#10)</li>
+ * <li>{@link KJUR.asn1.tsp} - RFC 3161 Timestamping Protocol Format</li>
+ * <li>{@link KJUR.asn1.x509} - RFC 5280 X.509 certificate and CRL</li>
+ * </ul>
+ * </p>
+ * NOTE: Please ignore method summary and document of this namespace.
+ * This caused by a bug of jsdoc2.
+ * @name KJUR.asn1
+ * @namespace
+ */
+if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
+
+/**
+ * ASN1 utilities class
+ * @name KJUR.asn1.ASN1Util
+ * @class ASN1 utilities class
+ * @since asn1 1.0.2
+ */
+KJUR.asn1.ASN1Util = new function() {
+    this.integerToByteHex = function(i) {
+        var h = i.toString(16);
+        if ((h.length % 2) == 1) h = '0' + h;
+        return h;
+    };
+    this.bigIntToMinTwosComplementsHex = function(bigIntegerValue) {
+        var h = bigIntegerValue.toString(16);
+        if (h.substr(0, 1) != '-') {
+            if (h.length % 2 == 1) {
+                h = '0' + h;
+            } else {
+                if (! h.match(/^[0-7]/)) {
+                    h = '00' + h;
+                }
+            }
+        } else {
+            var hPos = h.substr(1);
+            var xorLen = hPos.length;
+            if (xorLen % 2 == 1) {
+                xorLen += 1;
+            } else {
+                if (! h.match(/^[0-7]/)) {
+                    xorLen += 2;
+                }
+            }
+            var hMask = '';
+            for (var i = 0; i < xorLen; i++) {
+                hMask += 'f';
+            }
+            var biMask = new BigInteger(hMask, 16);
+            var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE);
+            h = biNeg.toString(16).replace(/^-/, '');
+        }
+        return h;
+    };
+    /**
+     * get PEM string from hexadecimal data and header string
+     * @name getPEMStringFromHex
+     * @memberOf KJUR.asn1.ASN1Util
+     * @function
+     * @param {String} dataHex hexadecimal string of PEM body
+     * @param {String} pemHeader PEM header string (ex. 'RSA PRIVATE KEY')
+     * @return {String} PEM formatted string of input data
+     * @description
+     * This method converts a hexadecimal string to a PEM string with
+     * a specified header. Its line break will be CRLF("\r\n").
+     * @example
+     * var pem  = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY');
+     * // value of pem will be:
+     * -----BEGIN PRIVATE KEY-----
+     * YWFh
+     * -----END PRIVATE KEY-----
+     */
+    this.getPEMStringFromHex = function(dataHex, pemHeader) {
+        return hextopem(dataHex, pemHeader);
+    };
+
+    /**
+     * generate ASN1Object specifed by JSON parameters
+     * @name newObject
+     * @memberOf KJUR.asn1.ASN1Util
+     * @function
+     * @param {Array} param JSON parameter to generate ASN1Object
+     * @return {KJUR.asn1.ASN1Object} generated object
+     * @since asn1 1.0.3
+     * @description
+     * generate any ASN1Object specified by JSON param
+     * including ASN.1 primitive or structured.
+     * Generally 'param' can be described as follows:
+     * <blockquote>
+     * {TYPE-OF-ASNOBJ: ASN1OBJ-PARAMETER}
+     * </blockquote>
+     * 'TYPE-OF-ASN1OBJ' can be one of following symbols:
+     * <ul>
+     * <li>'bool' - DERBoolean</li>
+     * <li>'int' - DERInteger</li>
+     * <li>'bitstr' - DERBitString</li>
+     * <li>'octstr' - DEROctetString</li>
+     * <li>'null' - DERNull</li>
+     * <li>'oid' - DERObjectIdentifier</li>
+     * <li>'enum' - DEREnumerated</li>
+     * <li>'utf8str' - DERUTF8String</li>
+     * <li>'numstr' - DERNumericString</li>
+     * <li>'prnstr' - DERPrintableString</li>
+     * <li>'telstr' - DERTeletexString</li>
+     * <li>'ia5str' - DERIA5String</li>
+     * <li>'utctime' - DERUTCTime</li>
+     * <li>'gentime' - DERGeneralizedTime</li>
+     * <li>'seq' - DERSequence</li>
+     * <li>'set' - DERSet</li>
+     * <li>'tag' - DERTaggedObject</li>
+     * </ul>
+     * @example
+     * newObject({'prnstr': 'aaa'});
+     * newObject({'seq': [{'int': 3}, {'prnstr': 'aaa'}]})
+     * // ASN.1 Tagged Object
+     * newObject({'tag': {'tag': 'a1',
+     *                    'explicit': true,
+     *                    'obj': {'seq': [{'int': 3}, {'prnstr': 'aaa'}]}}});
+     * // more simple representation of ASN.1 Tagged Object
+     * newObject({'tag': ['a1',
+     *                    true,
+     *                    {'seq': [
+     *                      {'int': 3},
+     *                      {'prnstr': 'aaa'}]}
+     *                   ]});
+     */
+    this.newObject = function(param) {
+        var _KJUR = KJUR,
+            _KJUR_asn1 = _KJUR.asn1,
+            _DERBoolean = _KJUR_asn1.DERBoolean,
+            _DERInteger = _KJUR_asn1.DERInteger,
+            _DERBitString = _KJUR_asn1.DERBitString,
+            _DEROctetString = _KJUR_asn1.DEROctetString,
+            _DERNull = _KJUR_asn1.DERNull,
+            _DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
+            _DEREnumerated = _KJUR_asn1.DEREnumerated,
+            _DERUTF8String = _KJUR_asn1.DERUTF8String,
+            _DERNumericString = _KJUR_asn1.DERNumericString,
+            _DERPrintableString = _KJUR_asn1.DERPrintableString,
+            _DERTeletexString = _KJUR_asn1.DERTeletexString,
+            _DERIA5String = _KJUR_asn1.DERIA5String,
+            _DERUTCTime = _KJUR_asn1.DERUTCTime,
+            _DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime,
+            _DERSequence = _KJUR_asn1.DERSequence,
+            _DERSet = _KJUR_asn1.DERSet,
+            _DERTaggedObject = _KJUR_asn1.DERTaggedObject,
+            _newObject = _KJUR_asn1.ASN1Util.newObject;
+
+        var keys = Object.keys(param);
+        if (keys.length != 1)
+            throw "key of param shall be only one.";
+        var key = keys[0];
+
+        if (":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:".indexOf(":" + key + ":") == -1)
+            throw "undefined key: " + key;
+
+        if (key == "bool")    return new _DERBoolean(param[key]);
+        if (key == "int")     return new _DERInteger(param[key]);
+        if (key == "bitstr")  return new _DERBitString(param[key]);
+        if (key == "octstr")  return new _DEROctetString(param[key]);
+        if (key == "null")    return new _DERNull(param[key]);
+        if (key == "oid")     return new _DERObjectIdentifier(param[key]);
+        if (key == "enum")    return new _DEREnumerated(param[key]);
+        if (key == "utf8str") return new _DERUTF8String(param[key]);
+        if (key == "numstr")  return new _DERNumericString(param[key]);
+        if (key == "prnstr")  return new _DERPrintableString(param[key]);
+        if (key == "telstr")  return new _DERTeletexString(param[key]);
+        if (key == "ia5str")  return new _DERIA5String(param[key]);
+        if (key == "utctime") return new _DERUTCTime(param[key]);
+        if (key == "gentime") return new _DERGeneralizedTime(param[key]);
+
+        if (key == "seq") {
+            var paramList = param[key];
+            var a = [];
+            for (var i = 0; i < paramList.length; i++) {
+                var asn1Obj = _newObject(paramList[i]);
+                a.push(asn1Obj);
+            }
+            return new _DERSequence({'array': a});
+        }
+
+        if (key == "set") {
+            var paramList = param[key];
+            var a = [];
+            for (var i = 0; i < paramList.length; i++) {
+                var asn1Obj = _newObject(paramList[i]);
+                a.push(asn1Obj);
+            }
+            return new _DERSet({'array': a});
+        }
+
+        if (key == "tag") {
+            var tagParam = param[key];
+            if (Object.prototype.toString.call(tagParam) === '[object Array]' &&
+                tagParam.length == 3) {
+                var obj = _newObject(tagParam[2]);
+                return new _DERTaggedObject({tag: tagParam[0],
+                    explicit: tagParam[1],
+                    obj: obj});
+            } else {
+                var newParam = {};
+                if (tagParam.explicit !== undefined)
+                    newParam.explicit = tagParam.explicit;
+                if (tagParam.tag !== undefined)
+                    newParam.tag = tagParam.tag;
+                if (tagParam.obj === undefined)
+                    throw "obj shall be specified for 'tag'.";
+                newParam.obj = _newObject(tagParam.obj);
+                return new _DERTaggedObject(newParam);
+            }
+        }
+    };
+
+    /**
+     * get encoded hexadecimal string of ASN1Object specifed by JSON parameters
+     * @name jsonToASN1HEX
+     * @memberOf KJUR.asn1.ASN1Util
+     * @function
+     * @param {Array} param JSON parameter to generate ASN1Object
+     * @return hexadecimal string of ASN1Object
+     * @since asn1 1.0.4
+     * @description
+     * As for ASN.1 object representation of JSON object,
+     * please see {@link newObject}.
+     * @example
+     * jsonToASN1HEX({'prnstr': 'aaa'});
+     */
+    this.jsonToASN1HEX = function(param) {
+        var asn1Obj = this.newObject(param);
+        return asn1Obj.getEncodedHex();
+    };
+};
+
+/**
+ * get dot noted oid number string from hexadecimal value of OID
+ * @name oidHexToInt
+ * @memberOf KJUR.asn1.ASN1Util
+ * @function
+ * @param {String} hex hexadecimal value of object identifier
+ * @return {String} dot noted string of object identifier
+ * @since jsrsasign 4.8.3 asn1 1.0.7
+ * @description
+ * This static method converts from hexadecimal string representation of
+ * ASN.1 value of object identifier to oid number string.
+ * @example
+ * KJUR.asn1.ASN1Util.oidHexToInt('550406') &rarr; "2.5.4.6"
+ */
+KJUR.asn1.ASN1Util.oidHexToInt = function(hex) {
+    var s = "";
+    var i01 = parseInt(hex.substr(0, 2), 16);
+    var i0 = Math.floor(i01 / 40);
+    var i1 = i01 % 40;
+    var s = i0 + "." + i1;
+
+    var binbuf = "";
+    for (var i = 2; i < hex.length; i += 2) {
+        var value = parseInt(hex.substr(i, 2), 16);
+        var bin = ("00000000" + value.toString(2)).slice(- 8);
+        binbuf = binbuf + bin.substr(1, 7);
+        if (bin.substr(0, 1) == "0") {
+            var bi = new BigInteger(binbuf, 2);
+            s = s + "." + bi.toString(10);
+            binbuf = "";
+        }
+    }
+    return s;
+};
+
+/**
+ * get hexadecimal value of object identifier from dot noted oid value
+ * @name oidIntToHex
+ * @memberOf KJUR.asn1.ASN1Util
+ * @function
+ * @param {String} oidString dot noted string of object identifier
+ * @return {String} hexadecimal value of object identifier
+ * @since jsrsasign 4.8.3 asn1 1.0.7
+ * @description
+ * This static method converts from object identifier value string.
+ * to hexadecimal string representation of it.
+ * @example
+ * KJUR.asn1.ASN1Util.oidIntToHex("2.5.4.6") &rarr; "550406"
+ */
+KJUR.asn1.ASN1Util.oidIntToHex = function(oidString) {
+    var itox = function(i) {
+        var h = i.toString(16);
+        if (h.length == 1) h = '0' + h;
+        return h;
+    };
+
+    var roidtox = function(roid) {
+        var h = '';
+        var bi = new BigInteger(roid, 10);
+        var b = bi.toString(2);
+        var padLen = 7 - b.length % 7;
+        if (padLen == 7) padLen = 0;
+        var bPad = '';
+        for (var i = 0; i < padLen; i++) bPad += '0';
+        b = bPad + b;
+        for (var i = 0; i < b.length - 1; i += 7) {
+            var b8 = b.substr(i, 7);
+            if (i != b.length - 7) b8 = '1' + b8;
+            h += itox(parseInt(b8, 2));
+        }
+        return h;
+    };
+
+    if (! oidString.match(/^[0-9.]+$/)) {
+        throw "malformed oid string: " + oidString;
+    }
+    var h = '';
+    var a = oidString.split('.');
+    var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
+    h += itox(i0);
+    a.splice(0, 2);
+    for (var i = 0; i < a.length; i++) {
+        h += roidtox(a[i]);
+    }
+    return h;
+};
+
+
+// ********************************************************************
+//  Abstract ASN.1 Classes
+// ********************************************************************
+
+// ********************************************************************
+
+/**
+ * base class for ASN.1 DER encoder object
+ * @name KJUR.asn1.ASN1Object
+ * @class base class for ASN.1 DER encoder object
+ * @property {Boolean} isModified flag whether internal data was changed
+ * @property {String} hTLV hexadecimal string of ASN.1 TLV
+ * @property {String} hT hexadecimal string of ASN.1 TLV tag(T)
+ * @property {String} hL hexadecimal string of ASN.1 TLV length(L)
+ * @property {String} hV hexadecimal string of ASN.1 TLV value(V)
+ * @description
+ */
+KJUR.asn1.ASN1Object = function() {
+    var hV = '';
+
+    /**
+     * get hexadecimal ASN.1 TLV length(L) bytes from TLV value(V)
+     * @name getLengthHexFromValue
+     * @memberOf KJUR.asn1.ASN1Object#
+     * @function
+     * @return {String} hexadecimal string of ASN.1 TLV length(L)
+     */
+    this.getLengthHexFromValue = function() {
+        if (typeof this.hV == "undefined" || this.hV == null) {
+            throw "this.hV is null or undefined.";
+        }
+        if (this.hV.length % 2 == 1) {
+            throw "value hex must be even length: n=" + hV.length + ",v=" + this.hV;
+        }
+        var n = this.hV.length / 2;
+        var hN = n.toString(16);
+        if (hN.length % 2 == 1) {
+            hN = "0" + hN;
+        }
+        if (n < 128) {
+            return hN;
+        } else {
+            var hNlen = hN.length / 2;
+            if (hNlen > 15) {
+                throw "ASN.1 length too long to represent by 8x: n = " + n.toString(16);
+            }
+            var head = 128 + hNlen;
+            return head.toString(16) + hN;
+        }
+    };
+
+    /**
+     * get hexadecimal string of ASN.1 TLV bytes
+     * @name getEncodedHex
+     * @memberOf KJUR.asn1.ASN1Object#
+     * @function
+     * @return {String} hexadecimal string of ASN.1 TLV
+     */
+    this.getEncodedHex = function() {
+        if (this.hTLV == null || this.isModified) {
+            this.hV = this.getFreshValueHex();
+            this.hL = this.getLengthHexFromValue();
+            this.hTLV = this.hT + this.hL + this.hV;
+            this.isModified = false;
+            //alert("first time: " + this.hTLV);
+        }
+        return this.hTLV;
+    };
+
+    /**
+     * get hexadecimal string of ASN.1 TLV value(V) bytes
+     * @name getValueHex
+     * @memberOf KJUR.asn1.ASN1Object#
+     * @function
+     * @return {String} hexadecimal string of ASN.1 TLV value(V) bytes
+     */
+    this.getValueHex = function() {
+        this.getEncodedHex();
+        return this.hV;
+    };
+
+    this.getFreshValueHex = function() {
+        return '';
+    };
+};
+
+// == BEGIN DERAbstractString ================================================
+/**
+ * base class for ASN.1 DER string classes
+ * @name KJUR.asn1.DERAbstractString
+ * @class base class for ASN.1 DER string classes
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @property {String} s internal string of value
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>str - specify initial ASN.1 value(V) by a string</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ */
+KJUR.asn1.DERAbstractString = function(params) {
+    KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
+
+    /**
+     * get string value of this string object
+     * @name getString
+     * @memberOf KJUR.asn1.DERAbstractString#
+     * @function
+     * @return {String} string value of this string object
+     */
+    this.getString = function() {
+        return this.s;
+    };
+
+    /**
+     * set value by a string
+     * @name setString
+     * @memberOf KJUR.asn1.DERAbstractString#
+     * @function
+     * @param {String} newS value by a string to set
+     */
+    this.setString = function(newS) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = newS;
+        this.hV = stohex(this.s);
+    };
+
+    /**
+     * set value by a hexadecimal string
+     * @name setStringHex
+     * @memberOf KJUR.asn1.DERAbstractString#
+     * @function
+     * @param {String} newHexString value by a hexadecimal string to set
+     */
+    this.setStringHex = function(newHexString) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = null;
+        this.hV = newHexString;
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params == "string") {
+            this.setString(params);
+        } else if (typeof params['str'] != "undefined") {
+            this.setString(params['str']);
+        } else if (typeof params['hex'] != "undefined") {
+            this.setStringHex(params['hex']);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);
+// == END   DERAbstractString ================================================
+
+// == BEGIN DERAbstractTime ==================================================
+/**
+ * base class for ASN.1 DER Generalized/UTCTime class
+ * @name KJUR.asn1.DERAbstractTime
+ * @class base class for ASN.1 DER Generalized/UTCTime class
+ * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * @see KJUR.asn1.ASN1Object - superclass
+ */
+KJUR.asn1.DERAbstractTime = function(params) {
+    KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);
+
+    // --- PRIVATE METHODS --------------------
+    this.localDateToUTC = function(d) {
+        utc = d.getTime() + (d.getTimezoneOffset() * 60000);
+        var utcDate = new Date(utc);
+        return utcDate;
+    };
+
+    /*
+     * format date string by Data object
+     * @name formatDate
+     * @memberOf KJUR.asn1.AbstractTime;
+     * @param {Date} dateObject
+     * @param {string} type 'utc' or 'gen'
+     * @param {boolean} withMillis flag for with millisections or not
+     * @description
+     * 'withMillis' flag is supported from asn1 1.0.6.
+     */
+    this.formatDate = function(dateObject, type, withMillis) {
+        var pad = this.zeroPadding;
+        var d = this.localDateToUTC(dateObject);
+        var year = String(d.getFullYear());
+        if (type == 'utc') year = year.substr(2, 2);
+        var month = pad(String(d.getMonth() + 1), 2);
+        var day = pad(String(d.getDate()), 2);
+        var hour = pad(String(d.getHours()), 2);
+        var min = pad(String(d.getMinutes()), 2);
+        var sec = pad(String(d.getSeconds()), 2);
+        var s = year + month + day + hour + min + sec;
+        if (withMillis === true) {
+            var millis = d.getMilliseconds();
+            if (millis != 0) {
+                var sMillis = pad(String(millis), 3);
+                sMillis = sMillis.replace(/[0]+$/, "");
+                s = s + "." + sMillis;
+            }
+        }
+        return s + "Z";
+    };
+
+    this.zeroPadding = function(s, len) {
+        if (s.length >= len) return s;
+        return new Array(len - s.length + 1).join('0') + s;
+    };
+
+    // --- PUBLIC METHODS --------------------
+    /**
+     * get string value of this string object
+     * @name getString
+     * @memberOf KJUR.asn1.DERAbstractTime#
+     * @function
+     * @return {String} string value of this time object
+     */
+    this.getString = function() {
+        return this.s;
+    };
+
+    /**
+     * set value by a string
+     * @name setString
+     * @memberOf KJUR.asn1.DERAbstractTime#
+     * @function
+     * @param {String} newS value by a string to set such like "130430235959Z"
+     */
+    this.setString = function(newS) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = newS;
+        this.hV = stohex(newS);
+    };
+
+    /**
+     * set value by a Date object
+     * @name setByDateValue
+     * @memberOf KJUR.asn1.DERAbstractTime#
+     * @function
+     * @param {Integer} year year of date (ex. 2013)
+     * @param {Integer} month month of date between 1 and 12 (ex. 12)
+     * @param {Integer} day day of month
+     * @param {Integer} hour hours of date
+     * @param {Integer} min minutes of date
+     * @param {Integer} sec seconds of date
+     */
+    this.setByDateValue = function(year, month, day, hour, min, sec) {
+        var dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0));
+        this.setByDate(dateObject);
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+};
+YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);
+// == END   DERAbstractTime ==================================================
+
+// == BEGIN DERAbstractStructured ============================================
+/**
+ * base class for ASN.1 DER structured class
+ * @name KJUR.asn1.DERAbstractStructured
+ * @class base class for ASN.1 DER structured class
+ * @property {Array} asn1Array internal array of ASN1Object
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * @see KJUR.asn1.ASN1Object - superclass
+ */
+KJUR.asn1.DERAbstractStructured = function(params) {
+    KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
+
+    /**
+     * set value by array of ASN1Object
+     * @name setByASN1ObjectArray
+     * @memberOf KJUR.asn1.DERAbstractStructured#
+     * @function
+     * @param {array} asn1ObjectArray array of ASN1Object to set
+     */
+    this.setByASN1ObjectArray = function(asn1ObjectArray) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.asn1Array = asn1ObjectArray;
+    };
+
+    /**
+     * append an ASN1Object to internal array
+     * @name appendASN1Object
+     * @memberOf KJUR.asn1.DERAbstractStructured#
+     * @function
+     * @param {ASN1Object} asn1Object to add
+     */
+    this.appendASN1Object = function(asn1Object) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.asn1Array.push(asn1Object);
+    };
+
+    this.asn1Array = new Array();
+    if (typeof params != "undefined") {
+        if (typeof params['array'] != "undefined") {
+            this.asn1Array = params['array'];
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);
+
+
+// ********************************************************************
+//  ASN.1 Object Classes
+// ********************************************************************
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Boolean
+ * @name KJUR.asn1.DERBoolean
+ * @class class for ASN.1 DER Boolean
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * @see KJUR.asn1.ASN1Object - superclass
+ */
+KJUR.asn1.DERBoolean = function() {
+    KJUR.asn1.DERBoolean.superclass.constructor.call(this);
+    this.hT = "01";
+    this.hTLV = "0101ff";
+};
+YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Integer
+ * @name KJUR.asn1.DERInteger
+ * @class class for ASN.1 DER Integer
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>int - specify initial ASN.1 value(V) by integer value</li>
+ * <li>bigint - specify initial ASN.1 value(V) by BigInteger object</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ */
+KJUR.asn1.DERInteger = function(params) {
+    KJUR.asn1.DERInteger.superclass.constructor.call(this);
+    this.hT = "02";
+
+    /**
+     * set value by Tom Wu's BigInteger object
+     * @name setByBigInteger
+     * @memberOf KJUR.asn1.DERInteger#
+     * @function
+     * @param {BigInteger} bigIntegerValue to set
+     */
+    this.setByBigInteger = function(bigIntegerValue) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
+    };
+
+    /**
+     * set value by integer value
+     * @name setByInteger
+     * @memberOf KJUR.asn1.DERInteger
+     * @function
+     * @param {Integer} integer value to set
+     */
+    this.setByInteger = function(intValue) {
+        var bi = new BigInteger(String(intValue), 10);
+        this.setByBigInteger(bi);
+    };
+
+    /**
+     * set value by integer value
+     * @name setValueHex
+     * @memberOf KJUR.asn1.DERInteger#
+     * @function
+     * @param {String} hexadecimal string of integer value
+     * @description
+     * <br/>
+     * NOTE: Value shall be represented by minimum octet length of
+     * two's complement representation.
+     * @example
+     * new KJUR.asn1.DERInteger(123);
+     * new KJUR.asn1.DERInteger({'int': 123});
+     * new KJUR.asn1.DERInteger({'hex': '1fad'});
+     */
+    this.setValueHex = function(newHexString) {
+        this.hV = newHexString;
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params['bigint'] != "undefined") {
+            this.setByBigInteger(params['bigint']);
+        } else if (typeof params['int'] != "undefined") {
+            this.setByInteger(params['int']);
+        } else if (typeof params == "number") {
+            this.setByInteger(params);
+        } else if (typeof params['hex'] != "undefined") {
+            this.setValueHex(params['hex']);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER encoded BitString primitive
+ * @name KJUR.asn1.DERBitString
+ * @class class for ASN.1 DER encoded BitString primitive
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>bin - specify binary string (ex. '10111')</li>
+ * <li>array - specify array of boolean (ex. [true,false,true,true])</li>
+ * <li>hex - specify hexadecimal string of ASN.1 value(V) including unused bits</li>
+ * <li>obj - specify {@link KJUR.asn1.ASN1Util.newObject}
+ * argument for "BitString encapsulates" structure.</li>
+ * </ul>
+ * NOTE1: 'params' can be omitted.<br/>
+ * NOTE2: 'obj' parameter have been supported since
+ * asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).<br/>
+ * @example
+ * // default constructor
+ * o = new KJUR.asn1.DERBitString();
+ * // initialize with binary string
+ * o = new KJUR.asn1.DERBitString({bin: "1011"});
+ * // initialize with boolean array
+ * o = new KJUR.asn1.DERBitString({array: [true,false,true,true]});
+ * // initialize with hexadecimal string (04 is unused bits)
+ * o = new KJUR.asn1.DEROctetString({hex: "04bac0"});
+ * // initialize with ASN1Util.newObject argument for encapsulated
+ * o = new KJUR.asn1.DERBitString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
+ * // above generates a ASN.1 data like this:
+ * // BIT STRING, encapsulates {
+ * //   SEQUENCE {
+ * //     INTEGER 3
+ * //     PrintableString 'aaa'
+ * //     }
+ * //   }
+ */
+KJUR.asn1.DERBitString = function(params) {
+    if (params !== undefined && typeof params.obj !== "undefined") {
+        var o = KJUR.asn1.ASN1Util.newObject(params.obj);
+        params.hex = "00" + o.getEncodedHex();
+    }
+    KJUR.asn1.DERBitString.superclass.constructor.call(this);
+    this.hT = "03";
+
+    /**
+     * set ASN.1 value(V) by a hexadecimal string including unused bits
+     * @name setHexValueIncludingUnusedBits
+     * @memberOf KJUR.asn1.DERBitString#
+     * @function
+     * @param {String} newHexStringIncludingUnusedBits
+     */
+    this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = newHexStringIncludingUnusedBits;
+    };
+
+    /**
+     * set ASN.1 value(V) by unused bit and hexadecimal string of value
+     * @name setUnusedBitsAndHexValue
+     * @memberOf KJUR.asn1.DERBitString#
+     * @function
+     * @param {Integer} unusedBits
+     * @param {String} hValue
+     */
+    this.setUnusedBitsAndHexValue = function(unusedBits, hValue) {
+        if (unusedBits < 0 || 7 < unusedBits) {
+            throw "unused bits shall be from 0 to 7: u = " + unusedBits;
+        }
+        var hUnusedBits = "0" + unusedBits;
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = hUnusedBits + hValue;
+    };
+
+    /**
+     * set ASN.1 DER BitString by binary string<br/>
+     * @name setByBinaryString
+     * @memberOf KJUR.asn1.DERBitString#
+     * @function
+     * @param {String} binaryString binary value string (i.e. '10111')
+     * @description
+     * Its unused bits will be calculated automatically by length of
+     * 'binaryValue'. <br/>
+     * NOTE: Trailing zeros '0' will be ignored.
+     * @example
+     * o = new KJUR.asn1.DERBitString();
+     * o.setByBooleanArray("01011");
+     */
+    this.setByBinaryString = function(binaryString) {
+        binaryString = binaryString.replace(/0+$/, '');
+        var unusedBits = 8 - binaryString.length % 8;
+        if (unusedBits == 8) unusedBits = 0;
+        for (var i = 0; i <= unusedBits; i++) {
+            binaryString += '0';
+        }
+        var h = '';
+        for (var i = 0; i < binaryString.length - 1; i += 8) {
+            var b = binaryString.substr(i, 8);
+            var x = parseInt(b, 2).toString(16);
+            if (x.length == 1) x = '0' + x;
+            h += x;
+        }
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = '0' + unusedBits + h;
+    };
+
+    /**
+     * set ASN.1 TLV value(V) by an array of boolean<br/>
+     * @name setByBooleanArray
+     * @memberOf KJUR.asn1.DERBitString#
+     * @function
+     * @param {array} booleanArray array of boolean (ex. [true, false, true])
+     * @description
+     * NOTE: Trailing falses will be ignored in the ASN.1 DER Object.
+     * @example
+     * o = new KJUR.asn1.DERBitString();
+     * o.setByBooleanArray([false, true, false, true, true]);
+     */
+    this.setByBooleanArray = function(booleanArray) {
+        var s = '';
+        for (var i = 0; i < booleanArray.length; i++) {
+            if (booleanArray[i] == true) {
+                s += '1';
+            } else {
+                s += '0';
+            }
+        }
+        this.setByBinaryString(s);
+    };
+
+    /**
+     * generate an array of falses with specified length<br/>
+     * @name newFalseArray
+     * @memberOf KJUR.asn1.DERBitString
+     * @function
+     * @param {Integer} nLength length of array to generate
+     * @return {array} array of boolean falses
+     * @description
+     * This static method may be useful to initialize boolean array.
+     * @example
+     * o = new KJUR.asn1.DERBitString();
+     * o.newFalseArray(3) &rarr; [false, false, false]
+     */
+    this.newFalseArray = function(nLength) {
+        var a = new Array(nLength);
+        for (var i = 0; i < nLength; i++) {
+            a[i] = false;
+        }
+        return a;
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params == "string" && params.toLowerCase().match(/^[0-9a-f]+$/)) {
+            this.setHexValueIncludingUnusedBits(params);
+        } else if (typeof params['hex'] != "undefined") {
+            this.setHexValueIncludingUnusedBits(params['hex']);
+        } else if (typeof params['bin'] != "undefined") {
+            this.setByBinaryString(params['bin']);
+        } else if (typeof params['array'] != "undefined") {
+            this.setByBooleanArray(params['array']);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER OctetString<br/>
+ * @name KJUR.asn1.DEROctetString
+ * @class class for ASN.1 DER OctetString
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * This class provides ASN.1 OctetString simple type.<br/>
+ * Supported "params" attributes are:
+ * <ul>
+ * <li>str - to set a string as a value</li>
+ * <li>hex - to set a hexadecimal string as a value</li>
+ * <li>obj - to set a encapsulated ASN.1 value by JSON object
+ * which is defined in {@link KJUR.asn1.ASN1Util.newObject}</li>
+ * </ul>
+ * NOTE: A parameter 'obj' have been supported
+ * for "OCTET STRING, encapsulates" structure.
+ * since asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).
+ * @see KJUR.asn1.DERAbstractString - superclass
+ * @example
+ * // default constructor
+ * o = new KJUR.asn1.DEROctetString();
+ * // initialize with string
+ * o = new KJUR.asn1.DEROctetString({str: "aaa"});
+ * // initialize with hexadecimal string
+ * o = new KJUR.asn1.DEROctetString({hex: "616161"});
+ * // initialize with ASN1Util.newObject argument
+ * o = new KJUR.asn1.DEROctetString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
+ * // above generates a ASN.1 data like this:
+ * // OCTET STRING, encapsulates {
+ * //   SEQUENCE {
+ * //     INTEGER 3
+ * //     PrintableString 'aaa'
+ * //     }
+ * //   }
+ */
+KJUR.asn1.DEROctetString = function(params) {
+    if (params !== undefined && typeof params.obj !== "undefined") {
+        var o = KJUR.asn1.ASN1Util.newObject(params.obj);
+        params.hex = o.getEncodedHex();
+    }
+    KJUR.asn1.DEROctetString.superclass.constructor.call(this, params);
+    this.hT = "04";
+};
+YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Null
+ * @name KJUR.asn1.DERNull
+ * @class class for ASN.1 DER Null
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * @see KJUR.asn1.ASN1Object - superclass
+ */
+KJUR.asn1.DERNull = function() {
+    KJUR.asn1.DERNull.superclass.constructor.call(this);
+    this.hT = "05";
+    this.hTLV = "0500";
+};
+YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER ObjectIdentifier
+ * @name KJUR.asn1.DERObjectIdentifier
+ * @class class for ASN.1 DER ObjectIdentifier
+ * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'})
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ */
+KJUR.asn1.DERObjectIdentifier = function(params) {
+    var itox = function(i) {
+        var h = i.toString(16);
+        if (h.length == 1) h = '0' + h;
+        return h;
+    };
+    var roidtox = function(roid) {
+        var h = '';
+        var bi = new BigInteger(roid, 10);
+        var b = bi.toString(2);
+        var padLen = 7 - b.length % 7;
+        if (padLen == 7) padLen = 0;
+        var bPad = '';
+        for (var i = 0; i < padLen; i++) bPad += '0';
+        b = bPad + b;
+        for (var i = 0; i < b.length - 1; i += 7) {
+            var b8 = b.substr(i, 7);
+            if (i != b.length - 7) b8 = '1' + b8;
+            h += itox(parseInt(b8, 2));
+        }
+        return h;
+    };
+
+    KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);
+    this.hT = "06";
+
+    /**
+     * set value by a hexadecimal string
+     * @name setValueHex
+     * @memberOf KJUR.asn1.DERObjectIdentifier#
+     * @function
+     * @param {String} newHexString hexadecimal value of OID bytes
+     */
+    this.setValueHex = function(newHexString) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = null;
+        this.hV = newHexString;
+    };
+
+    /**
+     * set value by a OID string<br/>
+     * @name setValueOidString
+     * @memberOf KJUR.asn1.DERObjectIdentifier#
+     * @function
+     * @param {String} oidString OID string (ex. 2.5.4.13)
+     * @example
+     * o = new KJUR.asn1.DERObjectIdentifier();
+     * o.setValueOidString("2.5.4.13");
+     */
+    this.setValueOidString = function(oidString) {
+        if (! oidString.match(/^[0-9.]+$/)) {
+            throw "malformed oid string: " + oidString;
+        }
+        var h = '';
+        var a = oidString.split('.');
+        var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
+        h += itox(i0);
+        a.splice(0, 2);
+        for (var i = 0; i < a.length; i++) {
+            h += roidtox(a[i]);
+        }
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = null;
+        this.hV = h;
+    };
+
+    /**
+     * set value by a OID name
+     * @name setValueName
+     * @memberOf KJUR.asn1.DERObjectIdentifier#
+     * @function
+     * @param {String} oidName OID name (ex. 'serverAuth')
+     * @since 1.0.1
+     * @description
+     * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'.
+     * Otherwise raise error.
+     * @example
+     * o = new KJUR.asn1.DERObjectIdentifier();
+     * o.setValueName("serverAuth");
+     */
+    this.setValueName = function(oidName) {
+        var oid = KJUR.asn1.x509.OID.name2oid(oidName);
+        if (oid !== '') {
+            this.setValueOidString(oid);
+        } else {
+            throw "DERObjectIdentifier oidName undefined: " + oidName;
+        }
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (params !== undefined) {
+        if (typeof params === "string") {
+            if (params.match(/^[0-2].[0-9.]+$/)) {
+                this.setValueOidString(params);
+            } else {
+                this.setValueName(params);
+            }
+        } else if (params.oid !== undefined) {
+            this.setValueOidString(params.oid);
+        } else if (params.hex !== undefined) {
+            this.setValueHex(params.hex);
+        } else if (params.name !== undefined) {
+            this.setValueName(params.name);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Enumerated
+ * @name KJUR.asn1.DEREnumerated
+ * @class class for ASN.1 DER Enumerated
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>int - specify initial ASN.1 value(V) by integer value</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ * @example
+ * new KJUR.asn1.DEREnumerated(123);
+ * new KJUR.asn1.DEREnumerated({int: 123});
+ * new KJUR.asn1.DEREnumerated({hex: '1fad'});
+ */
+KJUR.asn1.DEREnumerated = function(params) {
+    KJUR.asn1.DEREnumerated.superclass.constructor.call(this);
+    this.hT = "0a";
+
+    /**
+     * set value by Tom Wu's BigInteger object
+     * @name setByBigInteger
+     * @memberOf KJUR.asn1.DEREnumerated#
+     * @function
+     * @param {BigInteger} bigIntegerValue to set
+     */
+    this.setByBigInteger = function(bigIntegerValue) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
+    };
+
+    /**
+     * set value by integer value
+     * @name setByInteger
+     * @memberOf KJUR.asn1.DEREnumerated#
+     * @function
+     * @param {Integer} integer value to set
+     */
+    this.setByInteger = function(intValue) {
+        var bi = new BigInteger(String(intValue), 10);
+        this.setByBigInteger(bi);
+    };
+
+    /**
+     * set value by integer value
+     * @name setValueHex
+     * @memberOf KJUR.asn1.DEREnumerated#
+     * @function
+     * @param {String} hexadecimal string of integer value
+     * @description
+     * <br/>
+     * NOTE: Value shall be represented by minimum octet length of
+     * two's complement representation.
+     */
+    this.setValueHex = function(newHexString) {
+        this.hV = newHexString;
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params['int'] != "undefined") {
+            this.setByInteger(params['int']);
+        } else if (typeof params == "number") {
+            this.setByInteger(params);
+        } else if (typeof params['hex'] != "undefined") {
+            this.setValueHex(params['hex']);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER UTF8String
+ * @name KJUR.asn1.DERUTF8String
+ * @class class for ASN.1 DER UTF8String
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERUTF8String = function(params) {
+    KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params);
+    this.hT = "0c";
+};
+YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER NumericString
+ * @name KJUR.asn1.DERNumericString
+ * @class class for ASN.1 DER NumericString
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERNumericString = function(params) {
+    KJUR.asn1.DERNumericString.superclass.constructor.call(this, params);
+    this.hT = "12";
+};
+YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER PrintableString
+ * @name KJUR.asn1.DERPrintableString
+ * @class class for ASN.1 DER PrintableString
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERPrintableString = function(params) {
+    KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params);
+    this.hT = "13";
+};
+YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER TeletexString
+ * @name KJUR.asn1.DERTeletexString
+ * @class class for ASN.1 DER TeletexString
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERTeletexString = function(params) {
+    KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params);
+    this.hT = "14";
+};
+YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER IA5String
+ * @name KJUR.asn1.DERIA5String
+ * @class class for ASN.1 DER IA5String
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERIA5String = function(params) {
+    KJUR.asn1.DERIA5String.superclass.constructor.call(this, params);
+    this.hT = "16";
+};
+YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER UTCTime
+ * @name KJUR.asn1.DERUTCTime
+ * @class class for ASN.1 DER UTCTime
+ * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
+ * @extends KJUR.asn1.DERAbstractTime
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * <li>date - specify Date object.</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ * <h4>EXAMPLES</h4>
+ * @example
+ * d1 = new KJUR.asn1.DERUTCTime();
+ * d1.setString('130430125959Z');
+ *
+ * d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'});
+ * d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))});
+ * d4 = new KJUR.asn1.DERUTCTime('130430125959Z');
+ */
+KJUR.asn1.DERUTCTime = function(params) {
+    KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params);
+    this.hT = "17";
+
+    /**
+     * set value by a Date object<br/>
+     * @name setByDate
+     * @memberOf KJUR.asn1.DERUTCTime#
+     * @function
+     * @param {Date} dateObject Date object to set ASN.1 value(V)
+     * @example
+     * o = new KJUR.asn1.DERUTCTime();
+     * o.setByDate(new Date("2016/12/31"));
+     */
+    this.setByDate = function(dateObject) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.date = dateObject;
+        this.s = this.formatDate(this.date, 'utc');
+        this.hV = stohex(this.s);
+    };
+
+    this.getFreshValueHex = function() {
+        if (typeof this.date == "undefined" && typeof this.s == "undefined") {
+            this.date = new Date();
+            this.s = this.formatDate(this.date, 'utc');
+            this.hV = stohex(this.s);
+        }
+        return this.hV;
+    };
+
+    if (params !== undefined) {
+        if (params.str !== undefined) {
+            this.setString(params.str);
+        } else if (typeof params == "string" && params.match(/^[0-9]{12}Z$/)) {
+            this.setString(params);
+        } else if (params.hex !== undefined) {
+            this.setStringHex(params.hex);
+        } else if (params.date !== undefined) {
+            this.setByDate(params.date);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER GeneralizedTime
+ * @name KJUR.asn1.DERGeneralizedTime
+ * @class class for ASN.1 DER GeneralizedTime
+ * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'})
+ * @property {Boolean} withMillis flag to show milliseconds or not
+ * @extends KJUR.asn1.DERAbstractTime
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * <li>date - specify Date object.</li>
+ * <li>millis - specify flag to show milliseconds (from 1.0.6)</li>
+ * </ul>
+ * NOTE1: 'params' can be omitted.
+ * NOTE2: 'withMillis' property is supported from asn1 1.0.6.
+ */
+KJUR.asn1.DERGeneralizedTime = function(params) {
+    KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params);
+    this.hT = "18";
+    this.withMillis = false;
+
+    /**
+     * set value by a Date object
+     * @name setByDate
+     * @memberOf KJUR.asn1.DERGeneralizedTime#
+     * @function
+     * @param {Date} dateObject Date object to set ASN.1 value(V)
+     * @example
+     * When you specify UTC time, use 'Date.UTC' method like this:<br/>
+     * o1 = new DERUTCTime();
+     * o1.setByDate(date);
+     *
+     * date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59
+     */
+    this.setByDate = function(dateObject) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.date = dateObject;
+        this.s = this.formatDate(this.date, 'gen', this.withMillis);
+        this.hV = stohex(this.s);
+    };
+
+    this.getFreshValueHex = function() {
+        if (this.date === undefined && this.s === undefined) {
+            this.date = new Date();
+            this.s = this.formatDate(this.date, 'gen', this.withMillis);
+            this.hV = stohex(this.s);
+        }
+        return this.hV;
+    };
+
+    if (params !== undefined) {
+        if (params.str !== undefined) {
+            this.setString(params.str);
+        } else if (typeof params == "string" && params.match(/^[0-9]{14}Z$/)) {
+            this.setString(params);
+        } else if (params.hex !== undefined) {
+            this.setStringHex(params.hex);
+        } else if (params.date !== undefined) {
+            this.setByDate(params.date);
+        }
+        if (params.millis === true) {
+            this.withMillis = true;
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Sequence
+ * @name KJUR.asn1.DERSequence
+ * @class class for ASN.1 DER Sequence
+ * @extends KJUR.asn1.DERAbstractStructured
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>array - specify array of ASN1Object to set elements of content</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ */
+KJUR.asn1.DERSequence = function(params) {
+    KJUR.asn1.DERSequence.superclass.constructor.call(this, params);
+    this.hT = "30";
+    this.getFreshValueHex = function() {
+        var h = '';
+        for (var i = 0; i < this.asn1Array.length; i++) {
+            var asn1Obj = this.asn1Array[i];
+            h += asn1Obj.getEncodedHex();
+        }
+        this.hV = h;
+        return this.hV;
+    };
+};
+YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Set
+ * @name KJUR.asn1.DERSet
+ * @class class for ASN.1 DER Set
+ * @extends KJUR.asn1.DERAbstractStructured
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>array - specify array of ASN1Object to set elements of content</li>
+ * <li>sortflag - flag for sort (default: true). ASN.1 BER is not sorted in 'SET OF'.</li>
+ * </ul>
+ * NOTE1: 'params' can be omitted.<br/>
+ * NOTE2: sortflag is supported since 1.0.5.
+ */
+KJUR.asn1.DERSet = function(params) {
+    KJUR.asn1.DERSet.superclass.constructor.call(this, params);
+    this.hT = "31";
+    this.sortFlag = true; // item shall be sorted only in ASN.1 DER
+    this.getFreshValueHex = function() {
+        var a = new Array();
+        for (var i = 0; i < this.asn1Array.length; i++) {
+            var asn1Obj = this.asn1Array[i];
+            a.push(asn1Obj.getEncodedHex());
+        }
+        if (this.sortFlag == true) a.sort();
+        this.hV = a.join('');
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params.sortflag != "undefined" &&
+            params.sortflag == false)
+            this.sortFlag = false;
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER TaggedObject
+ * @name KJUR.asn1.DERTaggedObject
+ * @class class for ASN.1 DER TaggedObject
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object.
+ * For example, if you find '[1]' tag in a ASN.1 dump,
+ * 'tagNoHex' will be 'a1'.
+ * <br/>
+ * As for optional argument 'params' for constructor, you can specify *ANY* of
+ * following properties:
+ * <ul>
+ * <li>explicit - specify true if this is explicit tag otherwise false
+ *     (default is 'true').</li>
+ * <li>tag - specify tag (default is 'a0' which means [0])</li>
+ * <li>obj - specify ASN1Object which is tagged</li>
+ * </ul>
+ * @example
+ * d1 = new KJUR.asn1.DERUTF8String({'str':'a'});
+ * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1});
+ * hex = d2.getEncodedHex();
+ */
+KJUR.asn1.DERTaggedObject = function(params) {
+    KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);
+    this.hT = "a0";
+    this.hV = '';
+    this.isExplicit = true;
+    this.asn1Object = null;
+
+    /**
+     * set value by an ASN1Object
+     * @name setString
+     * @memberOf KJUR.asn1.DERTaggedObject#
+     * @function
+     * @param {Boolean} isExplicitFlag flag for explicit/implicit tag
+     * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag
+     * @param {ASN1Object} asn1Object ASN.1 to encapsulate
+     */
+    this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) {
+        this.hT = tagNoHex;
+        this.isExplicit = isExplicitFlag;
+        this.asn1Object = asn1Object;
+        if (this.isExplicit) {
+            this.hV = this.asn1Object.getEncodedHex();
+            this.hTLV = null;
+            this.isModified = true;
+        } else {
+            this.hV = null;
+            this.hTLV = asn1Object.getEncodedHex();
+            this.hTLV = this.hTLV.replace(/^../, tagNoHex);
+            this.isModified = false;
+        }
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params['tag'] != "undefined") {
+            this.hT = params['tag'];
+        }
+        if (typeof params['explicit'] != "undefined") {
+            this.isExplicit = params['explicit'];
+        }
+        if (typeof params['obj'] != "undefined") {
+            this.asn1Object = params['obj'];
+            this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);
+
+/**
+ * Create a new JSEncryptRSAKey that extends Tom Wu's RSA key object.
+ * This object is just a decorator for parsing the key parameter
+ * @param {string|Object} key - The key in string format, or an object containing
+ * the parameters needed to build a RSAKey object.
+ * @constructor
+ */
+var JSEncryptRSAKey = /** @class */ (function (_super) {
+    __extends(JSEncryptRSAKey, _super);
+    function JSEncryptRSAKey(key) {
+        var _this = _super.call(this) || this;
+        // Call the super constructor.
+        //  RSAKey.call(this);
+        // If a key key was provided.
+        if (key) {
+            // If this is a string...
+            if (typeof key === "string") {
+                _this.parseKey(key);
+            }
+            else if (JSEncryptRSAKey.hasPrivateKeyProperty(key) ||
+                JSEncryptRSAKey.hasPublicKeyProperty(key)) {
+                // Set the values for the key.
+                _this.parsePropertiesFrom(key);
+            }
+        }
+        return _this;
+    }
+    /**
+     * Method to parse a pem encoded string containing both a public or private key.
+     * The method will translate the pem encoded string in a der encoded string and
+     * will parse private key and public key parameters. This method accepts public key
+     * in the rsaencryption pkcs #1 format (oid: 1.2.840.113549.1.1.1).
+     *
+     * @todo Check how many rsa formats use the same format of pkcs #1.
+     *
+     * The format is defined as:
+     * PublicKeyInfo ::= SEQUENCE {
+     *   algorithm       AlgorithmIdentifier,
+     *   PublicKey       BIT STRING
+     * }
+     * Where AlgorithmIdentifier is:
+     * AlgorithmIdentifier ::= SEQUENCE {
+     *   algorithm       OBJECT IDENTIFIER,     the OID of the enc algorithm
+     *   parameters      ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)
+     * }
+     * and PublicKey is a SEQUENCE encapsulated in a BIT STRING
+     * RSAPublicKey ::= SEQUENCE {
+     *   modulus           INTEGER,  -- n
+     *   publicExponent    INTEGER   -- e
+     * }
+     * it's possible to examine the structure of the keys obtained from openssl using
+     * an asn.1 dumper as the one used here to parse the components: http://lapo.it/asn1js/
+     * @argument {string} pem the pem encoded string, can include the BEGIN/END header/footer
+     * @private
+     */
+    JSEncryptRSAKey.prototype.parseKey = function (pem) {
+        try {
+            var modulus = 0;
+            var public_exponent = 0;
+            var reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/;
+            var der = reHex.test(pem) ? Hex.decode(pem) : Base64.unarmor(pem);
+            var asn1 = ASN1.decode(der);
+            // Fixes a bug with OpenSSL 1.0+ private keys
+            if (asn1.sub.length === 3) {
+                asn1 = asn1.sub[2].sub[0];
+            }
+            if (asn1.sub.length === 9) {
+                // Parse the private key.
+                modulus = asn1.sub[1].getHexStringValue(); // bigint
+                this.n = parseBigInt(modulus, 16);
+                public_exponent = asn1.sub[2].getHexStringValue(); // int
+                this.e = parseInt(public_exponent, 16);
+                var private_exponent = asn1.sub[3].getHexStringValue(); // bigint
+                this.d = parseBigInt(private_exponent, 16);
+                var prime1 = asn1.sub[4].getHexStringValue(); // bigint
+                this.p = parseBigInt(prime1, 16);
+                var prime2 = asn1.sub[5].getHexStringValue(); // bigint
+                this.q = parseBigInt(prime2, 16);
+                var exponent1 = asn1.sub[6].getHexStringValue(); // bigint
+                this.dmp1 = parseBigInt(exponent1, 16);
+                var exponent2 = asn1.sub[7].getHexStringValue(); // bigint
+                this.dmq1 = parseBigInt(exponent2, 16);
+                var coefficient = asn1.sub[8].getHexStringValue(); // bigint
+                this.coeff = parseBigInt(coefficient, 16);
+            }
+            else if (asn1.sub.length === 2) {
+                // Parse the public key.
+                var bit_string = asn1.sub[1];
+                var sequence = bit_string.sub[0];
+                modulus = sequence.sub[0].getHexStringValue();
+                this.n = parseBigInt(modulus, 16);
+                public_exponent = sequence.sub[1].getHexStringValue();
+                this.e = parseInt(public_exponent, 16);
+            }
+            else {
+                return false;
+            }
+            return true;
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Translate rsa parameters in a hex encoded string representing the rsa key.
+     *
+     * The translation follow the ASN.1 notation :
+     * RSAPrivateKey ::= SEQUENCE {
+     *   version           Version,
+     *   modulus           INTEGER,  -- n
+     *   publicExponent    INTEGER,  -- e
+     *   privateExponent   INTEGER,  -- d
+     *   prime1            INTEGER,  -- p
+     *   prime2            INTEGER,  -- q
+     *   exponent1         INTEGER,  -- d mod (p1)
+     *   exponent2         INTEGER,  -- d mod (q-1)
+     *   coefficient       INTEGER,  -- (inverse of q) mod p
+     * }
+     * @returns {string}  DER Encoded String representing the rsa private key
+     * @private
+     */
+    JSEncryptRSAKey.prototype.getPrivateBaseKey = function () {
+        var options = {
+            array: [
+                new KJUR.asn1.DERInteger({ int: 0 }),
+                new KJUR.asn1.DERInteger({ bigint: this.n }),
+                new KJUR.asn1.DERInteger({ int: this.e }),
+                new KJUR.asn1.DERInteger({ bigint: this.d }),
+                new KJUR.asn1.DERInteger({ bigint: this.p }),
+                new KJUR.asn1.DERInteger({ bigint: this.q }),
+                new KJUR.asn1.DERInteger({ bigint: this.dmp1 }),
+                new KJUR.asn1.DERInteger({ bigint: this.dmq1 }),
+                new KJUR.asn1.DERInteger({ bigint: this.coeff })
+            ]
+        };
+        var seq = new KJUR.asn1.DERSequence(options);
+        return seq.getEncodedHex();
+    };
+    /**
+     * base64 (pem) encoded version of the DER encoded representation
+     * @returns {string} pem encoded representation without header and footer
+     * @public
+     */
+    JSEncryptRSAKey.prototype.getPrivateBaseKeyB64 = function () {
+        return hex2b64(this.getPrivateBaseKey());
+    };
+    /**
+     * Translate rsa parameters in a hex encoded string representing the rsa public key.
+     * The representation follow the ASN.1 notation :
+     * PublicKeyInfo ::= SEQUENCE {
+     *   algorithm       AlgorithmIdentifier,
+     *   PublicKey       BIT STRING
+     * }
+     * Where AlgorithmIdentifier is:
+     * AlgorithmIdentifier ::= SEQUENCE {
+     *   algorithm       OBJECT IDENTIFIER,     the OID of the enc algorithm
+     *   parameters      ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)
+     * }
+     * and PublicKey is a SEQUENCE encapsulated in a BIT STRING
+     * RSAPublicKey ::= SEQUENCE {
+     *   modulus           INTEGER,  -- n
+     *   publicExponent    INTEGER   -- e
+     * }
+     * @returns {string} DER Encoded String representing the rsa public key
+     * @private
+     */
+    JSEncryptRSAKey.prototype.getPublicBaseKey = function () {
+        var first_sequence = new KJUR.asn1.DERSequence({
+            array: [
+                new KJUR.asn1.DERObjectIdentifier({ oid: "1.2.840.113549.1.1.1" }),
+                new KJUR.asn1.DERNull()
+            ]
+        });
+        var second_sequence = new KJUR.asn1.DERSequence({
+            array: [
+                new KJUR.asn1.DERInteger({ bigint: this.n }),
+                new KJUR.asn1.DERInteger({ int: this.e })
+            ]
+        });
+        var bit_string = new KJUR.asn1.DERBitString({
+            hex: "00" + second_sequence.getEncodedHex()
+        });
+        var seq = new KJUR.asn1.DERSequence({
+            array: [
+                first_sequence,
+                bit_string
+            ]
+        });
+        return seq.getEncodedHex();
+    };
+    /**
+     * base64 (pem) encoded version of the DER encoded representation
+     * @returns {string} pem encoded representation without header and footer
+     * @public
+     */
+    JSEncryptRSAKey.prototype.getPublicBaseKeyB64 = function () {
+        return hex2b64(this.getPublicBaseKey());
+    };
+    /**
+     * wrap the string in block of width chars. The default value for rsa keys is 64
+     * characters.
+     * @param {string} str the pem encoded string without header and footer
+     * @param {Number} [width=64] - the length the string has to be wrapped at
+     * @returns {string}
+     * @private
+     */
+    JSEncryptRSAKey.wordwrap = function (str, width) {
+        width = width || 64;
+        if (!str) {
+            return str;
+        }
+        var regex = "(.{1," + width + "})( +|$\n?)|(.{1," + width + "})";
+        return str.match(RegExp(regex, "g")).join("\n");
+    };
+    /**
+     * Retrieve the pem encoded private key
+     * @returns {string} the pem encoded private key with header/footer
+     * @public
+     */
+    JSEncryptRSAKey.prototype.getPrivateKey = function () {
+        var key = "-----BEGIN RSA PRIVATE KEY-----\n";
+        key += JSEncryptRSAKey.wordwrap(this.getPrivateBaseKeyB64()) + "\n";
+        key += "-----END RSA PRIVATE KEY-----";
+        return key;
+    };
+    /**
+     * Retrieve the pem encoded public key
+     * @returns {string} the pem encoded public key with header/footer
+     * @public
+     */
+    JSEncryptRSAKey.prototype.getPublicKey = function () {
+        var key = "-----BEGIN PUBLIC KEY-----\n";
+        key += JSEncryptRSAKey.wordwrap(this.getPublicBaseKeyB64()) + "\n";
+        key += "-----END PUBLIC KEY-----";
+        return key;
+    };
+    /**
+     * Check if the object contains the necessary parameters to populate the rsa modulus
+     * and public exponent parameters.
+     * @param {Object} [obj={}] - An object that may contain the two public key
+     * parameters
+     * @returns {boolean} true if the object contains both the modulus and the public exponent
+     * properties (n and e)
+     * @todo check for types of n and e. N should be a parseable bigInt object, E should
+     * be a parseable integer number
+     * @private
+     */
+    JSEncryptRSAKey.hasPublicKeyProperty = function (obj) {
+        obj = obj || {};
+        return (obj.hasOwnProperty("n") &&
+            obj.hasOwnProperty("e"));
+    };
+    /**
+     * Check if the object contains ALL the parameters of an RSA key.
+     * @param {Object} [obj={}] - An object that may contain nine rsa key
+     * parameters
+     * @returns {boolean} true if the object contains all the parameters needed
+     * @todo check for types of the parameters all the parameters but the public exponent
+     * should be parseable bigint objects, the public exponent should be a parseable integer number
+     * @private
+     */
+    JSEncryptRSAKey.hasPrivateKeyProperty = function (obj) {
+        obj = obj || {};
+        return (obj.hasOwnProperty("n") &&
+            obj.hasOwnProperty("e") &&
+            obj.hasOwnProperty("d") &&
+            obj.hasOwnProperty("p") &&
+            obj.hasOwnProperty("q") &&
+            obj.hasOwnProperty("dmp1") &&
+            obj.hasOwnProperty("dmq1") &&
+            obj.hasOwnProperty("coeff"));
+    };
+    /**
+     * Parse the properties of obj in the current rsa object. Obj should AT LEAST
+     * include the modulus and public exponent (n, e) parameters.
+     * @param {Object} obj - the object containing rsa parameters
+     * @private
+     */
+    JSEncryptRSAKey.prototype.parsePropertiesFrom = function (obj) {
+        this.n = obj.n;
+        this.e = obj.e;
+        if (obj.hasOwnProperty("d")) {
+            this.d = obj.d;
+            this.p = obj.p;
+            this.q = obj.q;
+            this.dmp1 = obj.dmp1;
+            this.dmq1 = obj.dmq1;
+            this.coeff = obj.coeff;
+        }
+    };
+    return JSEncryptRSAKey;
+}(RSAKey));
+
+/**
+ *
+ * @param {Object} [options = {}] - An object to customize JSEncrypt behaviour
+ * possible parameters are:
+ * - default_key_size        {number}  default: 1024 the key size in bit
+ * - default_public_exponent {string}  default: '010001' the hexadecimal representation of the public exponent
+ * - log                     {boolean} default: false whether log warn/error or not
+ * @constructor
+ */
+var JSEncrypt = /** @class */ (function () {
+    function JSEncrypt(options) {
+        options = options || {};
+        this.default_key_size = parseInt(options.default_key_size, 10) || 1024;
+        this.default_public_exponent = options.default_public_exponent || "010001"; // 65537 default openssl public exponent for rsa key type
+        this.log = options.log || false;
+        // The private and public key.
+        this.key = null;
+    }
+    /**
+     * Method to set the rsa key parameter (one method is enough to set both the public
+     * and the private key, since the private key contains the public key paramenters)
+     * Log a warning if logs are enabled
+     * @param {Object|string} key the pem encoded string or an object (with or without header/footer)
+     * @public
+     */
+    JSEncrypt.prototype.setKey = function (key) {
+        if (this.log && this.key) {
+            console.warn("A key was already set, overriding existing.");
+        }
+        this.key = new JSEncryptRSAKey(key);
+    };
+    /**
+     * Proxy method for setKey, for api compatibility
+     * @see setKey
+     * @public
+     */
+    JSEncrypt.prototype.setPrivateKey = function (privkey) {
+        // Create the key.
+        this.setKey(privkey);
+    };
+    /**
+     * Proxy method for setKey, for api compatibility
+     * @see setKey
+     * @public
+     */
+    JSEncrypt.prototype.setPublicKey = function (pubkey) {
+        // Sets the public key.
+        this.setKey(pubkey);
+    };
+    /**
+     * Proxy method for RSAKey object's decrypt, decrypt the string using the private
+     * components of the rsa key object. Note that if the object was not set will be created
+     * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor
+     * @param {string} str base64 encoded crypted string to decrypt
+     * @return {string} the decrypted string
+     * @public
+     */
+    JSEncrypt.prototype.decrypt = function (str) {
+        // Return the decrypted string.
+        try {
+            return this.getKey().decrypt(b64tohex(str));
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Proxy method for RSAKey object's encrypt, encrypt the string using the public
+     * components of the rsa key object. Note that if the object was not set will be created
+     * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor
+     * @param {string} str the string to encrypt
+     * @return {string} the encrypted string encoded in base64
+     * @public
+     */
+    JSEncrypt.prototype.encrypt = function (str) {
+        // Return the encrypted string.
+        try {
+            return hex2b64(this.getKey().encrypt(str));
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Proxy method for RSAKey object's sign.
+     * @param {string} str the string to sign
+     * @param {function} digestMethod hash method
+     * @param {string} digestName the name of the hash algorithm
+     * @return {string} the signature encoded in base64
+     * @public
+     */
+    JSEncrypt.prototype.sign = function (str, digestMethod, digestName) {
+        // return the RSA signature of 'str' in 'hex' format.
+        try {
+            return hex2b64(this.getKey().sign(str, digestMethod, digestName));
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Proxy method for RSAKey object's verify.
+     * @param {string} str the string to verify
+     * @param {string} signature the signature encoded in base64 to compare the string to
+     * @param {function} digestMethod hash method
+     * @return {boolean} whether the data and signature match
+     * @public
+     */
+    JSEncrypt.prototype.verify = function (str, signature, digestMethod) {
+        // Return the decrypted 'digest' of the signature.
+        try {
+            return this.getKey().verify(str, b64tohex(signature), digestMethod);
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Getter for the current JSEncryptRSAKey object. If it doesn't exists a new object
+     * will be created and returned
+     * @param {callback} [cb] the callback to be called if we want the key to be generated
+     * in an async fashion
+     * @returns {JSEncryptRSAKey} the JSEncryptRSAKey object
+     * @public
+     */
+    JSEncrypt.prototype.getKey = function (cb) {
+        // Only create new if it does not exist.
+        if (!this.key) {
+            // Get a new private key.
+            this.key = new JSEncryptRSAKey();
+            if (cb && {}.toString.call(cb) === "[object Function]") {
+                this.key.generateAsync(this.default_key_size, this.default_public_exponent, cb);
+                return;
+            }
+            // Generate the key.
+            this.key.generate(this.default_key_size, this.default_public_exponent);
+        }
+        return this.key;
+    };
+    /**
+     * Returns the pem encoded representation of the private key
+     * If the key doesn't exists a new key will be created
+     * @returns {string} pem encoded representation of the private key WITH header and footer
+     * @public
+     */
+    JSEncrypt.prototype.getPrivateKey = function () {
+        // Return the private representation of this key.
+        return this.getKey().getPrivateKey();
+    };
+    /**
+     * Returns the pem encoded representation of the private key
+     * If the key doesn't exists a new key will be created
+     * @returns {string} pem encoded representation of the private key WITHOUT header and footer
+     * @public
+     */
+    JSEncrypt.prototype.getPrivateKeyB64 = function () {
+        // Return the private representation of this key.
+        return this.getKey().getPrivateBaseKeyB64();
+    };
+    /**
+     * Returns the pem encoded representation of the public key
+     * If the key doesn't exists a new key will be created
+     * @returns {string} pem encoded representation of the public key WITH header and footer
+     * @public
+     */
+    JSEncrypt.prototype.getPublicKey = function () {
+        // Return the private representation of this key.
+        return this.getKey().getPublicKey();
+    };
+    /**
+     * Returns the pem encoded representation of the public key
+     * If the key doesn't exists a new key will be created
+     * @returns {string} pem encoded representation of the public key WITHOUT header and footer
+     * @public
+     */
+    JSEncrypt.prototype.getPublicKeyB64 = function () {
+        // Return the private representation of this key.
+        return this.getKey().getPublicBaseKeyB64();
+    };
+    JSEncrypt.version = "3.0.0-rc.1";
+    return JSEncrypt;
+}());
+
+window.JSEncrypt = JSEncrypt;
+
+exports.JSEncrypt = JSEncrypt;
+exports.default = JSEncrypt;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/d2d_app/client/js/myApps.js b/d2d_app/client/js/myApps.js
new file mode 100755 (executable)
index 0000000..9ea6114
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+"use strict";
+import { UpdateWebClip } from './app.js';
+import Actions from './actions.js';
+
+const serverPort = 9000;
+const serverURL = window.location.protocol + '//' + window.location.hostname;
+const actions = new Actions();
+const NEW_WINDOW_TIMEOUT = 1000;
+const myappsmodule = {};
+
+(function () {
+    var xhr;
+    function emptyElement(elm) {
+        while (elm.firstChild) {
+            elm.removeChild(elm.firstChild);
+        }
+        return elm;
+    }
+    /**
+     * Open app in new window
+     * @param {Object} response
+     * @private
+     */
+    function openAppWindow(response) {
+        document.getElementById("page-main").style.display = "none";
+        var timer = setTimeout(function () {
+            clearTimeout(timer);
+            document.getElementById("page-main").style.display = "block";
+            window.open(serverURL + ':' + response.port + '/app', 'newWindow');
+        }, NEW_WINDOW_TIMEOUT);
+    };
+
+    function showListView(dataArray) {
+        var formResult = document.getElementById("d2dApps"),
+            imgResult = document.getElementById("d2dAppList"),
+            formObj,
+            imgObj,
+            textObj,
+            objTable,
+            objRow,
+            i,
+            d2dApp,
+            icon;
+
+        emptyElement(imgResult);
+
+        objTable = document.createElement("div");
+        objTable.className = "result-table";
+
+        if (dataArray.length > 0) {
+            for (i = 0; i < dataArray.length; i++) {
+                formObj = document.createElement("div");
+                imgObj = document.createElement("img");
+                textObj = document.createElement("p");
+                formObj.style.textAlign = "center";
+                d2dApp = dataArray[i]['d2dApp'];
+                if (d2dApp.hasOwnProperty("appName")) {
+                    if (d2dApp.iconPath) {
+                        icon = d2dApp.iconPath.substring(d2dApp.iconPath.indexOf('/',10)+1);
+                        imgObj.src = `/d2dIcon/${icon}`;
+                    } else {
+                        imgObj.src = `./images/icon.png`;
+                    }
+                    imgObj.className = "app-icon-img";
+                    imgObj.alt = d2dApp.appName;
+                    textObj.style.display = "block";
+                    textObj.style.margin = "0 auto";
+                    textObj.style.fontSize = "14px";
+                    textObj.innerHTML = d2dApp.appName;
+                }
+                imgObj.addEventListener("click", actions.launchAppOnTV(
+                    d2dApp.appPkgID,
+                    d2dApp.appAppID,
+                    function (response) {
+                        openAppWindow(response);
+                    }));
+                formObj.appendChild(imgObj);
+                formObj.appendChild(textObj);
+
+                imgResult.appendChild(formObj);
+            }
+            formResult.appendChild(imgResult);
+        } else {
+            objRow = document.createElement("div");
+            objRow.className = "result-table-error";
+            objRow.appendChild(document.createTextNode("No Data"));
+            objTable.appendChild(objRow);
+        }
+    }
+
+    function showList() {
+        xhr = new XMLHttpRequest();
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState === xhr.DONE) {
+                if (xhr.status === 200 || xhr.status === 201) {
+                    showListView(JSON.parse(xhr.responseText));
+                } else {
+                    console.error(xhr.responseText);
+                }
+            }
+        };
+        xhr.open('GET', serverURL + ':' + serverPort + '/appList');
+        xhr.send();
+    }
+
+    function init() {
+        var eventSource = new EventSource(serverURL + ':' + serverPort + '/updateAppList');
+        eventSource.addEventListener('message', evt => {
+            showListView(JSON.parse(evt.data));
+            UpdateWebClip(JSON.parse(evt.data));
+        }, false);
+        eventSource.addEventListener('open', evt => {
+            console.log("Connected to...");
+        }, false);
+        eventSource.addEventListener('error', evt => {
+            if (evt.target.readyState == EventSource.CLOSED) {
+                console.log("Disconnected from...");
+            } else if (evt.target.readyState == EventSource.CONNECTING) {
+                console.log('Connecting to...');
+            }
+        }, false);
+        showList();
+    }
+    window.onload = init;
+    myappsmodule.openAppWindow = openAppWindow;
+}());
+
+export function openAppWindow(response) {
+    myappsmodule.openAppWindow(response);
+};
+
diff --git a/d2d_app/client/js/pincode.js b/d2d_app/client/js/pincode.js
new file mode 100755 (executable)
index 0000000..c1a49fe
--- /dev/null
@@ -0,0 +1,99 @@
+const serverPort = 9000;
+const serverURL = window.location.protocol + '//' + window.location.hostname;
+
+var publicKey;
+var input = '';
+var dots = document.querySelectorAll('.dot'), numbers = document.querySelectorAll('.number');
+
+function preloadKey() {
+    var xhr = new XMLHttpRequest();
+    xhr.onload = function () {
+        if (xhr.status === 200 || xhr.status === 201) {
+            publicKey = xhr.responseText;
+            if (publicKey) {
+                init();
+            } else {
+                console.error('[WT] Failed to get public key.');
+            }
+        } else {
+            console.error(xhr.responseText);
+        }
+    };
+    xhr.open('GET', serverURL + ':' + serverPort + '/publicKey');
+    xhr.send();
+}
+
+function init() {
+    dots = Array.prototype.slice.call(dots);
+    numbers = Array.prototype.slice.call(numbers);
+    numbers.forEach(function (number, index) {
+        number.addEventListener('click', function () {
+            number.className += ' grow';
+            if (number.innerHTML === '0') {
+                input += 0;
+            } else {
+                input += index + 1;
+            }
+            dots[input.length - 1].className += ' active';
+            if (input.length >= 4) {
+                sendPinCode(input);
+
+                setTimeout(function () {
+                    dots.forEach(function (dot, index) {
+                        dot.className = 'dot';
+                    });
+                    input = '';
+                }, 900);
+                setTimeout(function () {
+                    document.body.className = '';
+                }, 1000);
+            }
+            setTimeout(function () {
+                number.className = 'number';
+            }, 1000);
+        });
+    });
+}
+
+function sendPinCode(data) {
+    var encrypt = new JSEncrypt();
+    encrypt.setPublicKey(publicKey);
+    var xhr = new XMLHttpRequest();
+    xhr.onload = function () {
+        if (xhr.status === 200 || xhr.status === 201) {
+            console.log(`result : ${xhr.responseText}`);
+            chkPinCode(xhr.responseText === 'true' ? true : false);
+        } else {
+            console.error(xhr.responseText);
+        }
+    };
+    xhr.open('POST', serverURL + ':' + serverPort + '/pinCodeToServer');
+    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+    xhr.send(encrypt.encrypt(data));
+}
+
+function chkPinCode(returnVal) {
+    if (returnVal) {
+        dots.forEach(function (dot, index) {
+            dot.className += ' correct';
+        });
+        document.body.className += ' correct';
+        setTimeout(function () {
+            loginForm.submit();
+            //pinCode();
+        }, 1000);
+    } else {
+        dots.forEach(function (dot, index) {
+            dot.className += ' wrong';
+        });
+        document.body.className += ' wrong';
+    }
+}
+
+function pinCode() {
+    window.location.href = serverURL + ':' + serverPort + '/client/client.html';
+}
+
+window.onload = function () {
+    preloadKey();
+};
diff --git a/d2d_app/client/lib/tau/LICENSE.Flora b/d2d_app/client/lib/tau/LICENSE.Flora
new file mode 100644 (file)
index 0000000..4ab7e53
--- /dev/null
@@ -0,0 +1,206 @@
+Flora License
+
+Version 1.1, April, 2013
+
+http://floralicense.org/license/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction,
+and distribution as defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by
+the copyright owner that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and
+all other entities that control, are controlled by, or are
+under common control with that entity. For the purposes of
+this definition, "control" means (i) the power, direct or indirect,
+to cause the direction or management of such entity,
+whether by contract or otherwise, or (ii) ownership of fifty percent (50%)
+or more of the outstanding shares, or (iii) beneficial ownership of
+such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity
+exercising permissions granted by this License.
+
+"Source" form shall mean the preferred form for making modifications,
+including but not limited to software source code, documentation source,
+and configuration files.
+
+"Object" form shall mean any form resulting from mechanical
+transformation or translation of a Source form, including but
+not limited to compiled object code, generated documentation,
+and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form,
+made available under the License, as indicated by a copyright notice
+that is included in or attached to the work (an example is provided
+in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form,
+that is based on (or derived from) the Work and for which the editorial
+revisions, annotations, elaborations, or other modifications represent,
+as a whole, an original work of authorship. For the purposes of this License,
+Derivative Works shall not include works that remain separable from,
+or merely link (or bind by name) to the interfaces of, the Work and
+Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original
+version of the Work and any modifications or additions to that Work or
+Derivative Works thereof, that is intentionally submitted to Licensor
+for inclusion in the Work by the copyright owner or by an individual or
+Legal Entity authorized to submit on behalf of the copyright owner.
+For the purposes of this definition, "submitted" means any form of
+electronic, verbal, or written communication sent to the Licensor or
+its representatives, including but not limited to communication on
+electronic mailing lists, source code control systems, and issue
+tracking systems that are managed by, or on behalf of, the Licensor
+for the purpose of discussing and improving the Work, but excluding
+communication that is conspicuously marked or otherwise designated
+in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity
+on behalf of whom a Contribution has been received by Licensor and
+subsequently incorporated within the Work.
+
+"Tizen Certified Platform" shall mean a software platform that complies
+with the standards set forth in the Tizen Compliance Specification
+and passes the Tizen Compliance Tests as defined from time to time
+by the Tizen Technical Steering Group and certified by the Tizen
+Association or its designated agent.
+
+2. Grant of Copyright License.  Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the
+Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License.  Subject to the terms and conditions of
+this License, each Contributor hereby grants to You a perpetual,
+worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+(except as stated in this section) patent license to make, have made,
+use, offer to sell, sell, import, and otherwise transfer the Work
+solely as incorporated into a Tizen Certified Platform, where such
+license applies only to those patent claims licensable by such
+Contributor that are necessarily infringed by their Contribution(s)
+alone or by combination of their Contribution(s) with the Work solely
+as incorporated into a Tizen Certified Platform to which such
+Contribution(s) was submitted. If You institute patent litigation
+against any entity (including a cross-claim or counterclaim
+in a lawsuit) alleging that the Work or a Contribution incorporated
+within the Work constitutes direct or contributory patent infringement,
+then any patent licenses granted to You under this License for that
+Work shall terminate as of the date such litigation is filed.
+
+4. Redistribution.  You may reproduce and distribute copies of the
+Work or Derivative Works thereof pursuant to the copyright license
+above, in any medium, with or without modifications, and in Source or
+Object form, provided that You meet the following conditions:
+
+  1. You must give any other recipients of the Work or Derivative Works
+     a copy of this License; and
+  2. You must cause any modified files to carry prominent notices stating
+     that You changed the files; and
+  3. You must retain, in the Source form of any Derivative Works that
+     You distribute, all copyright, patent, trademark, and attribution
+     notices from the Source form of the Work, excluding those notices
+     that do not pertain to any part of the Derivative Works; and
+  4. If the Work includes a "NOTICE" text file as part of its distribution,
+     then any Derivative Works that You distribute must include a readable
+     copy of the attribution notices contained within such NOTICE file,
+     excluding those notices that do not pertain to any part of
+     the Derivative Works, in at least one of the following places:
+     within a NOTICE text file distributed as part of the Derivative Works;
+     within the Source form or documentation, if provided along with the
+     Derivative Works; or, within a display generated by the Derivative Works,
+     if and wherever such third-party notices normally appear.
+     The contents of the NOTICE file are for informational purposes only
+     and do not modify the License. You may add Your own attribution notices
+     within Derivative Works that You distribute, alongside or as an addendum
+     to the NOTICE text from the Work, provided that such additional attribution
+     notices cannot be construed as modifying the License. You may add Your own
+     copyright statement to Your modifications and may provide additional or
+     different license terms and conditions for use, reproduction, or
+     distribution of Your modifications, or for any such Derivative Works
+     as a whole, provided Your use, reproduction, and distribution of
+     the Work otherwise complies with the conditions stated in this License
+     and your own copyright statement or terms and conditions do not conflict
+     the conditions stated in the License including section 3.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+any Contribution intentionally submitted for inclusion in the Work
+by You to the Licensor shall be under the terms and conditions of
+this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify
+the terms of any separate license agreement you may have executed
+with Licensor regarding such Contributions.
+
+6. Trademarks.  This License does not grant permission to use the trade
+names, trademarks, service marks, or product names of the Licensor,
+except as required for reasonable and customary use in describing the
+origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+agreed to in writing, Licensor provides the Work (and each
+Contributor provides its Contributions) on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+implied, including, without limitation, any warranties or conditions
+of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+PARTICULAR PURPOSE. You are solely responsible for determining the
+appropriateness of using or redistributing the Work and assume any
+risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+whether in tort (including negligence), contract, or otherwise,
+unless required by applicable law (such as deliberate and grossly
+negligent acts) or agreed to in writing, shall any Contributor be
+liable to You for damages, including any direct, indirect, special,
+incidental, or consequential damages of any character arising as a
+result of this License or out of the use or inability to use the
+Work (including but not limited to damages for loss of goodwill,
+work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses), even if such Contributor
+has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+the Work or Derivative Works thereof, You may choose to offer,
+and charge a fee for, acceptance of support, warranty, indemnity,
+or other liability obligations and/or rights consistent with this
+License. However, in accepting such obligations, You may act only
+on Your own behalf and on Your sole responsibility, not on behalf
+of any other Contributor, and only if You agree to indemnify,
+defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason
+of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Flora License to your work
+
+To apply the Flora License to your work, attach the following
+boilerplate notice, with the fields enclosed by brackets "[]"
+replaced with your own identifying information. (Don't include
+the brackets!) The text should be enclosed in the appropriate
+comment syntax for the file format. We also recommend that a
+file or class name and description of purpose be included on the
+same "printed page" as the copyright notice for easier
+identification within third-party archives.
+
+   Copyright 2015 Samsung Electronics Co., Ltd.
+
+   Licensed under the Flora License, Version 1.1 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://floralicense.org/license/
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
diff --git a/d2d_app/client/lib/tau/VERSION b/d2d_app/client/lib/tau/VERSION
new file mode 100644 (file)
index 0000000..c813fe1
--- /dev/null
@@ -0,0 +1 @@
+1.2.5
diff --git a/d2d_app/client/lib/tau/animation/tau.animation.js b/d2d_app/client/lib/tau/animation/tau.animation.js
new file mode 100644 (file)
index 0000000..c6bb11a
--- /dev/null
@@ -0,0 +1,4077 @@
+(function(window) {
+(!window.tau) && (window.tau = {});
+var ns = window.tau.animation = {}; 
+(function(window, ns) {
+    ( function () {
+
+        var lastTime = 0;
+        var vendors = [ 'ms', 'moz', 'webkit', 'o' ];
+
+        for ( var x = 0; x < vendors.length && !window.requestAnimationFrame; ++ x ) {
+
+            window.requestAnimationFrame = window[ vendors[ x ] + 'RequestAnimationFrame' ];
+            window.cancelAnimationFrame = window[ vendors[ x ] + 'CancelAnimationFrame' ] || window[ vendors[ x ] + 'CancelRequestAnimationFrame' ];
+
+        }
+
+        if ( window.requestAnimationFrame === undefined ) {
+
+            window.requestAnimationFrame = function ( callback ) {
+
+                var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
+                var id = window.setTimeout( function() { callback( currTime + timeToCall ); }, timeToCall );
+                lastTime = currTime + timeToCall;
+                return id;
+
+            };
+
+        }
+
+        window.cancelAnimationFrame = window.cancelAnimationFrame || function ( id ) { window.clearTimeout( id ) };
+
+    }() );
+
+    (function init(window, ns) {
+        window.Uint8Array.prototype.setValue = function() {
+            for (var i = 0, len = this.length; i < len; i++) {
+                if (arguments[i] === undefined) {
+                    return;
+                } else {
+                    this[i] = arguments[i];
+                }
+            }
+
+        };
+
+        /**
+         * Gets time based on window time system
+         * @method getTime
+         * @return {Object}
+         * @member ns
+         * @static
+         */
+        ns.getTime = (function() {
+            if (window.performance) {
+                if (window.performance.now) {
+                    return function() {
+                        return window.performance.now()
+                    };
+                } else {
+                    if (window.performance.webkitNow) {
+                        return function() {
+                            return window.performance.webkitNow()
+                        };
+                    } else {
+                        return function() {
+                            return new Date().getTime()
+                        };
+                    }
+                }
+            } else {
+                return function() {
+                    return new Date().getTime()
+                };
+            }
+        })();
+
+
+
+    })(window, ns);
+
+
+    var base = {
+
+        /**
+         * Enum value for type of animation
+         * @variable ENUM
+         * @member ns.base
+         * @private
+         */
+        ENUM: {
+            NODETYPE: {
+                GROUP: 1,
+                ANIMATION: 2
+            },
+            GROUPTYPE: {
+                SEQUENCE: 4,
+                PARALLEL: 8
+            }
+        },
+
+        /**
+         * Calls given function every element of array
+         * @method forEach
+         * @param {Object} a
+         * @param {Function} f
+         * @return {Object}
+         * @member ns.base
+         * @public
+         */
+        forEach: function(a, f) {
+            for (var i = 0, il = (a && a.length); i < il; i++) {
+                var o = a[i];
+                f(o, i);
+            }
+        },
+
+        /**
+         * Returns copied object from the source
+         * @method copy
+         * @param {Object} src
+         * @param {Object} dst
+         * @return {Object}
+         * @member ns.base
+         * @private
+         */
+        copy: function(src, dst) {
+            dst = dst || {};
+
+            for (var key in src) {
+                if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') {
+                    dst[key] = src[key];
+//                    if(typeof(src.length) !== 'undefined') {
+//                        this.copy(src[key], dst[key]);
+//                    } else {
+//                        dst[key] = src[key];
+//                    }
+                }
+            }
+
+            return dst;
+        },
+
+        /**
+         * Returns copied array from the source
+         * @method arrayCopy
+         * @param {Object} src
+         * @param {Object} dst
+         * @return {Object}
+         * @member ns.base
+         * @private
+         */
+        arrayCopy: function(src, dst) {
+            var i, l = src.length;
+
+            if (l !== undefined) {
+                if (dst === undefined) {
+                    if (src instanceof Uint8Array) {
+                        dst = new Uint8Array(l)
+                    } else {
+                        dst = [];
+                    }
+                }
+
+                for (i = 0; i < l; i++) {
+                    if(typeof src[i] !== 'string' && src[i].length !== undefined) {
+                        dst[i] = ns.base.arrayCopy(src[i]);
+                    } else {
+                        dst[i] = src[i];
+                    }
+                }
+
+            } else {
+                dst = src;
+            }
+
+            return dst;
+        },
+
+        /**
+         * Returns copied object from the source. DeepCopy checks all type of property in source such as object, string, number, and so on.
+         * @method deepCopy
+         * @param {Object} src
+         * @param {Object} dst
+         * @return {Object}
+         * @member ns.base
+         * @private
+         */
+        deepCopy: function(src, dst, filter) {
+            if (typeof(src) == 'object') {
+                dst = dst || {};
+                if (typeof(src.length) != 'undefined') {
+                    if (src instanceof Array) {
+                        dst = new Array();
+                    } else if (src instanceof Uint8Array) {
+                        dst = new Uint8Array(src.length);
+                    }
+                }
+
+                for (var objInd in src) {
+                    if (typeof(src[objInd]) == 'object') {
+                        dst[objInd] = this.deepCopy(src[objInd]);
+                    } else if (typeof(src[objInd]) == 'string') {
+                        dst[objInd] = src[objInd];
+                    } else if (typeof(src[objInd]) == 'number') {
+                        dst[objInd] = src[objInd];
+                    } else if (typeof(src[objInd]) == 'boolean') {
+                        ((src[objInd] == true) ? dst[objInd] = true : dst[objInd] = false);
+                    }
+                }
+            } else {
+                dst = src;
+            }
+            return dst;
+        },
+
+        /**
+         * Returns SingleTon object. This function provide usage of SingleTon pattern.
+         * @method singleTon
+         * @param {Object} SingletonObject
+         * @return {Object}
+         * @member ns.base
+         * @private
+         */
+        singleTon: function(SingletonObject) {
+            var _singleton = {};
+
+            _singleton.getInstance = function() {
+                if (this._singleton === undefined) {
+                    this._singleton = new SingletonObject;
+                }
+                return this._singleton;
+            };
+
+            return _singleton;
+        },
+
+        /**
+         * Returns true or false based on whether the type of parameter is number or not.
+         * @method isNumber
+         * @param {Number} n
+         * @return {Boolean}
+         * @member ns.base
+         * @public
+         */
+        isNumber: function(n) {
+            return (typeof n === 'number')
+        },
+
+        /**
+         * Returns true or false based on whether the type of parameter is function or not.
+         * @method isFunction
+         * @param {Number} value
+         * @return {Boolean}
+         * @member ns.base
+         * @public
+         */
+        isFunction: function(value) {
+            return (typeof value === 'function');
+        },
+
+        /**
+         * Returns true or false based on whether the parameter is object or not.
+         * @method isObject
+         * @param {Number} value
+         * @return {Boolean}
+         * @member ns.base
+         * @public
+         */
+        isObject: function(value) {
+            return (value instanceof Object);
+        },
+
+        /**
+         * Returns true or false based on whether the parameter is array or not.
+         * @method isArray
+         * @param {Number} value
+         * @return {Boolean}
+         * @member ns.base
+         * @public
+         */
+        isArray: function(value) {
+            return (value instanceof Array);
+        },
+
+        // TODO: deprecated - use ns.$
+        selector: function(str) {
+            var s = str.slice(0, 1),
+                c = str.slice(1), result;
+
+            if(s === '.') {
+                result = document.getElementsByClassName(c);
+            } else if(s === '#') {
+                result = document.getElementById(c);
+            }
+            return result;
+        }
+    };
+
+    base.WeakMap = function() {
+        // private references holders
+        this.keys = [];
+        this.values = [];
+        this.i = 0;
+    };
+
+    // WeakMap#delete(key:void*):void
+    base.WeakMap.prototype.del = function(key) {
+        if (this.has(key)) {
+            this.keys.splice(this.i, 1);
+            this.values.splice(this.i, 1);
+        }
+        return -1 < this.i;
+    };
+
+    base.WeakMap.prototype.get = function(key, d3fault) {
+        return this.has(key) ? this.values[this.i] : d3fault;
+    };
+
+    base.WeakMap.prototype.has = function(key) {
+        if (key !== Object(key))
+            throw new TypeError("not a non-null object");
+        this.i = Array.prototype.indexOf.call(this.keys, key);
+        return -1 < this.i;
+    };
+
+    base.WeakMap.prototype.set = function(key, value) {
+        this.has(key) ? this.values[this.i] = value : this.values[this.keys.push(key) - 1] = value;
+    };
+
+    base.WeakMap.prototype.getKey = function() {
+        return this.keys;
+    };
+
+    var initializing = false, fnTest = /xyz/.test(function() {
+        xyz;
+    }) ? /\b_super\b/ : /.*/;
+
+    // The base Class implementation (does nothing)
+    base.Class = function() {
+    };
+
+    // Create a new Class that inherits from this class
+    base.Class.extend = function(prop) {
+        var _super = this.prototype;
+        var _static = prop.static;
+        // Instantiate a base class (but only create the instance,
+        // don't run the init constructor)
+        initializing = true;
+        var prototype = new this();
+        initializing = false;
+
+        // Copy the properties over onto the new prototype
+        for (var name in prop) {
+            if (name !== 'static') {
+                // Check if we're overwriting an existing function
+                prototype[name] = typeof prop[name] == "function" &&
+                    typeof _super[name] == "function" && fnTest.test(prop[name]) ?
+                    (function(name, fn) {
+                        return function() {
+                            var tmp = this._super;
+
+                            // Add a new ._super() method that is the same method
+                            // but on the super-class
+                            this._super = _super[name];
+
+                            // The method only need to be bound temporarily, so we
+                            // remove it when we're done executing
+                            var ret = fn.apply(this, arguments);
+                            this._super = tmp;
+
+                            return ret;
+                        };
+                    })(name, prop[name]) :
+                    prop[name];
+            }
+
+        }
+
+        // The dummy class constructor
+        function Class() {
+            // All construction is actually done in the init method
+            if (!initializing && this._init)
+                return this._init.apply(this, arguments);
+        }
+
+        // Populate our constructed prototype object
+        Class.prototype = prototype;
+
+        // Enforce the constructor to be what we expect
+        Class.prototype.constructor = Class;
+
+        // And make this class extendable
+        Class.extend = arguments.callee;
+
+        if (_static) {
+            for (var p in _static) {
+                if (_static.hasOwnProperty(p)) {
+                    Class[p] = _static[p];
+                }
+            }
+        }
+
+        return Class;
+    };
+
+    ns.base = base;
+
+})(window, ns);
+
+
+
+
+
+
+
+
+(function(window, ns) {
+    'use strict';
+
+    var Ticker = ns.base.Class.extend({
+        _init: function() {
+
+            this.now = ns.getTime;
+            this._frameId = null; // requeatAnimatoinFrame ID
+
+            this.animators = [];
+            this.animatorIdx = 0;
+        },
+
+        /**
+         * On requestAnimationFrame with tick.
+         * @method tickOn
+         * @member ns.Ticker
+         * @private
+         */
+        tickOn: function() {
+            var self = this;
+
+            (function loop() {
+                self._frameId = window.requestAnimationFrame(loop);
+                var i,
+                    time = ns.getTime();
+
+                for(i = 0; i < self.animatorIdx; i++) {
+                    self.animators[i].tick(time);
+                }
+            })();
+        },
+
+        /**
+         * Off requestAnimationFrame by cancelAnimationFrame.
+         * @method tickOn
+         * @member ns.Ticker
+         * @private
+         */
+        tickOff: function() {
+            if(this._frameId) {
+                window.cancelAnimationFrame(this._frameId);
+                this._frameId = null;
+            }
+        },
+
+        /**
+         * Triggers Ticker's status by on
+         * @event __on
+         * @member ns.Ticker
+         * @private
+         */
+        __on : function(e) {
+            if(this.animators.indexOf(e) < 0) {  // TODO : change map ?
+                //this.animators.push(e);
+                this.animators[this.animatorIdx] = e;
+                this.animatorIdx++;
+
+                if(this._frameId === null) {
+                    this.tickOn();
+                }
+            }
+        },
+
+        /**
+         * Triggers Ticker's status by off
+         * @event __off
+         * @member ns.Ticker
+         * @private
+         */
+        __off : function(e) {
+            var idx = this.animators.indexOf(e);
+            if(idx >= 0) {
+
+                this.animators.splice(idx, 1);
+                this.animatorIdx--;
+
+                if(this.animatorIdx === 0) {
+                    this.tickOff();
+                }
+            }
+        }
+    });
+
+    /*
+    * Ticks with requestAnimationFrame
+    */
+    ns.Ticker = ns.base.singleTon(Ticker);
+})(window, ns);
+
+(function(window, ns) {
+    'use strict';      // jshint ignore:line
+
+    var p;
+    function Ease() {
+        this.regExpCubicBezier = /cubic-bezier\s*\(\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*\)/;
+    }
+
+    function cubicBezier(x1, y1, x2, y2) {
+        return function(t) {
+            var rp = 1 - t, rp3 = 3 * rp, p2 = t * t, p3 = p2 * t, a1 = rp3 * t * rp, a2 = rp3 * p2;
+            return a1 * y1 + a2 * y2 + p3;
+        };
+    }
+
+    function calcBounceOut(t) {
+        if (t < 1 / 2.75) {
+            return (7.5625 * t * t);
+        } else if (t < 2 / 2.75) {
+            return (7.5625 * (t -= 1.5 / 2.75) * t + 0.75);
+        } else if (t < 2.5 / 2.75) {
+            return (7.5625 * (t -= 2.25 / 2.75) * t + 0.9375);
+        } else {
+            return (7.5625 * (t -= 2.625 / 2.75) * t + 0.984375);
+        }
+    }
+
+    p = Ease.prototype;
+    p.ease = cubicBezier(0.25, 0.1, 0.25, 1);
+
+    p.easeOut = cubicBezier(0, 0, 0.58, 1);
+
+    p.easeInOut = cubicBezier(0.42, 0, 0.58, 1);
+
+    p.easeIn = cubicBezier(0.42, 0, 1, 1);
+
+    p.sineIn = cubicBezier(0.47, 0, 0.745, 0.715);
+
+    p.sineOut = cubicBezier(0.39, 0.575, 0.565, 1);
+
+    p.sineInOut = cubicBezier(0.445, 0.05, 0.55, 0.95);
+
+    p.expoIn = cubicBezier(0.95, 0.05, 0.795, 0.035);
+
+    p.expoOut = cubicBezier(0.19, 1, 0.22, 1);
+
+    p.expoInOut = cubicBezier(1, 0, 0, 1);
+
+    p.circIn = cubicBezier(0.6, 0.04, 0.98, 0.335);
+
+    p.circOut = cubicBezier(0.075, 0.82, 0.165, 1);
+
+    p.circInOut = cubicBezier(0.785, 0.135, 0.15, 0.86);
+
+    p.backIn = cubicBezier(0.6, -0.28, 0.735, 0.045);
+
+    p.backOut = cubicBezier(0.175, 0.885, 0.32, 1.275);
+
+    p.backInOut = cubicBezier(0.68, -0.55, 0.265, 1.55);
+
+    p.zoomInDown = cubicBezier(0.55, 0.055, 0.675, 0.19);
+
+    p.bounce1 = cubicBezier(0.215, 0.610, 0.355, 1.000);
+    p.bounce2 = cubicBezier(0.755, 0.050, 0.855, 0.060);
+
+    // http://gizma.com/easing/
+    p.linear = function(t) {
+        return t;
+    };
+
+    p.cubicIn = function(t) {
+        return t * t * t;
+    };
+
+    p.cubicOut = function(t) {
+        return (--t) * t * t + 1;
+    };
+
+    p.cubicInOut = function(t) {
+        return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
+    };
+
+    p.quadIn = function(t) {
+        return t * t;
+    };
+
+    p.quadOut = function(t) {
+        return t * (2 - t);
+    };
+
+    p.quadInOut = function(t) {
+        return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
+    };
+
+    p.quartIn = function(t) {
+        return t * t * t * t;
+    };
+
+    p.quartOut = function(t) {
+        return  1 - (--t) * t * t * t;
+    };
+
+    p.quartInOut = function(t) {
+        return t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;
+    };
+
+    p.quintIn = function(t) {
+        return  t * t * t * t * t;
+    };
+
+    p.quintOut = function(t) {
+        return  1 + (--t) * t * t * t * t;
+    };
+
+    p.quintInOut = function(t) {
+        return  t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t;
+    };
+
+    p.bounceOut = function(t) {
+        return calcBounceOut(t);
+    };
+
+    p.bounceIn = function(t) {
+        return 1 - Ease.prototype.bounceOut(1 - t);
+    };
+
+    p.bounceInOut = function(t) {
+        if (t < 0.5) {
+            return Ease.prototype.bounceIn(t * 2) * 0.5;
+        }
+        return Ease.prototype.bounceOut(t * 2 - 1) * 0.5 + 0.5;
+    };
+
+    var pi2 = Math.PI * 2;
+    var defaultS = 0.3 / pi2 * Math.asin(1);
+
+    p.elasticIn = function(t) {
+        if (t === 0 || t === 1) {
+            return t;
+        }
+        return -(Math.pow(2, 10 * (t -= 1)) * Math.sin((t - defaultS) * pi2 / 0.3));
+    };
+
+    p.elasticOut = function(t) {
+        if (t === 0 || t === 1) {
+            return t;
+        }
+        return (Math.pow(2, -10 * t) * Math.sin((t - defaultS) * pi2 / 0.3) + 1);
+    };
+
+    p.elasticInOut = function(t) {
+        if ((t *= 2) < 1) {
+            return -0.5 * (Math.pow(2, 10 * (t -= 1)) * Math.sin((t - defaultS) * pi2 / 0.3));
+        }
+        return Math.pow(2, -10 * (t -= 1)) * Math.sin((t - defaultS) * pi2 / 0.3) * 0.5 + 1;
+    };
+    /*
+     * Provides ease functions
+     */
+    ns.Ease = ns.base.singleTon(Ease);
+})(window, ns);
+/*
+ * # Tween Animator
+ *
+ * Provides Tween and animate javascript properties.
+ *
+ * @example
+ * var box = document.getElementById('box');
+ * var tween = new ns.Tween({width: 100, height:100}, {width: 200, height: 250}, {
+ *                          duration: 1000,
+ *                          onUpdate: function() {
+ *                              box.style.width = this.width + 'px';
+ *                              box.style.height = this.height + 'px';
+ *                          }
+ *                      });
+ * tween.play()
+ *
+ * @class ns.TweenAnimator
+ */
+(function(window, ns) {
+    'use strict';
+
+    var Ticker = ns.Ticker.getInstance(),
+        Ease = ns.Ease.getInstance(),
+    // enum
+        STATE = {
+            STOP: 'stop',
+            PAUSE: 'pause',
+            RUN: 'running'
+        },
+        DIRECTION = {
+            FORWARD: true,
+            REVERSE: false
+        };
+
+    var createTweens = function() {
+        var idx = 0,
+            length = 0,
+            tweens = [];
+
+        return {
+            add: function(tween) {
+                tweens[length] = tween;
+                length++;
+            },
+
+            next: function() {
+
+                if (idx < length) {
+                    idx++;
+                    return tweens[idx - 1];
+                } else {
+                    return false;
+                }
+            },
+
+            cur: function() {
+                return idx;
+            },
+
+            rewind: function() {
+                idx = 0;
+            },
+
+            get: function(i) {
+                return (i === undefined ? tweens : tweens[i]);
+            },
+
+            length: function() {
+                return length;
+            },
+
+            hasNext: function() {
+                return idx < length;
+            },
+
+            clear: function() {
+                if (length !== 0 && idx <= length) {
+                    tweens.splice(0, idx)
+                }
+                idx = 0;
+                length = tweens.length;
+            },
+
+            allClear: function() {
+                tweens = [];
+                idx = length = 0;
+            }
+
+        }
+    };
+
+    var createEvent = function() {
+        var listeners = [],
+            length = 0;
+
+        return {
+            on: function(f) {
+                listeners[length] = f;
+                length++;
+            },
+
+            onFront: function(f) {
+                listeners.unshift(f);
+                length++;
+            },
+
+            emit: function() {
+                for (var i = 0; i < length; i++) {
+                    listeners[i].apply(null, arguments);
+                }
+            },
+
+            remove: function(f) {
+                for (var i = 0; i < length; i++) {
+                    if (listeners[i] === f) {
+                        listeners[i].splice(i, 1);
+                        length--;
+                    }
+                }
+            },
+
+            getLength: function() {
+                return length;
+            },
+
+            removeAll: function() {
+                listeners = [];
+                length = 0;
+            }
+        }
+    };
+
+    var TweenAnimator = ns.base.Class.extend({
+        _init: function(fromTo, option) {
+
+            this.tweenQueue = createTweens();
+            this.tweenInfo = null;
+
+            // state
+            this._direction = DIRECTION.FORWARD;
+            this._state = STATE.STOP;
+            this._isTick = false;
+            this.isTweenInfo = false;
+
+            fromTo && this.add(fromTo, option);
+
+            // time value
+            this._startTime = this._lastTime = this._playTime = this._previousTime = 0;
+            this._totalTime = this._duration + this._delay;
+            //this._progress = 0;
+
+            // check to change direction
+            this._changedDirection = false;
+
+            // tween queue cache
+            this._isCache = false;  // don't save tween object
+        },
+
+        /**
+         * Called by Ticker every frame
+         * @method tick
+         * @param {number} tick time
+         * @member ns.TweenAnimator
+         * @private
+         */
+        tick: function(delta) {
+
+            if (this._state === STATE.RUN) {
+                var now = delta,
+                    runTime = now - this._playTime;
+
+                this._previousTime = now;
+
+                if (runTime < 0) {
+                    return;
+                } else if (runTime <= this._duration) {
+                    this.tweenInfo.progress = runTime / (this._duration || 1);
+
+                    this._update();
+                } else {
+
+                    if (this.tweenInfo.progress !== 1) {
+                        this.tweenInfo.progress = 1;
+                        this._update();
+                    }
+                    if (now >= this._lastTime) {
+                        this._complete();
+                    }
+                }
+            }
+        },
+
+        /**
+         * Start tween animation
+         * @method play
+         * @member ns.TweenAnimator
+         * @public
+         */
+        play: function() {
+            if (this._state === STATE.RUN) {
+                return;
+            }
+
+            if (this._state === STATE.PAUSE) {
+                if (this._direction !== DIRECTION.FORWARD) {
+                    this._direction = DIRECTION.FORWARD;
+                    this._changedDirection = true;
+                }
+                this.resume();
+
+            } else {
+                this._direction = DIRECTION.FORWARD;
+                this._play();
+            }
+        },
+
+        /**
+         * Start tween animation to the reverse direction.
+         * @method reverse
+         * @member ns.TweenAnimator
+         * @public
+         */
+        reverse: function() {
+            if (this._state === STATE.RUN) {
+                return;
+            }
+
+            if (this._state === STATE.PAUSE) {
+                if (this._direction !== DIRECTION.REVERSE) {
+                    this._direction = DIRECTION.REVERSE;
+                    this._changedDirection = true;
+                }
+                this.resume();
+
+            } else {
+                this._direction = DIRECTION.REVERSE;
+                this._play();
+            }
+        },
+
+        /**
+         * Stop tween animation.
+         * @method stop
+         * @member ns.TweenAnimator
+         * @public
+         */
+        stop: function() {
+            if (this._state !== STATE.STOP) {
+                this._stopTween();
+                this.tweenQueue.allClear();
+                // TODO : call complete callback?
+            }
+        },
+
+        /**
+         * Pause tween animation.
+         * @method pause
+         * @member ns.TweenAnimator
+         * @public
+         */
+        pause: function() {
+            if (this._state === STATE.RUN) {
+                this._state = STATE.PAUSE;
+            }
+
+        },
+
+        /**
+         * Resume tween animation if it is paused.
+         * @method resume
+         * @param {string} direction
+         * @member ns.TweenAnimator
+         * @public
+         */
+        resume: function(direction) {
+            var cur = ns.getTime();
+
+            if (this._state === STATE.PAUSE) {
+
+                if (this._changedDirection || (direction !== undefined && direction !== this._direction)) {
+                    if (direction !== undefined) {
+                        this._direction = direction;
+                    }
+                    this._lastTime = cur + this._previousTime - this._playTime;
+                    this._playTime = this._lastTime - this._duration;
+                    this._startTime = this._playTime - this._delay;
+
+                    this._changedDirection = false;
+                } else {
+                    var elapsedTime = cur - this._previousTime;
+                    this._startTime += elapsedTime;
+                    this._playTime += elapsedTime;
+                    this._lastTime += elapsedTime;
+                }
+
+                this._state = STATE.RUN;
+            }
+
+        },
+
+        /**
+         * Jump to a specific time
+         * @method seek
+         * @param {number} specific time
+         * @member ns.TweenAnimator
+         * @public
+         */
+        seek: function(n) {
+            var seekTime = n * this._totalTime - this._delay;
+            if (seekTime >= 0) {
+                this._update(seekTime / this._duration);
+            }
+        },
+
+        /**
+         * Get value of seek time
+         * @method getSeek
+         * @param {number} seek time
+         * @return {number} value
+         * @member ns.TweenAnimator
+         * @private
+         */
+        getSeek: function(p, type) {
+            var i, name, l, p,
+                n = this.tweenInfo.name,
+                t = this.tweenInfo.to,
+                f = this.tweenInfo.from;
+
+            if (type) {
+                p = p * this._totalTime - this._delay
+            }
+
+            for (i = 0; name = n[i]; i++) {
+
+                if (this.cur[name] && (l = this.cur[name].length)) {
+                    (this.cur[name] === undefined) && (this.cur[name] = []);
+                    this._calculateTween(this.cur[name], t[name], f[name], p);
+
+                } else {
+                    this.cur[name] = (t[name] - f[name]) * this._ease(p) + f[name];
+                }
+
+            }
+
+            return this.cur;
+        },
+
+        /**
+         * Set start time of tween
+         * @method setStartTime
+         * @param {number} start time
+         * @member ns.TweenAnimator
+         * @private
+         */
+        setStartTime: function(time) {
+            this._startTime = time;
+            //this._playTime = this._startTime + (this._direction ? this._delay : 0);
+            //this._lastTime = this._playTime + this._duration + (this._direction ? 0 : this._delay);
+        },
+
+        /**
+         * Replay tween animation
+         * @method replay
+         * @member ns.TweenAnimator
+         * @private
+         */
+        replay: function() {
+            this._update(0);
+            this._start();
+        },
+
+        /**
+         * Set duration of tween
+         * @method duration
+         * @param {number}
+         * @member ns.TweenAnimator
+         * @private
+         */
+        duration: function(n) {
+            this._duration = ns.base.isNumber(n) ? n : 1000;
+        },
+
+        /**
+         * Set delay of tween
+         * @method delay
+         * @param {number}
+         * @member ns.TweenAnimator
+         * @private
+         */
+        delay: function(n) {
+            this._delay = ns.base.isNumber(n) ? n : 0;
+        },
+
+        /**
+         * Set ease of tween
+         * @method ease
+         * @param {string}
+         * @member ns.TweenAnimator
+         * @private
+         */
+        ease: function(f) {
+            this._ease = ns.base.isFunction(Ease[f]) ? Ease[f] : Ease.linear;
+        },
+
+        /**
+         * Set loop of tween
+         * @method loop
+         * @param {number}
+         * @member ns.TweenAnimator
+         * @private
+         */
+        loop: function(n) {
+            this._loop = ns.base.isNumber(n) ? n : 1;
+        },
+
+        /**
+         * Add tween object
+         * @method add
+         * @param {object} fromTo from and to value object
+         * @param {object} option value object including duration, delay, ease ans so on.
+         * @member ns.TweenAnimator
+         * @public
+         */
+        add: function(fromTo, option) {
+            var tween;
+
+            if (option === undefined) {
+                tween = fromTo;
+                tween.startCallback = createEvent();
+                tween.completeCallback = createEvent();
+                tween.progress = 0;
+            } else {
+                tween = {
+                    fromTo: {},
+                    name: [],
+                    progress: 0,
+                    startCallback: createEvent(),
+                    completeCallback: createEvent()
+                };
+
+                tween.option = option;
+            }
+
+            tween.option.onStart && tween.startCallback.on(tween.option.onStart);
+            tween.option.onComplete && tween.completeCallback.on(tween.option.onComplete);
+
+            this.tweenQueue.add(tween);
+
+            if (this.tweenQueue.length() === 1) {
+                this.tweenQueue.next();
+                this.initTween(tween);
+                this.isTweenInfo = true;
+            }
+
+            return tween;
+        },
+
+        /**
+         * Shift to next tween object.
+         * @method nextTween
+         * @return {object | boolean} tween object or false if not.
+         * @member ns.TweenAnimator
+         * @private
+         */
+
+        setRender: function(f) {
+            this.render = f;
+        },
+
+        setUpdateTarget: function(target) {
+            this.cur = target;
+        },
+
+        getState: function() {
+            return this._state;
+        },
+
+        getCurrentTweenInfo: function() {
+            return this.tweenInfo;
+        },
+
+        nextTweenInfo: function() {
+            return this.tweenQueue.next();
+        },
+
+        getLastTweenInfo: function() {
+            return this.tweenQueue.get(this.tweenQueue.length() - 1);
+        },
+
+        getFirstTweenInfo: function() {
+            return this.tweenQueue.get(0);
+        },
+        /**
+         * Initialize cur tween object.
+         * @method initTween
+         * @param {object} tweenInfo object
+         * @member ns.TweenAnimator
+         * @private
+         */
+        initTween: function(tweenInfo) {
+            var option = tweenInfo.option;
+
+            this.tweenInfo = tweenInfo;
+            this.cur = (this.cur !== undefined) ? this.cur : (option._cur !== undefined) ? option._cur : {};
+
+            this.option = option;
+
+            // user event
+            this._onUpdate = option.onUpdate;  // only one update callback exists because it affect performance.
+
+            // tween option value
+            if (ns.base.isObject(option)) {
+                this.duration(option.duration);
+                this.ease(option.ease);
+                this.delay(option.delay);
+                this.loop(option.loop);
+
+                this._reverseDelay = option.reverseDelay || 0;
+
+            } else {
+                this._duration = 1000;
+                this._delay = 0;
+                this._loop = 1;
+                this._ease = Ease.linear;
+                this._reverseDelay = 0;
+            }
+            this._loopCnt = this._loop;
+
+        },
+
+        tweenQueueCache: function(flag) {
+            (typeof flag === 'boolean') && (this._isCache = flag);
+        },
+
+        /**
+         * If state is stop, start tween. or If it is pause, resume tween.
+         * @method _play
+         * @member ns.TweenAnimator
+         * @private
+         */
+        _play: function() {
+            if (this._state === STATE.PAUSE) {
+                this.resume();
+            } else if (this._state === STATE.STOP) {
+                this._start();
+            }
+        },
+
+        /**
+         * Calculate start, play and last time. And start tick.
+         * @method _start
+         * @member ns.TweenAnimator
+         * @private
+         */
+        _start: function() {
+            this._state = STATE.RUN;
+
+            this._startTime = this._startTime || ns.getTime();
+            this._playTime = this._startTime + (this._direction ? this._delay : 0);
+            this._lastTime = this._playTime + this._duration + (this._direction ? 0 : this._delay) + this._reverseDelay;
+
+            //this._onStart && this._onStart();
+            this.tweenInfo.startCallback.emit();
+
+            if (!this._isTick) {
+                Ticker.__on(this);
+                this._isTick = true;
+            }
+        },
+
+        /**
+         * Update tween value every frame.
+         * @method _update
+         * @param {number} progress
+         * @member ns.TweenAnimator
+         * @private
+         */
+        _update: function(e) {
+            var i, name, l,
+                n = this.tweenInfo.name,
+                ft = this.tweenInfo.fromTo;
+
+            this.tweenInfo.progress = (e !== undefined) ?
+                e : (this._direction === DIRECTION.REVERSE ? 1 - this.tweenInfo.progress : this.tweenInfo.progress);
+
+            // render
+            for (i = 0; name = n[i]; i++) {
+                if (ft[name][0] && (l = ft[name][0].length)) {
+                    (this.cur[name] === undefined) && (this.cur[name] = []);
+                    this._calculateTween(this.cur[name], ft[name][0], ft[name][1]);
+
+                } else {
+                    this.cur[name] = (ft[name][1] - ft[name][0]) * this._ease(this.tweenInfo.progress) + ft[name][0];
+                }
+            }
+
+            this.render && this.render.call(this.cur, this.tweenInfo);
+            this._onUpdate && this._onUpdate.call(this.cur, this.tweenInfo);
+        },
+
+        /**
+         * Calculate tween value.
+         * @method _calculateTween
+         * @param {number} current value
+         * @param {number} from value
+         * @param {number} to value
+         * @param {number} progress
+         * @member ns.TweenAnimator
+         * @private
+         */
+        _calculateTween: function(c, f, t, p) {
+            var i, l;
+            (p === undefined) && (p = this.tweenInfo.progress);
+
+            for (i = 0, l = t.length; i < l; i++) {
+                if (typeof t[i] === 'number') {
+                    c[i] = (t[i] - f[i]) * this._ease(p) + f[i];
+                } else if (typeof t[i] === 'string') {
+                    c[i] = t[i];
+                } else {
+                    (c[i] === undefined) && (c[i] = []);
+                    this._calculateTween(c[i], f[i], t[i]);
+                }
+            }
+        },
+
+        /**
+         * If tween completed, call this function.
+         * @method _complete
+         * @member ns.TweenAnimator
+         * @private
+         */
+        _complete: function() {
+            var nextTween;
+            this.setStartTime(null);
+            this.isTweenInfo = false;
+            this.tweenInfo.completeCallback.emit();
+
+            // loop check
+            if (--this._loopCnt > 0) {
+                this.replay();
+            } else {
+                // search next tweenInfo
+                if (!this.isTweenInfo && (nextTween = this.tweenQueue.next())) {
+                    this.initTween(nextTween);
+
+                    if (!this._isCache) {
+                        this.tweenQueue.clear();
+                    }
+
+                    this._start();
+                } else {
+                    if (this.isTweenInfo) {
+                        this._start();
+                    } else {
+                        // finish tween
+                        this._stopTween();
+
+                        if (this.option._stackTweensFlag) {
+                            this.tweenQueue.rewind();
+                            nextTween = this.tweenQueue.next();
+                            this.initTween(nextTween);
+                        } else {
+                            this.tweenQueue.allClear();
+                        }
+                    }
+
+                }
+            }
+
+        },
+
+        /**
+         * Stop tween object and stop tick.
+         * @method _stopTween
+         * @member ns.TweenAnimator
+         * @private
+         */
+        _stopTween: function() {
+            this._state = STATE.STOP;
+            this._startTime = null;
+            Ticker.__off(this);
+            this._isTick = false;
+        }
+
+    });
+
+    ns.TweenAnimator = ns.Tween = TweenAnimator;
+})(window, ns);
+(function(window, ns, base) {
+    'use strict';
+
+    var Transform = ns.base.Class.extend({
+        _init: function() {
+            this.init();
+        },
+
+        /**
+         * Initialize transform values
+         * @method init
+         * @member ns.Transform.init
+         * @private
+         */
+        init: function() {
+            this.translateX = 0;
+            this.translateY = 0;
+            this.translateZ = 0;
+
+            this.rotateX = 0;
+            this.rotateY = 0;
+            this.rotateZ = 0;
+
+            this.skewX = 0;
+            this.skewY = 0;
+
+            this.scaleX = 1;
+            this.scaleY = 1;
+        },
+
+        /**
+         * Copy transform values
+         * @method copy
+         * @param {object} source transform value
+         * @member ns.Transform.copy
+         * @private
+         */
+        copy: function(t) {
+            this.translateX = t.translateX;
+            this.translateY = t.translateY;
+            this.translateZ = t.translateZ;
+
+            this.rotateX = t.rotateX;
+            this.rotateY = t.rotateY;
+            this.rotateZ = t.rotateZ;
+
+            this.skewX = t.skewX;
+            this.skewY = t.skewY;
+
+            this.scaleX = t.scaleX;
+            this.scaleY = t.scaleY;
+        },
+
+        /**
+         * Set transform array values
+         * @method set
+         * @param {array} source transform array value
+         * @member ns.Transform.set
+         * @private
+         */
+        set: function(t) {
+            if(t instanceof Array) {
+                // translate, rotate, scale, skew
+                this.translateX = base.isNumber(t[0]) ? t[0] : 0;
+                this.translateY = base.isNumber(t[1]) ? t[1] : 0;
+                this.translateZ = base.isNumber(t[2]) ? t[2] : 0;
+
+                this.rotateX = base.isNumber(t[3]) ? t[3] : 0;
+                this.rotateY = base.isNumber(t[4]) ? t[4] : 0;
+                this.rotateZ = base.isNumber(t[5]) ? t[5] : 0;
+
+                this.scaleX = base.isNumber(t[6]) ? t[6] : 1;
+                this.scaleY = base.isNumber(t[7]) ? t[7] : 1;
+
+                this.skewX = base.isNumber(t[8]) ? t[8] : 0;
+                this.skewY = base.isNumber(t[9]) ? t[9] : 0;
+            }
+        }
+    });
+
+    /*
+     * Sets or Initialize webkitTransform property
+     */
+    ns.Transform = Transform;
+
+})(window, ns, ns.base);
+
+(function(window, ns, base) {
+    'use strict';
+
+    var colorTable = {
+        aqua: new Uint8Array([0, 255, 255]),
+        lime: new Uint8Array([0, 255, 0]),
+        silver: new Uint8Array([192, 192, 192]),
+        black: new Uint8Array([0, 0, 0]),
+        maroon: new Uint8Array([128, 0, 0]),
+        teal: new Uint8Array([0, 128, 128]),
+        blue: new Uint8Array([0, 0, 255]),
+        navy: new Uint8Array([0, 0, 128]),
+        white: new Uint8Array([255, 255, 255]),
+        fuchsia: new Uint8Array([255, 0, 255]),
+        olive: new Uint8Array([128, 128, 0]),
+        yellow: new Uint8Array([255, 255, 0]),
+        orange: new Uint8Array([255, 165, 0]),
+        gray: new Uint8Array([128, 128, 128]),
+        purple: new Uint8Array([128, 0, 128]),
+        green: new Uint8Array([0, 128, 0]),
+        red: new Uint8Array([255, 0, 0]),
+        pink: new Uint8Array([255, 192, 203]),
+        cyan: new Uint8Array([0, 255, 255]),
+        transparent: new Uint8Array([255, 255, 255, 0])
+    };
+
+    var CSSPropertyParser = base.Class.extend({
+
+        _init: function() {
+            var self = this;
+
+            // px & unit
+            var pxType = ['borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth',
+                'marginTop', 'marginRight', 'marginBottom', 'marginLeft',
+                'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',
+                'width', 'height', 'top', 'left',
+                'clipTop', 'clipBottom', 'clipRight', 'clipLeft',
+                'fontSize', 'lineHeight'];
+            pxType.forEach(function(type) {
+                self[type] = self._unit.bind(self);
+            });
+
+            var backgroundType = ['backgroundPosition', 'backgroundSize'];
+            backgroundType.forEach(function(type) {
+                self[type] = self._arrayUnit.bind(self);
+
+            });
+
+            // border
+            var borderType = ['border', 'borderTop', 'borderRight', 'borderLeft', 'borderBottom'];
+            borderType.forEach(function(type) {
+                self[type] = function _border(str) {
+                    var result = {}, temp;
+
+                    temp = self._blank(str);
+
+                    result[type + 'Width'] = temp[0];
+                    result[type + 'Style'] = temp[1] === 'none' ? 'solid' : temp[1];   // TODO: 유효성 체크
+                    result[type + 'Color'] = temp[2];
+
+                    return result;
+                };
+            });
+
+            // color
+            var colorType = ['backgroundColor', 'color',
+                'borderColor', 'borderTopColor', 'borderRightColor', 'borderLeftColor', 'borderBottomColor'];
+
+            colorType.forEach(function(type) {
+                self[type] = self._color;
+            });
+
+            //margin & padding
+            var blankType = ['margin', 'padding'];
+            blankType.forEach(function(type) {
+                self[type] = function _blank(str) {
+                    var temp = self._blank(str), result = {};
+
+                    if (temp.length === 4) {
+                        result[type + 'Top'] = temp[0];
+                        result[type + 'Right'] = temp[1];
+                        result[type + 'Bottom'] = temp[2];
+                        result[type + 'Left'] = temp[3];
+                    } else if (temp.length === 3) {
+                        result[type + 'Top'] = temp[0];
+                        result[type + 'Right'] = temp[1];
+                        result[type + 'Bottom'] = temp[2];
+                        result[type + 'Left'] = temp[1];
+                    } else if (temp.length === 2) {
+                        result[type + 'Top'] = temp[0];
+                        result[type + 'Right'] = temp[1];
+                        result[type + 'Bottom'] = temp[0];
+                        result[type + 'Left'] = temp[1];
+                    } else if (temp.length === 1) {
+                        result[type + 'Top'] = temp[0];
+                        result[type + 'Right'] = temp[0];
+                        result[type + 'Bottom'] = temp[0];
+                        result[type + 'Left'] = temp[0];
+                    }
+
+                    return result;
+                }
+            });
+
+            //var unitWithString = ['lineHeight', 'fontSize'];
+            //unitWithString.forEach(function(type){
+            //    self[type] = function _unitString(str){
+            //        var result;
+            //
+            //        result = self._unit(str);
+            //
+            //        if(isNaN(result.value)) {
+            //            result = str;
+            //        }
+            //
+            //        return result;
+            //    }
+            //});
+
+            var shadowType = ['boxShadow', 'textShadow'];
+            shadowType.forEach(function(type) {
+                self[type] = function _shadowString(str) {
+
+                    var i, j, length, string, result = [], color, rgbArray = [], len, rgbIdx = 0,
+                        rgbExp = /rgb\([0-9]+[\, |\s]+[0-9]+[\, |\s]+[0-9]+\)/g, shadowLength;
+
+                    rgbArray = str.match(rgbExp) || [];
+                    str = str.replace(rgbExp, 'rgb');
+
+                    str = str.split(',');
+
+                    for (i = 0, length = str.length; i < length; i++) {
+
+
+                        if (str[i].match('rgb') && rgbArray[rgbIdx]) {
+                            str[i] = str[i].replace('rgb', rgbArray[rgbIdx]);
+                            rgbIdx++;
+                        }
+
+
+                        str[i] = self._blank(str[i]);
+                        shadowLength = str[i].length - 1;
+                        // search color
+
+                        if ((color = self._color(str[i][0]))) {
+                            str[i].splice(0, 1);
+                            str[i].push(color);
+                        } else {
+                            color = self._color(str[i][shadowLength]);
+                        }
+
+                        for (j = 0; j < shadowLength; j++) {
+                            str[i][j] = self._unit(str[i][j]);
+                        }
+                        str[i][j] = color;
+                    }
+
+
+                    return str;
+                }
+            });
+
+        },
+
+        opacity: function(v) {
+            return parseFloat(v);
+        },
+
+        clip: function(v) {
+            var text = v.replace(/\(|\)|,/g, ' ').trim().split(/\s+/g);
+
+            var result = [];
+            result[0] = text[0];
+
+            for (var i = 1; i <= 4; i++) {
+                result[i] = this._unit(text[i]);
+            }
+            return result;
+        },
+
+        webkitClipPath: function(v) {
+            var result = [], i, len,
+                text = v.replace(/\(|\)|,/g, ' ').trim().split(/\s+/g);
+
+            result.push(text[0]);
+            for (i = 1, len = text.length; i < len; i++) {
+                result.push(this._unit(text[i]));
+            }
+
+            return result;
+        },
+
+        backgroundImage: function(v) {
+            return v.replace(/url\(|\)$/ig, "");
+        },
+
+        _arrayUnit: function(v) {
+            var i, l, result = v.trim().split(' ');
+
+            for (i = 0, l = result.length; i < l; i++) {
+                result[i] = this._unit(result[i]);
+            }
+            return result;
+        },
+
+        _unit: function(str) {
+            if (typeof str === 'string') {
+                return {
+                    number: this._getFloat(str),
+                    unit: (this._getChar(str) || 'px')
+                }
+            } else {
+                return {
+                    number: str,
+                    unit: 'px'
+                };
+            }
+        },
+
+        _color: function(colorValue) {
+            //console.log(colorValue);
+            var first, second, third, rgb, length, i, string, result;
+            if (colorValue === undefined || colorValue === null) {
+                console.log('invalid color');
+                return false;
+            }
+
+            if (colorTable[colorValue]) {                //for string color value such as 'red'
+                result = colorTable[colorValue];
+            } else if (colorValue instanceof Array || colorValue instanceof Uint8Array) {
+                result = new Uint8Array(colorValue);
+            } else {
+                string = colorValue.toLowerCase();
+                string = string.trim();
+                if (string.charAt(0) === 'r' && string.charAt(1) === 'g' && string.charAt(2) === 'b') {
+                    if (string.charAt(3) === 'a') {
+                        rgb = string.replace(/rgba\(/g, '').replace(/\)/g, '').replace(/(\s*)/g, '').replace(/\,/g, ' ').split(' ');
+                        for (i = 0, length = rgb.length - 1; i < length; i++) {
+                            rgb[i] = parseInt(rgb[i]);
+                        }
+                        rgb[length] = parseFloat(rgb[length]);
+                    } else {
+                        rgb = string.replace(/rgb\(/g, '').replace(/\)/g, '').replace(/(\s*)/g, '').replace(/\,/g, ' ').split(' ');
+                        for (i = 0, length = rgb.length; i < length; i++) {
+                            rgb[i] = parseInt(rgb[i]);
+                        }
+                    }
+                    result = new Uint8Array(rgb);
+
+                } else if (string.charAt(0) === '#') {        //for '#XXX' or '#XXXXXX'
+                    if (string.length === 4) {
+                        first = string.charAt(1);
+                        second = string.charAt(2);
+                        third = string.charAt(3);
+                        string = "#" + first + first + second + second + third + third;
+                    }
+
+                    string = parseInt(string.substr(1), 16);  // remove '#'
+                    result = new Uint8Array(3);
+                    result.setValue(string >> 16, (string >> 8) & 255, string & 255);
+                } else {
+                    return false;
+//                    console.log(colorValue);
+                }
+            }
+            return result;
+        },
+
+        _getChar: function(arg) {
+            var charArr = arg.match(/[^0-9.-]/g);
+            var string = '';
+
+            if (charArr !== null) {
+                string = charArr.join('');
+            }
+
+            string.replace(/\, /g, '');
+
+            return string;
+        },
+
+        _getNum: function(arg) {
+            return parseInt(arg.match(/^[-]?\d+/g), 10);
+        },
+
+        _getFloat: function(arg) {
+            return parseFloat(arg.match(/^[+-]?\d*(\.?\d*)/g));
+        },
+
+        _blank: function(str) {
+            return str.trim().replace(/\, /g, ',').split(' ');
+        }
+    });
+
+    /*
+     * Parses css properties.
+     */
+    ns.CSSPropertyParser = base.singleTon(CSSPropertyParser);
+
+})(window, ns, ns.base);
+(function(window, ns, base) {
+    'use strict';
+
+    var CssStringCreator = base.Class.extend({
+
+        _init: function() {
+            this.createColor();
+            this.createBorderStyle();
+            this.createBlankFunction();
+            this.createUnit();
+            //this.createUnitWithString();
+            this.createShadow();
+        },
+
+
+        opacity: function(value) {
+            return value.opacity;
+        },
+
+        WebkitTransform: function(value) {
+            var string = '';
+            string += value.perspective ? ('perspective(' + value.perspective + 'px) ') : '';
+            string += 'translate3d(' + value.translateX + 'px, ' + value.translateY + 'px, ' + value.translateZ + 'px) ';
+
+            string += value.rotateX ? ('rotateX(' + value.rotateX + 'deg) ') : '';
+            string += value.rotateY ? ('rotateY(' + value.rotateY + 'deg) ') : '';
+            string += value.rotateZ ? ('rotateZ(' + value.rotateZ + 'deg) ') : '';
+
+            string += (value.scaleX !== 1) ? ('scaleX(' + value.scaleX + ') ') : '';
+            string += (value.scaleY !== 1) ? ('scaleY(' + value.scaleY + ') ') : '';
+
+            string += value.skewX ? ('skewX(' + value.skewX + 'deg) ') : '';
+            string += value.skewY ? ('skewY(' + value.skewY + 'deg) ') : '';
+
+            return string;
+        },
+
+        createUnit: function() {
+            var self = this,
+                type = ['width', 'height', 'top', 'left'],
+                backgroundType = ['backgroundPosition', 'backgroundSize'];
+
+            function _unit(v, u) {
+                if (u[this] === 'px') {
+                    return Math.round(v[this]) + u[this];
+                }
+                return v[this] + u[this];
+            }
+
+            type.forEach(function(f) {
+                self[f] = _unit.bind(f)
+            });
+
+            backgroundType.forEach(function(f) {
+                self[f] = _background.bind(f)
+            });
+
+            function _background(v, u) {
+                return v[this][0] + u[this][0] + ' ' + v[this][1] + u[this][1];
+            }
+        },
+
+        createColor: function() {
+            var self = this;
+            var type = ['borderColor', 'borderTopColor', 'borderRightColor', 'borderLeftColor', 'borderBottomColor',
+                'backgroundColor', 'color'];
+            type.forEach(function(f) {
+                self[f] = self._rgbColor(f);
+            });
+        },
+
+        createBorderStyle: function() {
+            var self = this;
+
+            var borderType = ['border', 'borderTop', 'borderRight', 'borderLeft', 'borderBottom'];
+            var borderWidthType = ['borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderLeftWidth', 'borderBottomWidth'];
+            var borderStyleType = ['borderStyle', 'borderTopStyle', 'borderRightStyle', 'borderLeftStyle', 'borderBottomStyle'];
+
+            function _border(v, u) {
+
+                var width = this + 'Width',
+                    color = this + 'Color',
+                    style = this + 'Style';
+                //console.log(v[color]);
+                return v[width] + u[width] + ' ' + u[style] + ' rgb(' +
+                    v[color][0] + ', ' + v[color][1] + ', ' + v[color][2] + ')';
+            }
+
+            function _borderWidth(v, u) {
+                return v[this].toFixed(2) + u[this];
+            }
+
+            borderType.forEach(function(f) {
+                self[f] = _border.bind(f)
+            });
+
+            borderStyleType.forEach(function(f) {
+                self[f] = self._direct(f);
+            });
+
+            borderWidthType.forEach(function(f) {
+                self[f] = _borderWidth.bind(f)
+            });
+        },
+
+        createBlankFunction: function() {
+            var self = this;
+            var blank = ['margin', 'padding'];
+            var blankType = ['marginTop', 'marginRight', 'marginBottom', 'marginLeft',
+                'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft',
+                'lineHeight', 'fontSize'];
+
+            blank.forEach(function(f) {
+                self[f] = _blank.bind(f)
+            });
+
+            function _blank(v, u) {
+                var top = this + 'Top',
+                    right = this + 'Right',
+                    bottom = this + 'Bottom',
+                    left = this + 'Left';
+//                console.log(v[top], u[top]);
+                return v[top] + u[top] + ' ' + v[right] + u[right] + ' ' + v[bottom] + u[bottom] + ' ' + v[left] + u[left];
+            }
+
+            blankType.forEach(function(f) {
+                self[f] = _blanktype.bind(f);
+            });
+
+            function _blanktype(v, u) {
+//                console.log(v[this], u[this]);
+                return v[this] + u[this];
+            }
+        },
+
+//        createUnitWithString: function(){
+//            var self = this,
+//                unitType = [];
+//
+//            unitType.forEach(function(f){
+//                self[f] = _unit.bind(f)
+//            });
+//
+//            function _unit(f) {
+//                return f[this][0] + f[this][1];
+//            }
+//        },
+
+        createShadow: function() {
+            var self = this,
+                shadowType = ['boxShadow', 'textShadow'];
+
+            shadowType.forEach(function(name) {
+                self[name] = function(v, u) {
+                    var value = v[name], unit = u[name], i, j, shadowLen, len, str = '';
+                    for (i = 0, shadowLen = value.length; i < shadowLen; i++) {
+
+                        (i !== 0) && (str += ', ');
+
+                        for (j = 0, len = value[i].length - 1; j < len; j++) {
+                            str += value[i][j] + unit[i][j] + ' ';
+                        }
+
+                        str += 'rgb(' + value[i][j][0] + ',' + value[i][j][1] + ',' + value[i][j][2] + ') ';
+
+                    }
+                    //console.log(str);
+                    return str;
+                }
+            });
+        },
+
+        //createShadow: function(){
+        //    var self = this,
+        //        shadowType = ['boxShadow', 'textShadow'];
+        //
+        //    shadowType.forEach(function(f){
+        //        self[f] = _shadow.bind(f);
+        //    });
+        //
+        //    function _shadow(v){
+        //        var result = '', i = 0, j = 0, length = 0, len = 0;
+        //        for(j = 0, length = v[this].length; j < length; j++){
+        //            for(i = 0, len = v[this][j].length; i < len; i++) {
+        //                if(v[this][j][i].length === 2) {
+        //                    if(v[this][j][i][1] !== '') {
+        //                        result += (v[this][j][i][0] + v[this][j][i][1] + ' ');
+        //                    }
+        //
+        //                } else if(v[this][j][i].length === 3){
+        //                    result += 'rgb(' + (v[this][j][i][0] + ',' + v[this][j][i][1] + ',' + v[this][j][i][2] + ')');
+        //                } else if(v[this][j][i] === 'inset') {
+        //                    result += ' inset';
+        //                }
+        //            }
+        //            if( (length-1) > j){
+        //                result += ', ';
+        //            }
+        //        }
+        //        return result;
+        //    }
+        //},
+
+
+        clip: function(v) {
+            return v.clip[0] + '(' + v.clip[1][0] + v.clip[1][1] + ' ' + v.clip[2][0] + v.clip[2][1] +
+                ' ' + v.clip[3][0] + v.clip[3][1] + ' ' + v.clip[4][0] + v.clip[4][1] + ')';
+
+        },
+
+//        clip: function(value, unit) {
+//            var v = value.clip,
+//                u = unit.clip;
+//
+//            return 'rect(' + v[0] + u[0]  + ' ' + v[1] + u[1] +
+//                ' ' + v[2] + u[2] + ' ' + v[3] + u[3] + ')';
+//
+//        },
+
+        webkitClipPath: function(value, unit) {
+            var v = value.webkitClipPath,
+                u = unit.webkitClipPath,
+                s = unit.webkitClipPathStyle,
+                i, l, style;
+
+            if (s === 'circle') {
+                // circle(0% at 50% 50%)
+                return u[0] + '(' + v[0] + u[1] + ' at ' + v[1] + u[2] + ' ' + v[2] + u[3] + ')';
+            } else if (s === 'polygon') {
+                // 'polygon(0 0, 0% 100%, 100% 0)'
+                style = s + '(';
+                for (i = 0, l = v.length; i < l; i += 2) {
+                    style += (v[i] + u[i] + ' ' + v[i + 1] + u[i + 1]);
+                    style += (i + 1 !== l - 1) ? ', ' : ')';
+                }
+                return style;
+            }
+        },
+
+        _direct: function(type) {
+            return function(v) {
+                return v[type];
+            }
+        },
+        _rgbColor: function(type) {
+            return function(v) {
+                //console.log(' rgb(' + v[type][0] + ', ' + v[type][1] + ', ' + v[type][2] + ')');
+                return 'rgb(' + v[type][0] + ', ' + v[type][1] + ', ' + v[type][2] + ')';
+            }
+        }
+    });
+
+    /*
+     * Creates string based on CSS properties
+     */
+    ns.CssStringCreator = base.singleTon(CssStringCreator);
+
+})(window, ns, ns.base);
+(function(window, ns, base) {
+    'use strict';
+
+    var CssParser = ns.CSSPropertyParser.getInstance();
+
+    var CssAnimationUtil = base.Class.extend({
+
+        _init: function() {
+
+            // width unit
+            var self = this, color,
+                widthUnit, heightUnit, background, marginPadding, border, shadow;
+
+            color = ['backgroundColor', 'color',
+                'borderColor', 'borderTopColor', 'borderRightColor', 'borderLeftColor', 'borderBottomColor'];
+
+            color.forEach(function(name) {
+                self[name] = function(animation) {
+                    self.settingCssAnimation(name, animation, '_colorType');
+                }
+            });
+
+            widthUnit = ['width', 'left', 'marginRight', 'marginLeft', 'paddingRight', 'paddingLeft',
+                'marginTop', 'marginBottom', 'paddingBottom', 'paddingTop',
+                'clipTop', 'clipBottom', 'clipRight', 'clipLeft',
+                'borderWidth', 'borderTopWidth', 'borderRightWidth', 'borderLeftWidth', 'borderBottomWidth',
+                'clipTop', 'clipBottom', 'clipRight', 'clipLeft'];
+            widthUnit.forEach(function(name) {
+                self[name] = function(animation) {
+                    self.settingCssAnimation(name, animation, '_unitType', 'width');
+                }
+            });
+
+            heightUnit = ['height', 'top'];
+            heightUnit.forEach(function(name) {
+                self[name] = function(animation) {
+                    self.settingCssAnimation(name, animation, '_unitType', 'height');
+                }
+            });
+
+            background = ['backgroundPosition', 'backgroundSize'];
+            background.forEach(function(name) {
+                self[name] = function(animation) {
+                    self.settingCssAnimation(name, animation, '_backgroundType');
+                }
+            });
+
+            marginPadding = ['margin', 'padding'];
+            marginPadding.forEach(function(name) {
+                self[name] = function(animation) {
+                    var from, to, i;
+
+                    if (animation.animationFromTo[name].length === 2) {
+                        from = CssParser[name](animation.animationFromTo[name][0]);
+                        to = CssParser[name](animation.animationFromTo[name][1]);
+
+                        for (i in to) {
+                            animation.animationFromTo[i] = [from[i], to[i]];
+                            self[i](animation);
+                        }
+
+                    } else {
+                        to = CssParser[name](animation.animationFromTo[name]);
+
+                        for (i in to) {
+                            animation.animationFromTo[i] = to[i];
+                            self[i](animation);
+                        }
+                    }
+                }
+            });
+
+            border = ['border', 'borderTop', 'borderRight', 'borderLeft', 'borderBottom'];
+            border.forEach(function(name) {
+                self[name] = function(animation) {
+                    var from, to;
+
+                    if (animation.animationFromTo[name].length === 2) {
+                        from = CssParser[name](animation.animationFromTo[name][0]);
+                        to = CssParser[name](animation.animationFromTo[name][1]);
+
+                        animation.animationFromTo[name + 'Width'] = [from[name + 'Width'], to[name + 'Width']];
+                        animation.animationFromTo[name + 'Color'] = [from[name + 'Color'], to[name + 'Color']];
+                    } else {
+                        to = CssParser[name](animation.animationFromTo[name]);
+
+                        animation.animationFromTo[name + 'Width'] = to[name + 'Width'];
+                        animation.animationFromTo[name + 'Color'] = to[name + 'Color'];
+                    }
+
+                    animation.unit[name + 'Style'] = to[name + 'Style'];
+
+                    self[name + 'Width'](animation);
+                    self[name + 'Color'](animation);
+                }
+            });
+
+            border = ['border', 'borderTop', 'borderRight', 'borderLeft', 'borderBottom'];
+            border.forEach(function(name) {
+                self[name] = function(animation) {
+                    var from, to;
+
+                    if (animation.animationFromTo[name].length === 2) {
+                        from = CssParser[name](animation.animationFromTo[name][0]);
+                        to = CssParser[name](animation.animationFromTo[name][1]);
+
+                        animation.animationFromTo[name + 'Width'] = [from[name + 'Width'], to[name + 'Width']];
+                        animation.animationFromTo[name + 'Color'] = [from[name + 'Color'], to[name + 'Color']];
+                    } else {
+                        to = CssParser[name](animation.animationFromTo[name]);
+
+                        animation.animationFromTo[name + 'Width'] = to[name + 'Width'];
+                        animation.animationFromTo[name + 'Color'] = to[name + 'Color'];
+                    }
+
+                    animation.unit[name + 'Style'] = to[name + 'Style'];
+
+                    self[name + 'Width'](animation);
+                    self[name + 'Color'](animation);
+                }
+            });
+
+            shadow = ['boxShadow', 'textShadow'];
+            shadow.forEach(function(name) {
+                self[name] = function(animation) {
+                    self.settingCssAnimation(name, animation, '_shadowType');
+                }
+            });
+
+            this.webkitClipPath = function(animation) {
+                this.settingCssAnimation('webkitClipPath', animation, '_webkitClipPathType');
+            };
+
+            this.fontSize = function(animation) {
+                this.settingCssAnimation('fontSize', animation, '_fontSizeType');
+            };
+
+            this.lineHeight = function(animation) {
+                this.settingCssAnimation('lineHeight', animation, '_unitType', 'lineHeight');
+            };
+
+            this.opacity = function(animation) {
+                this.settingCssAnimation('opacity', animation);
+            };
+
+            this.WebkitTransform = function(name, animation) {
+
+                var from, to, i, self = this;
+
+                if (typeof animation.animationFromTo[name] === 'object' && animation.animationFromTo[name].length === 2) {
+                    from = animation.animationFromTo[name][0];
+                    to = animation.animationFromTo[name][1];
+
+                } else {
+                    from = animation.target.cur[name];
+                    to = animation.animationFromTo[name];
+                }
+
+                if (name === 'translateX' || name === 'translateY' || name === 'translateZ') {
+                    (typeof from === 'string') && (from = this._getTranslateValue(name, animation, from));
+                    (typeof to === 'string') && (to = this._getTranslateValue(name, animation, to));
+                }
+
+                animation.fromTo[name] = [from, to];
+                animation.target.from[name] = to;
+                animation.name.push(name);
+            };
+        },
+
+        settingCssAnimation: function(name, animation, type, percentCriterion) {
+            var fromTo;
+
+            // 1. animation parser
+            fromTo = animation.fromTo[name] = [];
+
+            if (typeof animation.animationFromTo[name] === 'object' &&
+                animation.animationFromTo[name].length === 2) {
+                fromTo[0] = animation.animationFromTo[name][0];
+                fromTo[1] = animation.animationFromTo[name][1];
+            } else {
+                fromTo[0] = window.getComputedStyle(animation.target.dom)[name];
+                if (fromTo[0] === '' || fromTo[0] === 'auto' || fromTo[0] === 'none' || fromTo[0] === undefined) {
+                    fromTo[0] = this._exceptGetStyle(animation.target.dom, name);
+                }
+                fromTo[1] = animation.animationFromTo[name];
+            }
+
+            fromTo[0] = CssParser[name](fromTo[0]);
+            fromTo[1] = CssParser[name](fromTo[1]);
+
+            // type check
+            if (type) {
+                this[type] && this[type](name, animation, percentCriterion);
+            }
+            animation.name.push(name);
+
+            //console.log(animation.fromTo[name]);
+        },
+
+        unitArray: function(name, animation, percentCriterion) {
+            var from = [], to = [], unit = [], i, len, f, t, cri,
+                fromTo = animation.fromTo[name];
+
+            for (i = 0, len = fromTo[0].length; i < len; i++) {
+                f = fromTo[0][i];
+                t = fromTo[1][i];
+
+                if (f.unit !== t.unit) {
+                    cri = (typeof percentCriterion === 'object' && percentCriterion[i] ? percentCriterion[i] : percentCriterion);
+                    this._convertUnit(animation.target.dom, f, t, cri, name);
+                }
+
+                from.push(f.number);
+                to.push(t.number);
+                unit.push(t.unit);
+            }
+
+            animation.fromTo[name] = [from, to];
+            animation.unit[name] = unit;
+        },
+
+//      TYPE Function
+        _colorType: function(name, animation) {
+            animation.target.cur[name] = new Uint8Array(3);
+        },
+
+        _fontSizeType: function(name, animation) {
+            var fromTo = animation.fromTo[name];
+
+            if (isNaN(fromTo[0].number)) {
+                this._getStringFontNumber(fromTo[0], animation.target.dom)
+            }
+
+            if (isNaN(fromTo[1].number)) {
+                this._getStringFontNumber(fromTo[1], animation.target.dom)
+            }
+
+            this._unitType(name, animation, 'fontSize');
+        },
+
+        _backgroundType: function(name, animation) {
+
+            if (animation.fromTo[name][0].length === 1) {
+                animation.fromTo[name][0].push({
+                    number: 50,
+                    unit: '%'
+                });
+            }
+
+            if (animation.fromTo[name][1].length === 1) {
+                animation.fromTo[name][1].push({
+                    number: 50,
+                    unit: '%'
+                });
+            }
+
+            this.unitArray(name, animation, ['width', 'height']);
+        },
+
+        _unitType: function(name, animation, criterion) {
+            var from = animation.fromTo[name][0],
+                to = animation.fromTo[name][1];
+
+            if (from.unit !== to.unit) {
+                this._convertUnit(animation.target.dom, from, to, criterion, name);
+            }
+
+            animation.unit[name] = to.unit;
+            animation.target.unit[name] = to.unit;
+            animation.fromTo[name][0] = from.number;
+            animation.fromTo[name][1] = to.number;
+
+            //animation.target.from[name] = to[0];
+
+            return false;
+        },
+
+        _webkitClipPathType: function(name, animation) {
+            var fromTo = animation.fromTo[name];
+
+            // todo: exception
+            animation.unit[name + 'Style'] = fromTo[1][0];
+            fromTo[0].splice(0, 1);
+            fromTo[1].splice(0, 1);
+
+            this.unitArray(name, animation, 'width');
+        },
+
+        _shadowType: function(name, animation) {
+            var from = animation.fromTo[name][0], to = animation.fromTo[name][1],
+                animationFrom = [], animationTo = [], animationUnit = [],
+                shadowFrom, shadowTo,
+                unit, i, j, shadow, len, shadowLen;
+
+            animation.unit[name] = animationUnit;
+
+            for (i = 0, shadowLen = to.length; i < shadowLen; i++) {
+
+                (!from[i]) && (from[i] = []);
+                shadowFrom = from[i];
+                shadowTo = to[i];
+                unit = [];
+                animationUnit.push(unit);
+
+                for (j = 0, len = shadowTo.length - 1; j < len; j++) {
+
+                    unit.push(shadowTo[j].unit);
+
+                    if (shadowFrom[j] && shadowTo[j].unit !== (shadowFrom[j].unit)) {
+                        this._convertUnit(animation.target.dom, shadowFrom[j], shadowTo[j], 'width', name);
+                    }
+
+                    shadowTo[j] = shadowTo[j].number;
+
+                    shadowFrom[j] = (shadowFrom[j] ? shadowFrom[j].number : 0);
+                }
+
+                shadowFrom[len] || (shadowFrom[len] = new Uint8Array(3));
+
+            }
+
+            animation.cur[name] = base.deepCopy(to);
+        },
+
+        //TODO : not parser
+        _exceptGetStyle: function(dom, style) {
+            var result, imageUrl, img;
+
+            if (style === 'left') {
+                result = dom.offsetLeft + 'px';
+            } else if (style === 'top') {
+                result = dom.offsetTop + 'px';
+            } else if (style === 'clip') {
+                result = 'rect(0px 0px 0px 0px)';
+            } else if (style === 'boxShadow') {
+                result = '0px 0px 0px 0px black';
+            } else if (style === 'textShadow') {
+                result = '0px 0px 0px black';
+            } else if (style === 'backgroundPosition') {
+                result = '0px 0px';
+            } else if (style === 'backgroundSize') {
+                imageUrl = this._getStyle(dom, 'backgroundImage');
+                window.aa = img = new Image();
+                img.src = imageUrl;
+
+                if (img.width && img.height) {
+                    result = img.width + 'px ' + img.height + 'px';
+                } else {
+                    result = '0px 0px';
+                }
+            }
+
+            if (result === undefined) {
+                result = '0px';
+            }
+
+            return result;
+        },
+
+        // get Style
+        _getCriterionEm: function(dom, criterion) {
+            return criterion === 'fontSize' ? 16 : (this._getStyle(dom, 'fontSize').number || 16);
+        },
+
+        _getCriterionPercent: function(dom, criterion, style) {
+            var parent = dom.parentNode,
+                parentValue, string, size, imgSize;
+
+            if (style === 'lineHeight') {
+                return (this._getStyle(dom, 'fontSize').number || 16);
+            } else if (style === 'backgroundPosition') {
+
+                size = this._getStyle(dom, criterion).number;
+                imgSize = this._getBackgroundImageSize(dom, criterion);
+
+                return size - imgSize + 1;
+            } else if (style === 'backgroundSize') {
+                return this._getStyle(dom, criterion).number;
+            }
+
+            parentValue = CssParser._getFloat(window.getComputedStyle(parent)[criterion]);
+            while (parentValue === '' && parent !== document.body) {
+                parent = parent.parentNode;
+                parentValue = CssParser._getFloat(window.getComputedStyle(parent)[criterion]);
+            }
+
+            if (parentValue === 0 && (criterion === 'width' || criterion === 'height')) {
+                string = criterion.substring(0, 1).toUpperCase() + criterion.substring(1);
+                parentValue = window['inner' + string];
+            }
+
+            return parentValue;
+        },
+
+        _getStyle: function(dom, style) {
+            var s = window.getComputedStyle(dom)[style];
+            s = CssParser[style](s);
+            return s;
+        },
+
+        _getBackgroundImageSize: function(dom, style) {
+            var imageUrl, img,
+                size = this._getStyle(dom, 'backgroundSize');
+
+            if (size[0].unit === 'auto') {
+                imageUrl = this._getStyle(dom, 'backgroundImage');
+                img = new Image();
+                img.src = imageUrl;
+
+                if (style === undefined) {
+                    return [img.width, img.height];
+                }
+                return img[style];
+            } else {
+                return size[(style === 'width' ? 0 : 1)].number;
+            }
+
+        },
+
+        _getStringFontNumber: function(value, dom) {
+            var string = value.unit;
+
+            if (string === 'normal' || string === 'initial') {
+                value.number = (this._getStyle(dom, 'fontSize').number || 16);
+                value.unit = 'px';
+            } else if (string === 'xx-small') {
+                value.number = 0.5625;
+                value.unit = 'em';
+            } else if (string === 'x-small') {
+                value.number = 0.625;
+                value.unit = 'em';
+            } else if (string === 'small') {
+                value.number = 0.8125;
+                value.unit = 'em';
+            } else if (string === 'medium') {
+                value.number = 1;
+                value.unit = 'em';
+            } else if (string === 'large') {
+                value.number = 1.125;
+                value.unit = 'em';
+            } else if (string === 'x-large') {
+                value.number = 1.5;
+                value.unit = 'em';
+            } else if (string === 'xx-large') {
+                value.number = 2;
+                value.unit = 'em';
+            }
+        },
+
+        _getTranslateValue: function(name, animation, value) {
+            var translate, result;
+
+            translate = CssParser._unit(value);
+            if (translate.unit !== 'px') {
+                if (name === 'translateX' || name === 'translateZ') {
+                    result = this._convertPx(animation.target.dom, translate.number, translate.unit, 'width');
+
+                } else if (name === 'translateY') {
+                    result = this._convertPx(animation.target.dom, translate.number, translate.unit, 'height');
+                }
+            } else {
+                result = translate.number;
+            }
+
+            return result;
+        },
+
+
+        // Unit Convert  //TODO: refactoring
+        _convertUnit: function(dom, from, to, criterion, style) {
+            if (to.unit === 'em') {
+                from.number = this._convertEm(dom, from.number, from.unit, criterion, style);
+            } else if (to.unit === '%') {
+                from.number = this._convertPer(dom, from.number, from.unit, criterion, style);
+            } else if (to.unit === 'px') {
+                from.number = this._convertPx(dom, from.number, from.unit, criterion, style);
+            } else if (to.unit === 'cm') {
+                from.number = this._convertCm(dom, from.number, from.unit, criterion, style);
+            } else if (to.unit === 'pt') {
+                from.number = this._convertPt(dom, from.number, from.unit, criterion, style);
+            }
+        },
+
+        _convertEm: function(dom, value, unit, criterion, style) {
+            var fontSize = this._getCriterionEm(dom, criterion, style);
+            if (value === 0) {
+                return 0;
+            }
+
+            if (unit === 'px') {
+                return value / fontSize;
+            } else if (unit === '%') {
+                return (value / 100 * this._getCriterionPercent(dom, criterion, style)) / fontSize;
+            } else if (unit === 'cm' || unit === 'pt') {
+                return this._convertPx(dom, value, unit, criterion, style) / fontSize;
+            }
+
+            return false;
+        },
+
+        _convertPer: function(dom, value, unit, criterion, style) {
+            var parentValue = this._getCriterionPercent(dom, criterion, style);
+
+            if (value === 0) {
+                return 0;
+            }
+
+            if (unit === 'px') {
+                return value / parentValue * 100;
+            } else if (unit === 'em') {
+                return (value * this._getCriterionEm(dom, criterion, style)) / parentValue * 100;
+            } else if (unit === 'cm' || unit === 'pt') {
+                return this._convertPx(dom, value, unit, criterion, style) / parentValue * 100;
+            }
+
+            return false;
+        },
+
+        _convertPx: function(dom, value, unit, criterion, style) {
+            if (value === 0) {
+                return 0;
+            }
+
+            if (unit === '%') {
+                return value / 100 * this._getCriterionPercent(dom, criterion, style);
+            } else if (unit === 'em') {
+                return value * (value * this._getCriterionEm(dom, criterion, style));
+            } else if (unit === 'cm') {
+                return value * 37.795;
+            } else if (unit === 'pt') {
+                return value * 1.3;
+            }
+
+            return false;
+        },
+
+        _convertCm: function(dom, value, unit, criterion, style) {
+            var pxValue;
+
+            if (value === 0) {
+                return 0;
+            }
+
+            if (unit !== 'px') {
+                pxValue = this._convertPx(dom, value, unit, criterion, style);
+            } else {
+                pxValue = value;
+            }
+
+            return pxValue * 0.02646;
+        },
+
+        _convertPt: function(dom, value, unit, criterion, style) {
+            var ptValue;
+
+            if (value === 0) {
+                return 0;
+            }
+
+            if (unit !== 'px') {
+                ptValue = this._convertPx(dom, value, unit, criterion, style);
+            } else {
+                ptValue = value;
+            }
+
+            return ptValue * 0.75;
+        }
+
+    });
+
+    /*
+     * Makes CSS properties for animation. If user uses CSS property, the animation is going to make it's properties.
+     */
+    ns.CssAnimationUtil = ns.base.singleTon(CssAnimationUtil);
+
+})(window, ns, ns.base);
+/*
+ * # Animation Util
+ *
+ * Makes utilities for animation such as stagger, option, pre-defined effect, and keyframe.
+ * This module provide additional feature to help SimpleAnimation.
+ * Animation Util convert pre-defined effect, keyframe, option. Simple Animation will use based on this information.
+ * Also, Animation Util check whether stagger is on or not.
+ *
+ * @class ns.AnimationUtil
+ */
+(function(window, ns, base) {
+    var AnimationUtil = {
+
+        /**
+         * Returns option for animation. Because option value can be various type, this function make unified expression.
+         * @method optionAnalyzer
+         * @param {Object|Number} arg1
+         * The arg1 can be option Object as {duration: 1000, ease: 'bounceOut', delay: 100} OR number value that indicate duration
+         * @param {Object|undefined} arg2
+         * The arg2 can be Object as {ease: 'bounceOut', delay: 100} OR undefined
+         * @return {Object}
+         * @member ns.AnimationUtil
+         * @static
+         */
+        optionAnalyzer: function(arg1, arg2) {
+            var option;
+
+            if (arg1 !== undefined) {
+                if (typeof arg1 === 'number') {
+                    if (arg2 && typeof arg2 === 'object') {
+                        option = arg2;
+                    } else {
+                        option = {};
+                    }
+                    option.duration = arg1;
+                } else if (typeof arg1 === 'object') {
+                    option = arg1;
+                }
+            } else {
+                option = {};
+                option.duration = 1000;
+            }
+            return option;
+        },
+
+        /**
+         * Checks stagger option that included option of animation. If stagger is set, delay values of all targets are set in serial order automatically.
+         * @method checkStagger
+         * @param {Object} targets
+         * If stagger option is exists, this targets will be applied delay in serial order.
+         * @param {Object} option
+         * the option include stagger, drag, ease, and so on.
+         * @param {Function} callback
+         * The callback function will be called after this function. Actually, callback handle option value about targets.
+         * @member ns.AnimationUtil
+         * @static
+         */
+        checkStagger: function(targets, option, callback) {
+            var i, len, o;
+            this.animations = [];
+
+            // stagger
+            for (i = 0, len = targets.length; i < len; i++) {
+                o = ns.base.deepCopy(option);
+
+                if (option.stagger) {
+                    o.delay = option.stagger * i + (option.delay || 0);
+                    o.reverseDelay = option.stagger * (len - i);
+                }
+
+                if (i !== 0 && option.drag) {
+                    o.duration += (option.drag * i);
+                }
+
+                if (i === 0 && option.onStart) {
+                    o.onStart = option.onStart;
+                }
+                /*  else if (i === len - 1 && option.onComplete) {
+                 o.onComplete = option.onComplete;
+                 }*/
+
+                callback(targets[i], o, i);
+            }
+        },
+
+        /**
+         * Creates Keyframe for animation. If user make keyframe, this function will be called and make appropriate value for animation.
+         * @method createKeyFrame
+         * @param {Object} frame
+         * The frame has keyframe information. Keyframe animation based on frame.
+         * @param {Object} option
+         * The Option has ease, delay, duration, and so on.
+         * @param {Function} callback
+         * After handling based on frame and option, callback will invoked with result of handling.
+         * @member ns.AnimationUtil
+         * @static
+         */
+        createKeyFrame: function(frame, option, callback) {
+            var i, j, l, preDuration, ft, o, offset = [], frames = [];
+
+            for (i in frame) {
+                offset.push(parseFloat(i));
+            }
+
+            offset.sort(function(a, b) {
+                return a - b;
+            });
+            preDuration = offset[0];
+
+            for (i = 0, l = offset.length - 1; i < l; i++) {
+                o = ns.base.deepCopy(option);
+                ft = {};
+
+                for (j in frame[offset[i + 1]]) {
+                    if (frame[offset[i]][j] !== undefined) {
+                        ft[j] = [frame[offset[i]][j], frame[offset[i + 1]][j]]
+                    } else {
+                        ft[j] = frame[offset[i + 1]][j];
+                    }
+                }
+
+                o.duration = option.duration * (offset[i + 1] - preDuration);
+                preDuration = offset[i + 1];
+
+                if (i === 0) {
+
+                    option.onStart && (o.onStart = option.onStart);
+                    option.delay && (o.delay = option.delay);
+                    o.reverseDelay = 0;
+
+                } else {
+
+                    option.delay && (o.delay = 0);
+                    option.stagger && (o.delay = 0);
+
+                    if (i === l - 1) {
+
+                        option.onComplete && (o.onComplete = option.onComplete);
+
+
+                    } else {
+                        o.reverseDelay = 0;
+                    }
+                }
+
+//                if(option.stagger) {
+//                    if(i !== 0) {
+//                        o.delay = 0;
+//                    }
+//                    if(i !== l-1) {
+//                        o.reverseDelay = 0;
+//                    }
+//                }
+//                console.log(o.delay);
+                callback(ft, o, i);
+            }
+        },
+
+        /**
+         * Analyzes effect as pre-defined. This function make keyframe based frame, cubic-bezier based ease, transformOrigin value, visibility.
+         * @method effectAnalyzer
+         * @param {Object} target
+         * @param {String} animation
+         * The animation is a effect as a String.
+         * @return {Array}
+         * @member ns.AnimationUtil
+         * @static
+         */
+        effectAnalyzer: function(target, animation) {
+            var predefined, frame, ease, transformOrigin, visibility,
+                width = ns.CssAnimationUtil.getInstance()._getCriterionPercent(target.dom, 'width'),
+                height = ns.CssAnimationUtil.getInstance()._getCriterionPercent(target.dom, 'height');
+            predefined = animation;
+
+            target.dom.style.opacity = target.dom.style.opacity ? target.dom.style.opacity : 1;
+
+            if (predefined === 'pulse') {
+                frame = {
+                    0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY},
+                    0.5: {scaleX: 1.05 * target.cur.scaleX, scaleY: 1.05 * target.cur.scaleY},
+                    1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY}
+                };
+            } else if (predefined === 'rollIn') {
+                frame = {
+                    0: {translateX: -100 + target.cur.translateX, rotateZ: -120 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity},
+                    1: {translateX: 0 + target.cur.translateX, rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity}
+                };
+
+            } else if (predefined === 'rollOut') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    1: {translateX: 200 + target.cur.translateX, rotateZ: 120 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'bounce') {
+                frame = {
+                    0: {translateY: 0 + target.cur.translateY},
+                    0.2: {translateY: 0 + target.cur.translateY},
+                    0.4: {translateY: -30 + target.cur.translateY},
+                    0.5: {translateY: 0 + target.cur.translateY},
+                    0.7: {translateY: -15 + target.cur.translateY},
+                    0.8: {translateY: 0 + target.cur.translateY},
+                    0.9: {translateY: -4 + target.cur.translateY},
+                    1: {translateY: 0 + target.cur.translateY}
+                };
+                ease = ['bounce1', 'bounce1', 'bounce2', 'bounce1', 'bounce2', 'bounce1', '', 'bounce1'];
+                transformOrigin = 'center bottom';
+            } else if (predefined === 'bounceIn') {
+                frame = {
+                    0: {scaleX: 0.3 * target.cur.scaleX, scaleY: 0.3 * target.cur.scaleY},
+                    0.2: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY},
+                    0.4: {scaleX: 0.9 * target.cur.scaleX, scaleY: 0.9 * target.cur.scaleY},
+                    0.6: {scaleX: 1.03 * target.cur.scaleX, scaleY: 1.03 * target.cur.scaleY},
+                    0.8: {scaleX: 0.97 * target.cur.scaleX, scaleY: 0.97 * target.cur.scaleY},
+                    1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY}
+                };
+                ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1'];
+            } else if (predefined === 'bounceInDown') {
+                frame = {
+                    0: {translateY: -3000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity},
+                    0.6: {translateY: 25 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.75: {translateY: -10 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.9: {translateY: 5 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    1: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}
+                };
+                ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1'];
+            } else if (predefined === 'bounceInLeft') {
+                frame = {
+                    0: {translateX: -3000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity},
+                    0.6: {translateX: 25 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    0.75: {translateX: -10 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    0.9: {translateX: 5 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    1: {translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}
+                };
+                ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1'];
+            } else if (predefined === 'bounceInRight') {
+                frame = {
+                    0: {translateX: 3000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity},
+                    0.6: {translateX: -25 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    0.75: {translateX: 10 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    0.9: {translateX: -5 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    1: {translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity}
+                };
+                ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1'];
+            } else if (predefined === 'bounceInUp') {
+                frame = {
+                    0: {translateY: 3000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity},
+                    0.6: {translateY: -25 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.75: {translateY: 10 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.9: {translateY: -5 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    1: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}
+                };
+                ease = ['bounce1', 'bounce1', 'bounce1', 'bounce1', 'bounce1'];
+            } else if (predefined === 'bounceOut') {
+                frame = {
+                    0.2: {opacity: 0 * target.dom.style.opacity, scaleX: 0.9 * target.cur.scaleX, scaleY: 0.9 * target.cur.scaleY},
+                    0.5: {opacity: 1 * target.dom.style.opacity, scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY},
+                    1: {opacity: 0 * target.dom.style.opacity, scaleX: 0.3 * target.cur.scaleX, scaleY: 0.3 * target.cur.scaleY}
+                };
+            } else if (predefined === 'bounceOutDown') {
+                frame = {
+                    0: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.1: {translateY: 10 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.45: {translateY: -20 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    1: {translateY: 2000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'bounceOutLeft') {
+                frame = {
+                    0: {translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    0.2: {translateX: 20 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    1: {translateX: -2000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'bounceOutRight') {
+                frame = {
+                    0: {translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    0.2: {translateX: -20 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    1: {translateX: 2000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'bounceOutUp') {
+                frame = {
+                    0: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.2: {translateY: -10 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.45: {translateY: 20 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    1: {translateY: -2000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'zoomIn') {
+                frame = {
+                    0: {scaleX: 0.3 * target.cur.scaleX, scaleY: 0.3 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity},
+                    0.5: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'zoomInDown') {
+                frame = {
+                    0: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity, translateX: 0 + target.cur.translateX, translateY: -1000 + target.cur.translateY},
+                    0.6: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX, translateY: 60 + target.cur.translateY},
+                    1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX, translateY: 0 + target.cur.translateY}
+                };
+                ease = ['zoomInDown', 'backOut'];
+            } else if (predefined === 'zoomInLeft') {
+                frame = {
+                    0: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity, translateX: -1000 + target.cur.translateX},
+                    0.6: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateX: 10 + target.cur.translateX},
+                    1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateX}
+                };
+                ease = ['zoomInDown', 'backOut'];
+            } else if (predefined === 'zoomInRight') {
+                frame = {
+                    0: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity, translateX: 1000 + target.cur.translateX, translateY: target.cur.translateY},
+                    0.6: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateX: -10 + target.cur.translateX, translateY: target.cur.translateY},
+                    1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateY: target.cur.translateY}
+                };
+                ease = ['zoomInDown', 'backOut'];
+            } else if (predefined === 'zoomInUp') {
+                frame = {
+                    0: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity, translateY: 1000 + target.cur.translateY},
+                    0.6: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateY: -60 + target.cur.translateY},
+                    1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY}
+                };
+                ease = ['zoomInDown', 'backOut'];
+            } else if (predefined === 'zoomOut') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    0.6: {scaleX: 0.3 * target.cur.scaleX, scaleY: 0.3 * target.cur.scaleY, opacity: 0 * target.dom.style.opacity},
+                    1: {opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'zoomOutDown') {
+                frame = {
+                    0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.4: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, translateY: -60 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    1: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, translateY: 2000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity}
+                };
+                ease = ['zoomInDown', 'backOut'];
+                transformOrigin = 'center bottom';
+            } else if (predefined === 'zoomOutLeft') {
+                frame = {
+                    0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    0.4: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, translateX: 42 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    1: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, translateX: -2000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity}
+                };
+                transformOrigin = 'left center';
+            } else if (predefined === 'zoomOutRight') {
+                frame = {
+                    0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, translateX: 0 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    0.4: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, translateX: -42 + target.cur.translateX, opacity: 1 * target.dom.style.opacity},
+                    1: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, translateX: 2000 + target.cur.translateX, opacity: 0 * target.dom.style.opacity}
+                };
+                transformOrigin = 'right center';
+            } else if (predefined === 'zoomOutUp') {
+                frame = {
+                    0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    0.4: {scaleX: 0.475 * target.cur.scaleX, scaleY: 0.475 * target.cur.scaleY, translateY: 60 + target.cur.translateY, opacity: 1 * target.dom.style.opacity},
+                    1: {scaleX: 0.1 * target.cur.scaleX, scaleY: 0.1 * target.cur.scaleY, translateY: -2000 + target.cur.translateY, opacity: 0 * target.dom.style.opacity}
+                };
+                ease = ['zoomInDown', 'backOut'];
+                transformOrigin = 'center bottom';
+            } else if (predefined === 'slideInDown') {
+                frame = {
+                    0: {translateY: (height * -1) + target.cur.translateY},
+                    1: {translateY: 0 + target.cur.translateY}
+                };
+                visibility = 'visible';
+            } else if (predefined === 'slideInLeft') {
+                frame = {
+                    0: {translateX: (width * -1) + target.cur.translateX},
+                    1: {translateX: 0 + target.cur.translateX}
+                };
+                visibility = 'visible';
+            } else if (predefined === 'slideInRight') {
+                frame = {
+                    0: {translateX: (width * 1) + target.cur.translateX},
+                    1: {translateX: 0 + target.cur.translateX}
+                };
+                visibility = 'visible';
+            } else if (predefined === 'slideInUp') {
+                frame = {
+                    0: {translateY: (height * 1) + target.cur.translateY},
+                    1: {translateY: 0 + target.cur.translateY}
+                };
+                visibility = 'visible';
+            } else if (predefined === 'slideOutDown') {
+                frame = {
+                    0: {translateY: 0 + target.cur.translateY},
+                    1: {translateY: (height * 1) + target.cur.translateY}
+                };
+                visibility = 'hidden';
+            } else if (predefined === 'slideOutLeft') {
+                frame = {
+                    0: {translateX: 0 + target.cur.translateX},
+                    1: {translateX: (width * -1) + target.cur.translateX}
+                };
+                visibility = 'hidden';
+            } else if (predefined === 'slideOutRight') {
+                frame = {
+                    0: {translateX: 0 + target.cur.translateX},
+                    1: {translateX: (width * 1) + target.cur.translateX}
+                };
+                visibility = 'hidden';
+            } else if (predefined === 'slideOutUp') {
+                frame = {
+                    0: {translateY: 0 + target.cur.translateY},
+                    1: {translateY: (height * -1) + target.cur.translateY}
+                };
+                visibility = 'hidden';
+            } else if (predefined === 'flash') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    0.25: {opacity: 0 * target.dom.style.opacity},
+                    0.5: {opacity: 1 * target.dom.style.opacity},
+                    0.75: {opacity: 0 * target.dom.style.opacity},
+                    1: {opacity: 1 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'rubberBand') {
+                frame = {
+                    0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY},
+                    0.3: {scaleX: 1.25 * target.cur.scaleX, scaleY: 0.75 * target.cur.scaleY},
+                    0.4: {scaleX: 0.75 * target.cur.scaleX, scaleY: 1.25 * target.cur.scaleY},
+                    0.5: {scaleX: 1.15 * target.cur.scaleX, scaleY: 0.85 * target.cur.scaleY},
+                    0.65: {scaleX: 0.95 * target.cur.scaleX, scaleY: 1.05 * target.cur.scaleY},
+                    0.75: {scaleX: 1.05 * target.cur.scaleX, scaleY: 0.95 * target.cur.scaleY},
+                    1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY}
+                };
+            } else if (predefined === 'shake') {
+                frame = {
+                    0: {translateX: 0 + target.cur.translateX},
+                    0.1: {translateX: -10 + target.cur.translateX},
+                    0.2: {translateX: 10 + target.cur.translateX},
+                    0.3: {translateX: -10 + target.cur.translateX},
+                    0.4: {translateX: 10 + target.cur.translateX},
+                    0.5: {translateX: -10 + target.cur.translateX},
+                    0.6: {translateX: 10 + target.cur.translateX},
+                    0.7: {translateX: -10 + target.cur.translateX},
+                    0.8: {translateX: 10 + target.cur.translateX},
+                    0.9: {translateX: -10 + target.cur.translateX},
+                    1: {translateX: 0 + target.cur.translateX}
+                };
+            } else if (predefined === 'swing') {
+                frame = {
+                    0: {rotateZ: 0 + target.cur.rotateZ},
+                    0.2: {rotateZ: 15 + target.cur.rotateZ},
+                    0.4: {rotateZ: -10 + target.cur.rotateZ},
+                    0.6: {rotateZ: 5 + target.cur.rotateZ},
+                    0.8: {rotateZ: -5 + target.cur.rotateZ},
+                    1: {rotateZ: 0 + target.cur.rotateZ}
+                };
+                transformOrigin = 'top center';
+            } else if (predefined === 'tada') {
+                frame = {
+                    0: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, rotateZ: 0 + target.cur.rotateZ},
+                    0.15: {scaleX: 0.9 * target.cur.scaleX, scaleY: 0.9 * target.cur.scaleY, rotateZ: -3 + target.cur.rotateZ},
+                    0.3: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: 3 + target.cur.rotateZ},
+                    0.4: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: -3 + target.cur.rotateZ},
+                    0.5: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: 3 + target.cur.rotateZ},
+                    0.6: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: -3 + target.cur.rotateZ},
+                    0.7: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: 3 + target.cur.rotateZ},
+                    0.8: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: -3 + target.cur.rotateZ},
+                    0.9: {scaleX: 1.1 * target.cur.scaleX, scaleY: 1.1 * target.cur.scaleY, rotateZ: 3 + target.cur.rotateZ},
+                    1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, rotateZ: 0 + target.cur.rotateZ}
+                };
+            } else if (predefined === 'wobble') {
+                frame = {
+                    0: {translateX: 0 + target.cur.translateX, rotateZ: 0 + target.cur.rotateZ},
+                    0.15: {translateX: (width * -0.25) + target.cur.translateX, rotateZ: -5 + target.cur.rotateZ},
+                    0.3: {translateX: (width * 0.2) + target.cur.translateX, rotateZ: 3 + target.cur.rotateZ},
+                    0.45: {translateX: (width * -0.15) + target.cur.translateX, rotateZ: -3 + target.cur.rotateZ},
+                    0.6: {translateX: (width * 0.1) + target.cur.translateX, rotateZ: 2 + target.cur.rotateZ},
+                    0.75: {translateX: (width * -0.05) + target.cur.translateX, rotateZ: -1 + target.cur.rotateZ},
+                    1: {translateX: 0 + target.cur.translateX, rotateZ: 0 + target.cur.rotateZ}
+                };
+            } else if (predefined === 'jello') {
+                frame = {
+                    0: {skewX: 0 + target.cur.skewX, skewY: 0 + target.cur.skewY},
+                    0.22: {skewX: -12.5 + target.cur.skewX, skewY: -12.5 + target.cur.skewY},
+                    0.33: {skewX: 6.25 + target.cur.skewX, skewY: 6.25 + target.cur.skewY},
+                    0.44: {skewX: -3.125 + target.cur.skewX, skewY: -3.125 + target.cur.skewY},
+                    0.55: {skewX: 1.5625 + target.cur.skewX, skewY: 1.5625 + target.cur.skewY},
+                    0.66: {skewX: -0.78125 + target.cur.skewX, skewY: -0.78125 + target.cur.skewY},
+                    0.77: {skewX: 0.390625 + target.cur.skewX, skewY: 0.390625 + target.cur.skewY},
+                    0.88: {skewX: -0.1953125 + target.cur.skewX, skewY: -0.1953125 + target.cur.skewY},
+                    1: {skewX: 0 + target.cur.skewX, skewY: 0 + target.cur.skewY}
+                };
+                transformOrigin = 'center';
+            } else if (predefined === 'fadeIn') {
+                frame = {
+                    0: {opacity: 0 * target.dom.style.opacity},
+                    1: {opacity: 1 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'fadeInDown') {
+                frame = {
+                    0: {translateY: (height * -1) + target.cur.translateY, opacity: 0 * target.dom.style.opacity},
+                    1: {translateY: 0 + target.cur.translateY, opacity: 1 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'fadeInDownBig') {
+                frame = {
+                    0: {opacity: 0 * target.dom.style.opacity, translateY: -2000 + target.cur.translateY},
+                    1: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY}
+                };
+            } else if (predefined === 'fadeInLeft') {
+                frame = {
+                    0: {opacity: 0 * target.dom.style.opacity, translateX: (width * -1) + target.cur.translateX},
+                    1: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX}
+                };
+            } else if (predefined === 'fadeInLeftBig') {
+                frame = {
+                    0: {opacity: 0 * target.dom.style.opacity, translateX: -2000 + target.cur.translateX},
+                    1: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX}
+                };
+            } else if (predefined === 'fadeInRight') {
+                frame = {
+                    0: {opacity: 0 * target.dom.style.opacity, translateX: (width * 1) + target.cur.translateX},
+                    1: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX}
+                };
+            } else if (predefined === 'fadeInRightBig') {
+                frame = {
+                    0: {opacity: 0 * target.dom.style.opacity, translateX: 2000 + target.cur.translateX},
+                    1: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX}
+                };
+            } else if (predefined === 'fadeInUp') {
+                frame = {
+                    0: {opacity: 0 * target.dom.style.opacity, translateY: (height * 1) + target.cur.translateY},
+                    1: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY}
+                };
+
+            } else if (predefined === 'fadeInUpBig') {
+                frame = {
+                    0: {opacity: 0 * target.dom.style.opacity, translateY: 2000 + target.cur.translateY},
+                    1: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY}
+                };
+            } else if (predefined === 'fadeOut') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    1: {opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'fadeOutDown') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY},
+                    1: {opacity: 0 * target.dom.style.opacity, translateY: (height * 1) + target.cur.translateY}
+                };
+            } else if (predefined === 'fadeOutDownBig') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY},
+                    1: {opacity: 0 * target.dom.style.opacity, translateY: 2000 + target.cur.translateY}
+                };
+            } else if (predefined === 'fadeOutLeft') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX},
+                    1: {opacity: 0 * target.dom.style.opacity, translateX: (width * -1) + target.cur.translateX}
+                };
+            } else if (predefined === 'fadeOutLeftBig') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX},
+                    1: {opacity: 0 * target.dom.style.opacity, translateX: -2000 + target.cur.translateX}
+                };
+            } else if (predefined === 'fadeOutRight') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX},
+                    1: {opacity: 0 * target.dom.style.opacity, translateX: (width * 1) + target.cur.translateX}
+                };
+            } else if (predefined === 'fadeOutRightBig') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity, translateX: 0 + target.cur.translateX},
+                    1: {opacity: 0 * target.dom.style.opacity, translateX: 2000 + target.cur.translateX}
+                };
+            } else if (predefined === 'fadeOutUp') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY},
+                    1: {opacity: 0 * target.dom.style.opacity, translateY: (height * -1) + target.cur.translateY}
+                };
+            } else if (predefined === 'fadeOutUpBig') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity, translateY: 0 + target.cur.translateY},
+                    1: {opacity: 0 * target.dom.style.opacity, translateY: -2000 + target.cur.translateY}
+                };
+            } else if (predefined === 'flip') {
+                frame = {
+                    0: {rotateY: -360 + target.cur.rotateY, perspective: 400},
+                    0.4: {rotateY: -190 + target.cur.rotateY, translateZ: 150 + target.cur.translateZ, perspective: 400},
+                    0.5: {rotateY: -170 + target.cur.rotateY, translateZ: 150 + target.cur.translateZ, perspective: 400},
+                    0.8: {scaleX: 0.95 * target.cur.scaleX, scaleY: 0.95 * target.cur.scaleY, perspective: 400},
+                    1: {scaleX: 1 * target.cur.scaleX, scaleY: 1 * target.cur.scaleY, rotateY: 0 + target.cur.rotateY, translateZ: 0 + target.cur.translateZ, perspective: 400}
+                };
+                ease = ['easeIn', 'easeIn', 'easeIn', 'easeIn', 'easeIn'];
+            } else if (predefined === 'flipInX') {
+                frame = {
+                    0: {rotateX: 90 + target.cur.rotateX, perspective: 400, opacity: 0 * target.dom.style.opacity},
+                    0.4: {rotateX: -20 + target.cur.rotateX, perspective: 400, opacity: 1 * target.dom.style.opacity},
+                    0.6: {rotateX: 10 + target.cur.rotateX, perspective: 400, opacity: 1 * target.dom.style.opacity},
+                    0.8: {rotateX: -5 + target.cur.rotateX, perspective: 400, opacity: 1 * target.dom.style.opacity},
+                    1: {rotateX: 0 + target.cur.rotateX, perspective: 400, opacity: 1 * target.dom.style.opacity}
+                };
+                ease = ['easeIn', 'easeIn', 'easeIn', 'easeIn', 'easeIn'];
+            } else if (predefined === 'flipInY') {
+                frame = {
+                    0: {rotateY: 90 + target.cur.rotateY, perspective: 400, opacity: 0 * target.dom.style.opacity},
+                    0.4: {rotateY: -20 + target.cur.rotateY, perspective: 400, opacity: 1 * target.dom.style.opacity},
+                    0.6: {rotateY: 10 + target.cur.rotateY, perspective: 400, opacity: 1 * target.dom.style.opacity},
+                    0.8: {rotateY: -5 + target.cur.rotateY, perspective: 400, opacity: 1 * target.dom.style.opacity},
+                    1: {rotateY: 0 + target.cur.rotateY, perspective: 400, opacity: 1 * target.dom.style.opacity}
+                };
+                ease = ['easeIn', 'easeIn', 'easeIn', 'easeIn', 'easeIn'];
+            } else if (predefined === 'flipOutX') {
+                frame = {
+                    0: {perspective: 400},
+                    0.3: {perspective: 400, rotateX: -20 + target.cur.rotateX, opacity: 1 * target.dom.style.opacity},
+                    1: {perspective: 400, rotateX: 90 + target.cur.rotateX, opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'flipOutY') {
+                frame = {
+                    0: {perspective: 400},
+                    0.3: {perspective: 400, rotateY: -15 + target.cur.rotateY, opacity: 1 * target.dom.style.opacity},
+                    1: {perspective: 400, rotateY: 90 + target.cur.rotateY, opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'lightSpeedIn') {
+                frame = {
+                    0: {translateX: (width * 1) + target.cur.translateX, skewX: -30 + target.cur.skewX, opacity: 0 * target.dom.style.opacity},
+                    0.6: {translateX: 0 + target.cur.translateX, skewX: 20 + target.cur.skewX, opacity: 1 * target.dom.style.opacity},
+                    0.8: {translateX: 0 + target.cur.translateX, skewX: -5 + target.cur.skewX, opacity: 1 * target.dom.style.opacity},
+                    1: {translateX: 0 + target.cur.translateX, skewX: 0 + target.cur.skewX, opacity: 1 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'lightSpeedOut') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    1: {translateX: (width * 1) + target.cur.translateX, skewX: 30 + target.cur.skewX, opacity: 0 * target.dom.style.opacity}
+                };
+            } else if (predefined === 'rotateIn') {
+                frame = {
+                    0: {rotateZ: -200 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity},
+                    1: {rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity}
+                };
+                transformOrigin = 'center';
+            } else if (predefined === 'rotateInDownLeft') {
+                frame = {
+                    0: {rotateZ: -45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity},
+                    1: {rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity}
+                };
+
+                transformOrigin = 'left bottom';
+            } else if (predefined === 'rotateInDownRight') {
+                frame = {
+                    0: {rotateZ: 45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity},
+                    1: {rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity}
+                };
+                transformOrigin = 'right bottom';
+            } else if (predefined === 'rotateInUpLeft') {
+                frame = {
+                    0: {rotateZ: 45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity},
+                    1: {rotateZ: +target.cur.rotateZ, opacity: 1 * target.dom.style.opacity}
+                };
+                transformOrigin = 'left bottom';
+            } else if (predefined === 'rotateInUpRight') {
+                frame = {
+                    0: {rotateZ: -90 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity},
+                    1: {rotateZ: 0 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity}
+                };
+                transformOrigin = 'right bottom';
+            } else if (predefined === 'rotateOut') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    1: {rotateZ: 200 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}
+                };
+                transformOrigin = 'center';
+            } else if (predefined === 'rotateOutDownLeft') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    1: {rotateZ: 45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}
+                };
+                transformOrigin = 'left bottom';
+            } else if (predefined === 'rotateOutDownRight') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    1: {rotateZ: -45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}
+                };
+                transformOrigin = 'right bottom';
+            } else if (predefined === 'rotateOutUpLeft') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    1: {rotateZ: -45 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}
+                };
+                transformOrigin = 'left bottom';
+            } else if (predefined === 'rotateOutUpRight') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    1: {rotateZ: 90 + target.cur.rotateZ, opacity: 0 * target.dom.style.opacity}
+                };
+                transformOrigin = 'right bottom';
+            } else if (predefined === 'hinge') {
+                frame = {
+                    0: {opacity: 1 * target.dom.style.opacity},
+                    0.2: {rotateZ: 80 + target.cur.rotateZ},
+                    0.4: {rotateZ: 60 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity},
+                    0.6: {rotateZ: 80 + target.cur.rotateZ},
+                    0.8: {rotateZ: 60 + target.cur.rotateZ, opacity: 1 * target.dom.style.opacity},
+                    1: {translateY: 700 + target.cur.translateY, opacity: 0 * target.dom.style.opacity}
+                };
+                transformOrigin = 'top left';
+                ease = ['easeInOut', 'easeInOut', 'easeInOut', 'easeInOut', 'easeInOut', 'easeInOut'];
+            } else {
+                throw new Error('the name of animation is not exists');
+            }
+
+            return [frame, ease, transformOrigin, visibility];
+        }
+    };
+
+    ns.AnimationUtil = AnimationUtil;
+})(window, ns, ns.base);
+// TODO
+
+(function(window, ns, base) {
+    var _singleton;
+
+    var ObjectManager = base.Class.extend({
+
+        _init: function() {
+            if (_singleton !== undefined) {
+                _singleton = new this();
+                return _singleton;
+            }
+            this.targetObjects = [];
+
+            return this;
+        },
+
+        /**
+         * Add animation object to manager.
+         * @method addTarget
+         * @param {target} animation object
+         * @member ns.ObjectManager.addTarget
+         * @private
+         */
+        addTarget: function(target) {
+            this.targetObjects.push(target);
+            target.map = new ns.base.WeakMap();
+        },
+
+        /**
+         * Create animation object.
+         * @method getObject
+         * @param {target} animation object
+         * @member ns.ObjectManager.getObject
+         * @private
+         */
+        getObject: function(obj) {
+
+            if (obj instanceof ns.AnimationObject) {
+                return obj;
+            }
+
+            for (var i = 0, len = this.targetObjects.length; i < len; i++) {
+                if(obj instanceof this.targetObjects[i].$type) {
+
+                    var object = this.targetObjects[i].map.get(obj);
+
+                    if(object === undefined) {
+                        object = new ns[this.targetObjects[i].$namespace](obj);
+                        this.targetObjects[i].map.set(obj, object);
+                    }
+                    return object;
+                }
+            }
+
+            throw 'CannotCreateObject';
+
+            return;
+        },
+
+
+        static: {
+            /**
+             * Return ObjectManger object
+             * @method getInstance
+             * @return {object}
+             * @member ns.ObjectManager.getInstance
+             * @static
+             */
+            getInstance: function() {
+                if (_singleton === undefined) {
+                    _singleton = new ObjectManager();
+                }
+                return _singleton;
+            },
+
+            /**
+             * Create Animation Object by using plugin
+             * @method plugin
+             * @param {object}
+             * @member ns.ObjectManager.plugin
+             * @static
+             */
+            plugin: function(definition) {
+                var keywordTest = /^\$(?:namespace|constructor|type)$/;
+
+                if( (!definition.$constructor) ) {
+                    return;
+                }
+                // TODO : $namespace, type 예외 처리
+                function Class() {
+                    ns.AnimationObject.call(this);
+                    definition.$constructor.apply(this, arguments);
+                }
+
+                Class.prototype = new ns.AnimationObject();
+                Class.prototype.constructor = Class;
+
+                for(var name in definition) {
+                    if(keywordTest.test(name)) {
+                        continue;
+                    }
+
+                    Class.prototype[name] = typeof definition[name] === 'function' && definition[name];
+                }
+
+                ns[definition.$namespace] = Class;
+
+                this.getInstance().addTarget(definition);
+
+                return Class;
+            }
+        }
+    });
+
+    /*
+     * Manages objects that will be animated.
+     */
+    ns.ObjectManager = ObjectManager;
+
+})(window, ns, ns.base);
+
+
+
+(function(window) {
+    'use strict';
+
+    (function(window, ns, base) {
+        var AnimationObject = ns.base.Class.extend({
+            _init: function() {
+                this.from = new ns.Transform();
+                this.cur = base.copy(this.from);
+
+                this.updateSeek = false;
+                this.updateSeekProperty = [];
+            },
+
+            getFrom: function(to) {
+                var v = {};
+                var to = to.animation;
+                for(var i in to){
+                    v[i] = this.from[i];
+                    this.from[i] = to[i];
+                }
+                return v;
+            },
+
+            setFrom: function(v) {
+                this.from.set(v);
+            },
+            translate: function() {
+
+            },
+            rotate: function() {
+
+            }
+        });
+
+        /*
+         * Manages animationObject.
+         */
+        ns.AnimationObject = AnimationObject;
+
+    })(window, ns, ns.base);
+
+})(window);
+(function(window, ns, base) {
+    'use strict';
+    var CssAnimationUtil = ns.CssAnimationUtil.getInstance(),
+        CssStringCreator = ns.CssStringCreator.getInstance();
+
+    /*
+     * Constructs and Sets based on DOMObject. DOM Object is the one of target for animation.
+     */
+
+    ns.ObjectManager.plugin({
+        $namespace: 'DomObject',
+        $type: window.HTMLElement,
+        $constructor: function(dom) {
+            this.dom = dom;
+            //this.style = dom.style;
+            this.unit = {};
+            this._perspective = false;
+        },
+
+        /**
+         * Render dom object on screen.
+         * @method render
+         * @param {value} update target value
+         * @param {unit} unix
+         * @member ns.DomObject
+         * @private
+         */
+        render: function(tweenInfo) {
+            var i, u = tweenInfo.updateProperty, l;
+            for (i = 0; l = u[i]; i++) {
+                tweenInfo.targetStyle[l] = CssStringCreator[l](this, tweenInfo.unit);
+            }
+            //var isUpdateTransform = false;
+            //
+            //for(var i in updateValue) {
+            //    if(!this.isTransform(i) && this.dom.style[i] !== undefined) {
+            //        this.dom.style[i] = CssStringCreator[i](updateValue, unit);
+            //    } else {
+            //        if(!isUpdateTransform) {
+            //            this.dom.style.WebkitTransform = CssStringCreator.WebkitTransform(updateValue);
+            //            isUpdateTransform = true;
+            //        }
+            //    }
+            //}
+        },
+
+        objectRender: function(updateValue) {
+            var isUpdateTransform = false;
+
+            for (var i in updateValue) {
+                if (!this.isTransform(i) && this.dom.style[i] !== undefined) {
+                    this.dom.style[i] = CssStringCreator[i](updateValue, unit);
+                } else {
+                    if (!isUpdateTransform) {
+                        this.dom.style.WebkitTransform = CssStringCreator.WebkitTransform(updateValue);
+                        isUpdateTransform = true;
+                    }
+                }
+            }
+        },
+
+        /**
+         * Create tween object in order to animate dom object.
+         * @method createTweenObject
+         * @param {value} animation from value
+         * @param {value} animation to value
+         * @param {value} animation option including duration, delay, ease ans so on.
+         * @member ns.DomObject
+         * @private
+         */
+        createTweenInfo: function(fromTo, option, needFromTo) {
+            var info = {
+                fromTo: {},
+                animationFromTo: fromTo,
+                cur: this.cur,
+                option: option,
+                name: [],
+                unit: {},
+                target: this,
+                targetStyle: this.dom.style,
+                updateProperty: []
+            };
+
+            if (needFromTo) {
+                this.setAnimationFromTo(info);
+            }
+
+            return info;
+        },
+
+        setAnimationFromTo: function(obj) {
+            var isTransform = false,
+                fromTo = obj.animationFromTo,
+                i;
+
+            for (i in fromTo) {
+                if (this.isTransform(i)) {
+                    CssAnimationUtil.WebkitTransform(i, obj);
+                    if (!isTransform) {
+                        obj.updateProperty.push('WebkitTransform');
+                        isTransform = true;
+                    }
+                } else if (i === 'perspective') {
+                    this._perspective = base.isNumber(fromTo[i]) ? fromTo[i] : (base.isNumber(fromTo[i][1]) ? fromTo[i][1] : 0);
+                    this.cur.perspective = this._perspective;
+                } else {
+                    if (CssAnimationUtil[i]) {
+                        CssAnimationUtil[i](obj);
+                        obj.updateProperty.push(i);
+                    }
+                }
+
+            }
+        },
+        /**
+         * Check if it is transform or not.
+         * @method isTransform
+         * @param {string}
+         * @return {boolean}
+         * @member ns.DomObject
+         * @private
+         */
+        isTransform: function(i) {
+            if (i === undefined || i === null) {
+                return;
+            }
+            if (i === 'translateX' || i === 'translateY' || i === 'translateZ' ||
+                i === 'rotateX' || i === 'rotateY' || i === 'rotateZ' ||
+                i === 'scaleX' || i === 'scaleY' || i === 'skewX' || i === 'skewY' /*|| i === 'perspective'*/) {
+                return true;
+
+            }
+            return false;
+        },
+
+        /**
+         * Set perspective of dom object.
+         * @method perspective
+         * @param {number} perspective value
+         * @member ns.DomObject
+         * @private
+         */
+        perspective: function(n) {
+            if (n === undefined || n === null) {
+                return;
+            }
+            if (!ns.base.isNumber(n)) {
+                return;
+            }
+            this._perspective = n;
+            this.cur.perspective = n;
+        },
+
+        /**
+         * Set animation value of dom object
+         * @method set
+         * @param {value} animation value
+         * @member ns.DomObject
+         * @private
+         */
+        set: function(v) {
+            if (v === undefined || v === null) {
+                return;
+            }
+            for (var i in v) {
+                if (this.isTransform(i)) {
+                    this.from[i] = v[i];
+                    this.cur[i] = v[i];
+                } else if (i === 'perspective') {
+                    this.perspective(v[i]);
+                } else {
+                    this.dom.style[i] = v[i];
+                }
+            }
+            this.objectRender(base.deepCopy(this.from));
+        }
+    });
+})(window, ns, ns.base);
+
+/**
+ * # TAU Animation
+ *
+ * Provides features that make and control animation.
+ * Simple Animation has relevance to Tween Animator.
+ * As you can see below APIs, almost APIs make Tween-able object and control animation.
+ *
+ * @example
+ * #### using tween and tween from ~ to
+ *
+ * $('#box').tween({left: 200}, {duration: 1000, ease: 'bounceInOut', onComplete: function() {
+ *                           console.log('animation complete');
+ *                         }
+ * });
+ * $('#box').tween({left: [200, 300]} {duration: 1000, ease: 'bounceInOut', onComplete: function() {
+ *                                               console.log('animation complete');
+ *                                           }
+ *     });
+ *
+ *
+ * #### using tween and tween from ~ to as chaining
+ *
+ * var box = document.createElement('div');
+ * box.tween({rotateZ: 120}, 1000)
+ * .tween({left: 200}, 1000)
+ * .tween({left: [200, 400], top: 100}, 1000);
+ *
+ * #### effect animation with stagger
+ *
+ * $('.box').animate('bounce', {duration: 1000, stagger: 200});
+ *
+ *
+ * @class tau.animation.SimpleAnimationMixinObject
+ */
+(function(window, ns, base) {
+    'use strict';
+
+    var ObjectManager = ns.ObjectManager.getInstance();
+
+    var SimpleAnimationMixinObject = {
+        /**
+         * Adds tween animation with animation information and target is animated.
+         * @method tween
+         * @member tau.animation.SimpleAnimationMixinObject
+         * @public
+         */
+        tween: function(fromTo, arg1, arg2) {
+            var option;
+
+            if (!this.simpleAnimation) {
+                if (this.length) {
+                    this.simpleAnimation = new ns.SimpleAnimationGroup(this);
+                } else {
+                    this.simpleAnimation = new ns.SimpleAnimation(this);
+                }
+            }
+
+            option = ns.AnimationUtil.optionAnalyzer(arg1, arg2);
+            this.simpleAnimation.add(fromTo, option);
+            this.simpleAnimation.play();
+
+            return this;
+        },
+
+        /**
+         * Stops animation or group animations.
+         * @method stop
+         * @member tau.animation.SimpleAnimationMixinObject
+         * @public
+         */
+        stop: function() {
+            if (!this.simpleAnimation) {
+
+                if (!this.simpleAnimation) {
+                    if (this.length) {
+                        this.simpleAnimation = new ns.SimpleAnimationGroup(this);
+                    } else {
+                        this.simpleAnimation = new ns.SimpleAnimation(this);
+                    }
+                }
+
+            }
+            this.simpleAnimation.stop();
+
+        },
+
+        /**
+         * Sets transform property of target.
+         * @method transform
+         * @member tau.animation.SimpleAnimationMixinObject
+         * @public
+         */
+        transform: function(v) {
+            if (!this.simpleAnimation) {
+                if (this.length) {
+                    this.simpleAnimation = new ns.SimpleAnimationGroup(this);
+                } else {
+                    this.simpleAnimation = new ns.SimpleAnimation(this);
+                }
+            }
+
+            this.simpleAnimation.target.set(v);
+        }
+    };
+
+    /**
+     * Makes simpleAnimation for playing animation.
+     * @constructor SimpleAnimation
+     * @param {Object} target
+     * The target is animated by tween animator.
+     * @member tau.animation.SimpleAnimation
+     * @private
+     */
+    var SimpleAnimation = function(target) {
+
+        this.tweenAnimator = new ns.TweenAnimator();
+        this.target = ObjectManager.getObject(target); // get animation object
+        this.target.simpleAnimation = this;
+
+        this.target.render && this.tweenAnimator.setRender(this.target.render);
+        this.target.cur && this.tweenAnimator.setUpdateTarget(this.target.cur);
+    };
+
+    /**
+     * Adds tween information object in animator.
+     * @method add
+     * @param {Object} fromTo
+     * @param {Object} option
+     * @param {Object} secondTweenAnimator
+     * @member tau.animation.SimpleAnimation.prototype
+     * @private
+     */
+    SimpleAnimation.prototype.add = function(fromTo, option, secondTweenAnimator) {
+        var frame, tweenObject, lastTween, st,
+            tweenAnimator = secondTweenAnimator || this.tweenAnimator,
+            self = this;
+
+        if (typeof fromTo === 'string') {
+            frame = ns.AnimationUtil.effectAnalyzer(this.target, fromTo);
+
+            ns.AnimationUtil.createKeyFrame(frame[0], option, function(ft, o, i) {
+                if (frame[1] !== undefined) {
+                    o.ease = frame[1][i];
+                }
+
+                tweenObject = self.target.createTweenInfo(ft, o, true);
+                tweenAnimator.add(tweenObject);
+
+                if (frame[2] !== undefined) {
+                    if (i === 0) {
+                        tweenObject.startCallback.on(function() {
+                            self.target.dom.style.webkitTransformOrigin = frame[2];
+                        });
+                    } else if (i === frame.length) {
+                        tweenObject.completeCallback.on(function() {
+                            self.target.dom.style.webkitTransformOrigin = '';
+                        });
+                    }
+                }
+
+                if (frame[3] !== undefined) {
+                    tweenObject.completeCallback.on(function() {
+                        self.target.dom.style.visibility = frame[3];
+                    });
+                }
+            });
+
+            return;
+        }
+
+        if (fromTo.effect) {
+            if (this.parTweensGroup === undefined) {
+                this.parTweensGroup = [];
+                st = new ns.TweenAnimator();
+                this.parTweensGroup.push(st);
+            } else {
+                st = this.parTweensGroup[0];
+            }
+
+            this.target.render && st.setRender(this.target.render);
+            this.target.cur && st.setUpdateTarget(this.target.cur);
+
+            this.add(fromTo.effect, base.deepCopy(option), st);
+        }
+
+        if (tweenAnimator.getState() === 'running') {
+            tweenObject = self.target.createTweenInfo(fromTo, option, false);
+
+            if (lastTween = tweenAnimator.getLastTweenInfo()) {
+                lastTween.completeCallback.on(function() {
+                    self.target.setAnimationFromTo(tweenObject);
+                });
+            }
+
+        } else {
+            tweenObject = this.target.createTweenInfo(fromTo, option, true);
+        }
+
+        tweenAnimator.add(tweenObject);
+
+    };
+
+    /**
+     * Plays tween animation.
+     * @method play
+     * @member tau.animation.SimpleAnimation.prototype
+     * @private
+     */
+    SimpleAnimation.prototype.play = function() {
+        var i , len;
+        this.tweenAnimator.play();
+        if (this.parTweensGroup) {
+            for (i = 0, len = this.parTweensGroup.length; i < len; i++) {
+                this.parTweensGroup[i].play();
+            }
+        }
+    };
+
+    /**
+     * Stops tween animation.
+     * @method stop
+     * @member tau.animation.SimpleAnimation.prototype
+     * @private
+     */
+    SimpleAnimation.prototype.stop = function() {
+        var i , len;
+        this.tweenAnimator.stop();
+        if (this.parTweensGroup) {
+            for (i = 0, len = this.parTweensGroup.length; i < len; i++) {
+                this.parTweensGroup[i].stop();
+            }
+        }
+    };
+
+    /**
+     * Makes group of simpleAnimation.
+     * @constructor SimpleGroup
+     * @param {Array} t
+     * The target will be added Simple group.
+     * @member tau.animation.SimpleAnimationGroup
+     * @private
+     */
+    function SimpleAnimationGroup(t) {
+        var i, simple;
+
+        this.target = [];
+        this.len = t.length;
+
+        for (i = 0; i < this.len; i++) {
+            if (!(simple = ObjectManager.getObject(t[i]).simpleAnimation)) {
+                this.target[i] = new ns.SimpleAnimation(t[i]);
+            } else {
+                this.target[i] = simple;
+            }
+
+        }
+    }
+
+    /**
+     * Adds animation to TweenObject
+     * @method add
+     * @param {Object} fromTo
+     * @param {Object} option
+     * The target will be added simple group
+     * @member tau.animation.SimpleGroup.prototype
+     * @private
+     */
+    SimpleAnimationGroup.prototype.add = function(fromTo, option) {
+        var completedCnt = 0,
+            self = this;
+
+        ns.AnimationUtil.checkStagger(this.target, option, function(t, o, idx) {
+
+            if (option.onComplete) {
+                o.onComplete = function() {
+                    completedCnt++;
+                    if (completedCnt === self.len) {
+                        t.tweenAnimator.getCurrentTweenInfo().completeCallback.on(option.onComplete);
+                    }
+                };
+            }
+
+//            t.simpleAnimation.add(fromTo, o);
+            t.add(fromTo, o);
+
+        });
+    };
+
+    /**
+     * Plays animation.
+     * @method play
+     * The target will be added simple group
+     * @member tau.animation.SimpleAnimationGroup.prototype
+     * @private
+     */
+    SimpleAnimationGroup.prototype.play = function() {
+        var i;
+
+        for (i = 0; i < this.len; i++) {
+            this.target[i].play();
+        }
+    };
+
+    /**
+     * Stop animation.
+     * @method play
+     * The target will be added simple group
+     * @member tau.animation.SimpleAnimationGroup.prototype
+     * @private
+     */
+    SimpleAnimationGroup.prototype.stop = function() {
+        var i;
+
+        for (i = 0; i < this.len; i++) {
+            this.target[i].stop();
+        }
+    };
+
+    ns.SimpleAnimation = SimpleAnimation;
+    ns.SimpleAnimationGroup = SimpleAnimationGroup;
+    ns.SimpleAnimationMixinObject = SimpleAnimationMixinObject;
+
+})(window, ns, ns.base);
+
+/*
+ * # SimpleMixin
+ *
+ * Creates mixin object.
+ * If user animate pure DOM such as div, SimpleMixin is going to make appropriate target object.
+ *
+ * @class ns.SimpleMixin
+ */
+(function(window, ns) {
+    'use strict';
+    var SimpleAnimationMixinObject = ns.SimpleAnimationMixinObject;
+
+    /**
+     * Returns target after mixin APIs.
+     * @method extendAnimation
+     * @param {Object} target
+     * @param {Object|undefined} getElementFn
+     * @return {Object}
+     * @member ns.SimpleMixin
+     * @static
+     */
+    var mixin = function(target, getElementFn) {
+        var p;
+
+        if (target.prototype !== undefined) {
+            (p = isProperty(target.prototype)) && throwMixinException(p);
+
+            for (var i in SimpleAnimationMixinObject) {
+                target.prototype[i] = SimpleAnimationMixinObject[i];
+
+            }
+        } else if (target instanceof Object) {
+            (p = isProperty(target)) && throwMixinException(p);
+
+            for (var i in SimpleAnimationMixinObject) {
+                if (SimpleAnimationMixinObject.hasOwnProperty(i)) {
+                    target[i] = SimpleAnimationMixinObject[i];
+                }
+            }
+        } else {
+            throwMixinException();
+        }
+        return target;
+    };
+
+    function isProperty(t) {
+        var propertyTest = ['tween', 'stop', 'transform', 'simpleAnimation'],
+            i, len;
+
+        for (i = 0, len = propertyTest.length; i < len; i++) {
+            if (t.hasOwnProperty(propertyTest[i])) {
+                return propertyTest[i];
+            }
+        }
+
+        return false;
+
+    }
+
+    function throwMixinException(p) {
+        var message = 'Function or Object can apply Mixin';
+        (p !== undefined) ? (message += ': \"' + p + '\" is overrided.') : (message += '.');
+
+        console.warn(message);
+
+        //throw "CannotTauAnimationMixinException";
+    }
+
+    ns.SimpleMixin = mixin;
+})(window, ns);
+
+(function(window, ns) {
+    'use strict';
+
+    var ObjectManager = ns.ObjectManager.getInstance();
+
+    /**
+     * Returns animation target object
+     * @method target
+     * @param {String} str
+     * The str indicate ID or class name for selecting HTML element
+     * @member ns.Target
+     * @return {Target} Target Object
+     * @public
+     * @class ns.Target
+     */
+
+    ns.SimpleMixin(ns.DomObject);
+
+    ns.target = function(str) {
+        if (typeof str === 'string') {
+            var s = str.slice(0, 1), c = str.slice(1),
+                result;
+
+            if (s === '.') {
+                result = document.getElementsByClassName(c);
+                if (!result.tween) {  // TODO: not mixin
+                    ns.SimpleMixin(result, function() {
+                        return result
+                    });
+                }
+            } else if (s === '#') {
+                result = document.getElementById(c);
+                result = ObjectManager.getObject(result);
+            } else {
+
+            }
+        } else {
+            if (str instanceof window.HTMLElement) {
+                result = ObjectManager.getObject(str);
+            } else {
+
+            }
+        }
+
+        return result;
+    };
+
+    //checking whether jQuery is loaded or not.
+    //if (window.jQuery && window.$) {
+    //    ns.SimpleMixin($, $.get);
+    //} else {
+    //    window.$ = ns.$;
+    //}
+
+})(window, ns);
+
+})(window);
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/animation/tau.animation.min.js b/d2d_app/client/lib/tau/animation/tau.animation.min.js
new file mode 100644 (file)
index 0000000..baba450
--- /dev/null
@@ -0,0 +1,2 @@
+(function(t){!t.tau&&(t.tau={});var e=t.tau.animation={};(function(t,e){(function(){for(var e=0,i=["ms","moz","webkit","o"],a=0;i.length>a&&!t.requestAnimationFrame;++a)t.requestAnimationFrame=t[i[a]+"RequestAnimationFrame"],t.cancelAnimationFrame=t[i[a]+"CancelAnimationFrame"]||t[i[a]+"CancelRequestAnimationFrame"];void 0===t.requestAnimationFrame&&(t.requestAnimationFrame=function(i){var a=Date.now(),n=Math.max(0,16-(a-e)),r=t.setTimeout(function(){i(a+n)},n);return e=a+n,r}),t.cancelAnimationFrame=t.cancelAnimationFrame||function(e){t.clearTimeout(e)}})(),function(t,e){t.Uint8Array.prototype.setValue=function(){for(var t=0,e=this.length;e>t;t++){if(void 0===arguments[t])return;this[t]=arguments[t]}},e.getTime=function(){return t.performance?t.performance.now?function(){return t.performance.now()}:t.performance.webkitNow?function(){return t.performance.webkitNow()}:function(){return(new Date).getTime()}:function(){return(new Date).getTime()}}()}(t,e);var i={ENUM:{NODETYPE:{GROUP:1,ANIMATION:2},GROUPTYPE:{SEQUENCE:4,PARALLEL:8}},forEach:function(t,e){for(var i=0,a=t&&t.length;a>i;i++){var n=t[i];e(n,i)}},copy:function(t,e){e=e||{};for(var i in t)t.hasOwnProperty(i)&&"$$"!==i.substr(0,2)&&(e[i]=t[i]);return e},arrayCopy:function(t,i){var a,n=t.length;if(void 0!==n)for(void 0===i&&(i=t instanceof Uint8Array?new Uint8Array(n):[]),a=0;n>a;a++)i[a]="string"!=typeof t[a]&&void 0!==t[a].length?e.base.arrayCopy(t[a]):t[a];else i=t;return i},deepCopy:function(t,e){if("object"==typeof t){e=e||{},t.length!==void 0&&(t instanceof Array?e=[]:t instanceof Uint8Array&&(e=new Uint8Array(t.length)));for(var i in t)"object"==typeof t[i]?e[i]=this.deepCopy(t[i]):"string"==typeof t[i]?e[i]=t[i]:"number"==typeof t[i]?e[i]=t[i]:"boolean"==typeof t[i]&&(e[i]=1==t[i]?!0:!1)}else e=t;return e},singleTon:function(t){var e={};return e.getInstance=function(){return void 0===this._singleton&&(this._singleton=new t),this._singleton},e},isNumber:function(t){return"number"==typeof t},isFunction:function(t){return"function"==typeof t},isObject:function(t){return t instanceof Object},isArray:function(t){return t instanceof Array},selector:function(t){var e,i=t.slice(0,1),a=t.slice(1);return"."===i?e=document.getElementsByClassName(a):"#"===i&&(e=document.getElementById(a)),e}};i.WeakMap=function(){this.keys=[],this.values=[],this.i=0},i.WeakMap.prototype.del=function(t){return this.has(t)&&(this.keys.splice(this.i,1),this.values.splice(this.i,1)),this.i>-1},i.WeakMap.prototype.get=function(t,e){return this.has(t)?this.values[this.i]:e},i.WeakMap.prototype.has=function(t){if(t!==Object(t))throw new TypeError("not a non-null object");return this.i=Array.prototype.indexOf.call(this.keys,t),this.i>-1},i.WeakMap.prototype.set=function(t,e){this.has(t)?this.values[this.i]=e:this.values[this.keys.push(t)-1]=e},i.WeakMap.prototype.getKey=function(){return this.keys};var a=!1,n=/xyz/.test(function(){})?/\b_super\b/:/.*/;i.Class=function(){},i.Class.extend=function(t){function e(){return!a&&this._init?this._init.apply(this,arguments):void 0}var i=this.prototype,r=t.static;a=!0;var o=new this;a=!1;for(var s in t)"static"!==s&&(o[s]="function"==typeof t[s]&&"function"==typeof i[s]&&n.test(t[s])?function(t,e){return function(){var a=this._super;this._super=i[t];var n=e.apply(this,arguments);return this._super=a,n}}(s,t[s]):t[s]);if(e.prototype=o,e.prototype.constructor=e,e.extend=arguments.callee,r)for(var c in r)r.hasOwnProperty(c)&&(e[c]=r[c]);return e},e.base=i})(t,e),function(t,e){"use strict";var i=e.base.Class.extend({_init:function(){this.now=e.getTime,this._frameId=null,this.animators=[],this.animatorIdx=0},tickOn:function(){var i=this;(function a(){i._frameId=t.requestAnimationFrame(a);var n,r=e.getTime();for(n=0;i.animatorIdx>n;n++)i.animators[n].tick(r)})()},tickOff:function(){this._frameId&&(t.cancelAnimationFrame(this._frameId),this._frameId=null)},__on:function(t){0>this.animators.indexOf(t)&&(this.animators[this.animatorIdx]=t,this.animatorIdx++,null===this._frameId&&this.tickOn())},__off:function(t){var e=this.animators.indexOf(t);e>=0&&(this.animators.splice(e,1),this.animatorIdx--,0===this.animatorIdx&&this.tickOff())}});e.Ticker=e.base.singleTon(i)}(t,e),function(t,e){"use strict";function i(){this.regExpCubicBezier=/cubic-bezier\s*\(\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*,\s*([\d\.]+)\s*\)/}function a(t,e,i,a){return function(t){var i=1-t,n=3*i,r=t*t,o=r*t,s=n*t*i,c=n*r;return s*e+c*a+o}}function n(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}var r;r=i.prototype,r.ease=a(.25,.1,.25,1),r.easeOut=a(0,0,.58,1),r.easeInOut=a(.42,0,.58,1),r.easeIn=a(.42,0,1,1),r.sineIn=a(.47,0,.745,.715),r.sineOut=a(.39,.575,.565,1),r.sineInOut=a(.445,.05,.55,.95),r.expoIn=a(.95,.05,.795,.035),r.expoOut=a(.19,1,.22,1),r.expoInOut=a(1,0,0,1),r.circIn=a(.6,.04,.98,.335),r.circOut=a(.075,.82,.165,1),r.circInOut=a(.785,.135,.15,.86),r.backIn=a(.6,-.28,.735,.045),r.backOut=a(.175,.885,.32,1.275),r.backInOut=a(.68,-.55,.265,1.55),r.zoomInDown=a(.55,.055,.675,.19),r.bounce1=a(.215,.61,.355,1),r.bounce2=a(.755,.05,.855,.06),r.linear=function(t){return t},r.cubicIn=function(t){return t*t*t},r.cubicOut=function(t){return--t*t*t+1},r.cubicInOut=function(t){return.5>t?4*t*t*t:(t-1)*(2*t-2)*(2*t-2)+1},r.quadIn=function(t){return t*t},r.quadOut=function(t){return t*(2-t)},r.quadInOut=function(t){return.5>t?2*t*t:-1+(4-2*t)*t},r.quartIn=function(t){return t*t*t*t},r.quartOut=function(t){return 1- --t*t*t*t},r.quartInOut=function(t){return.5>t?8*t*t*t*t:1-8*--t*t*t*t},r.quintIn=function(t){return t*t*t*t*t},r.quintOut=function(t){return 1+--t*t*t*t*t},r.quintInOut=function(t){return.5>t?16*t*t*t*t*t:1+16*--t*t*t*t*t},r.bounceOut=function(t){return n(t)},r.bounceIn=function(t){return 1-i.prototype.bounceOut(1-t)},r.bounceInOut=function(t){return.5>t?.5*i.prototype.bounceIn(2*t):.5*i.prototype.bounceOut(2*t-1)+.5};var o=2*Math.PI,s=.3/o*Math.asin(1);r.elasticIn=function(t){return 0===t||1===t?t:-(Math.pow(2,10*(t-=1))*Math.sin((t-s)*o/.3))},r.elasticOut=function(t){return 0===t||1===t?t:Math.pow(2,-10*t)*Math.sin((t-s)*o/.3)+1},r.elasticInOut=function(t){return 1>(t*=2)?-.5*Math.pow(2,10*(t-=1))*Math.sin((t-s)*o/.3):.5*Math.pow(2,-10*(t-=1))*Math.sin((t-s)*o/.3)+1},e.Ease=e.base.singleTon(i)}(t,e),function(t,e){"use strict";var i=e.Ticker.getInstance(),a=e.Ease.getInstance(),n={STOP:"stop",PAUSE:"pause",RUN:"running"},r={FORWARD:!0,REVERSE:!1},o=function(){var t=0,e=0,i=[];return{add:function(t){i[e]=t,e++},next:function(){return e>t?(t++,i[t-1]):!1},cur:function(){return t},rewind:function(){t=0},get:function(t){return void 0===t?i:i[t]},length:function(){return e},hasNext:function(){return e>t},clear:function(){0!==e&&e>=t&&i.splice(0,t),t=0,e=i.length},allClear:function(){i=[],t=e=0}}},s=function(){var t=[],e=0;return{on:function(i){t[e]=i,e++},onFront:function(i){t.unshift(i),e++},emit:function(){for(var i=0;e>i;i++)t[i].apply(null,arguments)},remove:function(i){for(var a=0;e>a;a++)t[a]===i&&(t[a].splice(a,1),e--)},getLength:function(){return e},removeAll:function(){t=[],e=0}}},c=e.base.Class.extend({_init:function(t,e){this.tweenQueue=o(),this.tweenInfo=null,this._direction=r.FORWARD,this._state=n.STOP,this._isTick=!1,this.isTweenInfo=!1,t&&this.add(t,e),this._startTime=this._lastTime=this._playTime=this._previousTime=0,this._totalTime=this._duration+this._delay,this._changedDirection=!1,this._isCache=!1},tick:function(t){if(this._state===n.RUN){var e=t,i=e-this._playTime;if(this._previousTime=e,0>i)return;this._duration>=i?(this.tweenInfo.progress=i/(this._duration||1),this._update()):(1!==this.tweenInfo.progress&&(this.tweenInfo.progress=1,this._update()),e>=this._lastTime&&this._complete())}},play:function(){this._state!==n.RUN&&(this._state===n.PAUSE?(this._direction!==r.FORWARD&&(this._direction=r.FORWARD,this._changedDirection=!0),this.resume()):(this._direction=r.FORWARD,this._play()))},reverse:function(){this._state!==n.RUN&&(this._state===n.PAUSE?(this._direction!==r.REVERSE&&(this._direction=r.REVERSE,this._changedDirection=!0),this.resume()):(this._direction=r.REVERSE,this._play()))},stop:function(){this._state!==n.STOP&&(this._stopTween(),this.tweenQueue.allClear())},pause:function(){this._state===n.RUN&&(this._state=n.PAUSE)},resume:function(t){var i=e.getTime();if(this._state===n.PAUSE){if(this._changedDirection||void 0!==t&&t!==this._direction)void 0!==t&&(this._direction=t),this._lastTime=i+this._previousTime-this._playTime,this._playTime=this._lastTime-this._duration,this._startTime=this._playTime-this._delay,this._changedDirection=!1;else{var a=i-this._previousTime;this._startTime+=a,this._playTime+=a,this._lastTime+=a}this._state=n.RUN}},seek:function(t){var e=t*this._totalTime-this._delay;e>=0&&this._update(e/this._duration)},getSeek:function(t,e){var i,a,n,t,r=this.tweenInfo.name,o=this.tweenInfo.to,s=this.tweenInfo.from;for(e&&(t=t*this._totalTime-this._delay),i=0;a=r[i];i++)this.cur[a]&&(n=this.cur[a].length)?(void 0===this.cur[a]&&(this.cur[a]=[]),this._calculateTween(this.cur[a],o[a],s[a],t)):this.cur[a]=(o[a]-s[a])*this._ease(t)+s[a];return this.cur},setStartTime:function(t){this._startTime=t},replay:function(){this._update(0),this._start()},duration:function(t){this._duration=e.base.isNumber(t)?t:1e3},delay:function(t){this._delay=e.base.isNumber(t)?t:0},ease:function(t){this._ease=e.base.isFunction(a[t])?a[t]:a.linear},loop:function(t){this._loop=e.base.isNumber(t)?t:1},add:function(t,e){var i;return void 0===e?(i=t,i.startCallback=s(),i.completeCallback=s(),i.progress=0):(i={fromTo:{},name:[],progress:0,startCallback:s(),completeCallback:s()},i.option=e),i.option.onStart&&i.startCallback.on(i.option.onStart),i.option.onComplete&&i.completeCallback.on(i.option.onComplete),this.tweenQueue.add(i),1===this.tweenQueue.length()&&(this.tweenQueue.next(),this.initTween(i),this.isTweenInfo=!0),i},setRender:function(t){this.render=t},setUpdateTarget:function(t){this.cur=t},getState:function(){return this._state},getCurrentTweenInfo:function(){return this.tweenInfo},nextTweenInfo:function(){return this.tweenQueue.next()},getLastTweenInfo:function(){return this.tweenQueue.get(this.tweenQueue.length()-1)},getFirstTweenInfo:function(){return this.tweenQueue.get(0)},initTween:function(t){var i=t.option;this.tweenInfo=t,this.cur=void 0!==this.cur?this.cur:void 0!==i._cur?i._cur:{},this.option=i,this._onUpdate=i.onUpdate,e.base.isObject(i)?(this.duration(i.duration),this.ease(i.ease),this.delay(i.delay),this.loop(i.loop),this._reverseDelay=i.reverseDelay||0):(this._duration=1e3,this._delay=0,this._loop=1,this._ease=a.linear,this._reverseDelay=0),this._loopCnt=this._loop},tweenQueueCache:function(t){"boolean"==typeof t&&(this._isCache=t)},_play:function(){this._state===n.PAUSE?this.resume():this._state===n.STOP&&this._start()},_start:function(){this._state=n.RUN,this._startTime=this._startTime||e.getTime(),this._playTime=this._startTime+(this._direction?this._delay:0),this._lastTime=this._playTime+this._duration+(this._direction?0:this._delay)+this._reverseDelay,this.tweenInfo.startCallback.emit(),this._isTick||(i.__on(this),this._isTick=!0)},_update:function(t){var e,i,a,n=this.tweenInfo.name,o=this.tweenInfo.fromTo;for(this.tweenInfo.progress=void 0!==t?t:this._direction===r.REVERSE?1-this.tweenInfo.progress:this.tweenInfo.progress,e=0;i=n[e];e++)o[i][0]&&(a=o[i][0].length)?(void 0===this.cur[i]&&(this.cur[i]=[]),this._calculateTween(this.cur[i],o[i][0],o[i][1])):this.cur[i]=(o[i][1]-o[i][0])*this._ease(this.tweenInfo.progress)+o[i][0];this.render&&this.render.call(this.cur,this.tweenInfo),this._onUpdate&&this._onUpdate.call(this.cur,this.tweenInfo)},_calculateTween:function(t,e,i,a){var n,r;for(void 0===a&&(a=this.tweenInfo.progress),n=0,r=i.length;r>n;n++)"number"==typeof i[n]?t[n]=(i[n]-e[n])*this._ease(a)+e[n]:"string"==typeof i[n]?t[n]=i[n]:(void 0===t[n]&&(t[n]=[]),this._calculateTween(t[n],e[n],i[n]))},_complete:function(){var t;this.setStartTime(null),this.isTweenInfo=!1,this.tweenInfo.completeCallback.emit(),--this._loopCnt>0?this.replay():!this.isTweenInfo&&(t=this.tweenQueue.next())?(this.initTween(t),this._isCache||this.tweenQueue.clear(),this._start()):this.isTweenInfo?this._start():(this._stopTween(),this.option._stackTweensFlag?(this.tweenQueue.rewind(),t=this.tweenQueue.next(),this.initTween(t)):this.tweenQueue.allClear())},_stopTween:function(){this._state=n.STOP,this._startTime=null,i.__off(this),this._isTick=!1}});e.TweenAnimator=e.Tween=c}(t,e),function(t,e,i){"use strict";var a=e.base.Class.extend({_init:function(){this.init()},init:function(){this.translateX=0,this.translateY=0,this.translateZ=0,this.rotateX=0,this.rotateY=0,this.rotateZ=0,this.skewX=0,this.skewY=0,this.scaleX=1,this.scaleY=1},copy:function(t){this.translateX=t.translateX,this.translateY=t.translateY,this.translateZ=t.translateZ,this.rotateX=t.rotateX,this.rotateY=t.rotateY,this.rotateZ=t.rotateZ,this.skewX=t.skewX,this.skewY=t.skewY,this.scaleX=t.scaleX,this.scaleY=t.scaleY},set:function(t){t instanceof Array&&(this.translateX=i.isNumber(t[0])?t[0]:0,this.translateY=i.isNumber(t[1])?t[1]:0,this.translateZ=i.isNumber(t[2])?t[2]:0,this.rotateX=i.isNumber(t[3])?t[3]:0,this.rotateY=i.isNumber(t[4])?t[4]:0,this.rotateZ=i.isNumber(t[5])?t[5]:0,this.scaleX=i.isNumber(t[6])?t[6]:1,this.scaleY=i.isNumber(t[7])?t[7]:1,this.skewX=i.isNumber(t[8])?t[8]:0,this.skewY=i.isNumber(t[9])?t[9]:0)}});e.Transform=a}(t,e,e.base),function(t,e,i){"use strict";var a={aqua:new Uint8Array([0,255,255]),lime:new Uint8Array([0,255,0]),silver:new Uint8Array([192,192,192]),black:new Uint8Array([0,0,0]),maroon:new Uint8Array([128,0,0]),teal:new Uint8Array([0,128,128]),blue:new Uint8Array([0,0,255]),navy:new Uint8Array([0,0,128]),white:new Uint8Array([255,255,255]),fuchsia:new Uint8Array([255,0,255]),olive:new Uint8Array([128,128,0]),yellow:new Uint8Array([255,255,0]),orange:new Uint8Array([255,165,0]),gray:new Uint8Array([128,128,128]),purple:new Uint8Array([128,0,128]),green:new Uint8Array([0,128,0]),red:new Uint8Array([255,0,0]),pink:new Uint8Array([255,192,203]),cyan:new Uint8Array([0,255,255]),transparent:new Uint8Array([255,255,255,0])},n=i.Class.extend({_init:function(){var t=this,e=["borderWidth","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","marginTop","marginRight","marginBottom","marginLeft","paddingTop","paddingRight","paddingBottom","paddingLeft","width","height","top","left","clipTop","clipBottom","clipRight","clipLeft","fontSize","lineHeight"];e.forEach(function(e){t[e]=t._unit.bind(t)});var i=["backgroundPosition","backgroundSize"];i.forEach(function(e){t[e]=t._arrayUnit.bind(t)});var a=["border","borderTop","borderRight","borderLeft","borderBottom"];a.forEach(function(e){t[e]=function(i){var a,n={};return a=t._blank(i),n[e+"Width"]=a[0],n[e+"Style"]="none"===a[1]?"solid":a[1],n[e+"Color"]=a[2],n}});var n=["backgroundColor","color","borderColor","borderTopColor","borderRightColor","borderLeftColor","borderBottomColor"];n.forEach(function(e){t[e]=t._color});var r=["margin","padding"];r.forEach(function(e){t[e]=function(i){var a=t._blank(i),n={};return 4===a.length?(n[e+"Top"]=a[0],n[e+"Right"]=a[1],n[e+"Bottom"]=a[2],n[e+"Left"]=a[3]):3===a.length?(n[e+"Top"]=a[0],n[e+"Right"]=a[1],n[e+"Bottom"]=a[2],n[e+"Left"]=a[1]):2===a.length?(n[e+"Top"]=a[0],n[e+"Right"]=a[1],n[e+"Bottom"]=a[0],n[e+"Left"]=a[1]):1===a.length&&(n[e+"Top"]=a[0],n[e+"Right"]=a[0],n[e+"Bottom"]=a[0],n[e+"Left"]=a[0]),n}});var o=["boxShadow","textShadow"];o.forEach(function(e){t[e]=function(e){var i,a,n,r,o,s=[],c=0,l=/rgb\([0-9]+[\, |\s]+[0-9]+[\, |\s]+[0-9]+\)/g;for(s=e.match(l)||[],e=e.replace(l,"rgb"),e=e.split(","),i=0,n=e.length;n>i;i++){for(e[i].match("rgb")&&s[c]&&(e[i]=e[i].replace("rgb",s[c]),c++),e[i]=t._blank(e[i]),o=e[i].length-1,(r=t._color(e[i][0]))?(e[i].splice(0,1),e[i].push(r)):r=t._color(e[i][o]),a=0;o>a;a++)e[i][a]=t._unit(e[i][a]);e[i][a]=r}return e}})},opacity:function(t){return parseFloat(t)},clip:function(t){var e=t.replace(/\(|\)|,/g," ").trim().split(/\s+/g),i=[];i[0]=e[0];for(var a=1;4>=a;a++)i[a]=this._unit(e[a]);return i},webkitClipPath:function(t){var e,i,a=[],n=t.replace(/\(|\)|,/g," ").trim().split(/\s+/g);for(a.push(n[0]),e=1,i=n.length;i>e;e++)a.push(this._unit(n[e]));return a},backgroundImage:function(t){return t.replace(/url\(|\)$/gi,"")},_arrayUnit:function(t){var e,i,a=t.trim().split(" ");for(e=0,i=a.length;i>e;e++)a[e]=this._unit(a[e]);return a},_unit:function(t){return"string"==typeof t?{number:this._getFloat(t),unit:this._getChar(t)||"px"}:{number:t,unit:"px"}},_color:function(t){var e,i,n,r,o,s,c,l;if(void 0===t||null===t)return console.log("invalid color"),!1;if(a[t])l=a[t];else if(t instanceof Array||t instanceof Uint8Array)l=new Uint8Array(t);else if(c=t.toLowerCase(),c=c.trim(),"r"===c.charAt(0)&&"g"===c.charAt(1)&&"b"===c.charAt(2)){if("a"===c.charAt(3)){for(r=c.replace(/rgba\(/g,"").replace(/\)/g,"").replace(/(\s*)/g,"").replace(/\,/g," ").split(" "),s=0,o=r.length-1;o>s;s++)r[s]=parseInt(r[s]);r[o]=parseFloat(r[o])}else for(r=c.replace(/rgb\(/g,"").replace(/\)/g,"").replace(/(\s*)/g,"").replace(/\,/g," ").split(" "),s=0,o=r.length;o>s;s++)r[s]=parseInt(r[s]);l=new Uint8Array(r)}else{if("#"!==c.charAt(0))return!1;4===c.length&&(e=c.charAt(1),i=c.charAt(2),n=c.charAt(3),c="#"+e+e+i+i+n+n),c=parseInt(c.substr(1),16),l=new Uint8Array(3),l.setValue(c>>16,255&c>>8,255&c)}return l},_getChar:function(t){var e=t.match(/[^0-9.-]/g),i="";return null!==e&&(i=e.join("")),i.replace(/\, /g,""),i},_getNum:function(t){return parseInt(t.match(/^[-]?\d+/g),10)},_getFloat:function(t){return parseFloat(t.match(/^[+-]?\d*(\.?\d*)/g))},_blank:function(t){return t.trim().replace(/\, /g,",").split(" ")}});e.CSSPropertyParser=i.singleTon(n)}(t,e,e.base),function(t,e,i){"use strict";var a=i.Class.extend({_init:function(){this.createColor(),this.createBorderStyle(),this.createBlankFunction(),this.createUnit(),this.createShadow()},opacity:function(t){return t.opacity},WebkitTransform:function(t){var e="";return e+=t.perspective?"perspective("+t.perspective+"px) ":"",e+="translate3d("+t.translateX+"px, "+t.translateY+"px, "+t.translateZ+"px) ",e+=t.rotateX?"rotateX("+t.rotateX+"deg) ":"",e+=t.rotateY?"rotateY("+t.rotateY+"deg) ":"",e+=t.rotateZ?"rotateZ("+t.rotateZ+"deg) ":"",e+=1!==t.scaleX?"scaleX("+t.scaleX+") ":"",e+=1!==t.scaleY?"scaleY("+t.scaleY+") ":"",e+=t.skewX?"skewX("+t.skewX+"deg) ":"",e+=t.skewY?"skewY("+t.skewY+"deg) ":""},createUnit:function(){function t(t,e){return"px"===e[this]?Math.round(t[this])+e[this]:t[this]+e[this]}function e(t,e){return t[this][0]+e[this][0]+" "+t[this][1]+e[this][1]}var i=this,a=["width","height","top","left"],n=["backgroundPosition","backgroundSize"];a.forEach(function(e){i[e]=t.bind(e)}),n.forEach(function(t){i[t]=e.bind(t)})},createColor:function(){var t=this,e=["borderColor","borderTopColor","borderRightColor","borderLeftColor","borderBottomColor","backgroundColor","color"];e.forEach(function(e){t[e]=t._rgbColor(e)})},createBorderStyle:function(){function t(t,e){var i=this+"Width",a=this+"Color",n=this+"Style";return t[i]+e[i]+" "+e[n]+" rgb("+t[a][0]+", "+t[a][1]+", "+t[a][2]+")"}function e(t,e){return t[this].toFixed(2)+e[this]}var i=this,a=["border","borderTop","borderRight","borderLeft","borderBottom"],n=["borderWidth","borderTopWidth","borderRightWidth","borderLeftWidth","borderBottomWidth"],r=["borderStyle","borderTopStyle","borderRightStyle","borderLeftStyle","borderBottomStyle"];a.forEach(function(e){i[e]=t.bind(e)}),r.forEach(function(t){i[t]=i._direct(t)}),n.forEach(function(t){i[t]=e.bind(t)})},createBlankFunction:function(){function t(t,e){var i=this+"Top",a=this+"Right",n=this+"Bottom",r=this+"Left";return t[i]+e[i]+" "+t[a]+e[a]+" "+t[n]+e[n]+" "+t[r]+e[r]}function e(t,e){return t[this]+e[this]}var i=this,a=["margin","padding"],n=["marginTop","marginRight","marginBottom","marginLeft","paddingTop","paddingRight","paddingBottom","paddingLeft","lineHeight","fontSize"];a.forEach(function(e){i[e]=t.bind(e)}),n.forEach(function(t){i[t]=e.bind(t)})},createShadow:function(){var t=this,e=["boxShadow","textShadow"];e.forEach(function(e){t[e]=function(t,i){var a,n,r,o,s=t[e],c=i[e],l="";for(a=0,r=s.length;r>a;a++){for(0!==a&&(l+=", "),n=0,o=s[a].length-1;o>n;n++)l+=s[a][n]+c[a][n]+" ";l+="rgb("+s[a][n][0]+","+s[a][n][1]+","+s[a][n][2]+") "}return l}})},clip:function(t){return t.clip[0]+"("+t.clip[1][0]+t.clip[1][1]+" "+t.clip[2][0]+t.clip[2][1]+" "+t.clip[3][0]+t.clip[3][1]+" "+t.clip[4][0]+t.clip[4][1]+")"},webkitClipPath:function(t,e){var i,a,n,r=t.webkitClipPath,o=e.webkitClipPath,s=e.webkitClipPathStyle;if("circle"===s)return o[0]+"("+r[0]+o[1]+" at "+r[1]+o[2]+" "+r[2]+o[3]+")";if("polygon"===s){for(n=s+"(",i=0,a=r.length;a>i;i+=2)n+=r[i]+o[i]+" "+r[i+1]+o[i+1],n+=i+1!==a-1?", ":")";return n}},_direct:function(t){return function(e){return e[t]}},_rgbColor:function(t){return function(e){return"rgb("+e[t][0]+", "+e[t][1]+", "+e[t][2]+")"}}});e.CssStringCreator=i.singleTon(a)}(t,e,e.base),function(t,e,i){"use strict";var a=e.CSSPropertyParser.getInstance(),n=i.Class.extend({_init:function(){var t,e,i,n,r,o,s,c=this;t=["backgroundColor","color","borderColor","borderTopColor","borderRightColor","borderLeftColor","borderBottomColor"],t.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_colorType")}}),e=["width","left","marginRight","marginLeft","paddingRight","paddingLeft","marginTop","marginBottom","paddingBottom","paddingTop","clipTop","clipBottom","clipRight","clipLeft","borderWidth","borderTopWidth","borderRightWidth","borderLeftWidth","borderBottomWidth","clipTop","clipBottom","clipRight","clipLeft"],e.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_unitType","width")}}),i=["height","top"],i.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_unitType","height")}}),n=["backgroundPosition","backgroundSize"],n.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_backgroundType")}}),r=["margin","padding"],r.forEach(function(t){c[t]=function(e){var i,n,r;if(2===e.animationFromTo[t].length){i=a[t](e.animationFromTo[t][0]),n=a[t](e.animationFromTo[t][1]);for(r in n)e.animationFromTo[r]=[i[r],n[r]],c[r](e)}else{n=a[t](e.animationFromTo[t]);for(r in n)e.animationFromTo[r]=n[r],c[r](e)}}}),o=["border","borderTop","borderRight","borderLeft","borderBottom"],o.forEach(function(t){c[t]=function(e){var i,n;2===e.animationFromTo[t].length?(i=a[t](e.animationFromTo[t][0]),n=a[t](e.animationFromTo[t][1]),e.animationFromTo[t+"Width"]=[i[t+"Width"],n[t+"Width"]],e.animationFromTo[t+"Color"]=[i[t+"Color"],n[t+"Color"]]):(n=a[t](e.animationFromTo[t]),e.animationFromTo[t+"Width"]=n[t+"Width"],e.animationFromTo[t+"Color"]=n[t+"Color"]),e.unit[t+"Style"]=n[t+"Style"],c[t+"Width"](e),c[t+"Color"](e)}}),o=["border","borderTop","borderRight","borderLeft","borderBottom"],o.forEach(function(t){c[t]=function(e){var i,n;2===e.animationFromTo[t].length?(i=a[t](e.animationFromTo[t][0]),n=a[t](e.animationFromTo[t][1]),e.animationFromTo[t+"Width"]=[i[t+"Width"],n[t+"Width"]],e.animationFromTo[t+"Color"]=[i[t+"Color"],n[t+"Color"]]):(n=a[t](e.animationFromTo[t]),e.animationFromTo[t+"Width"]=n[t+"Width"],e.animationFromTo[t+"Color"]=n[t+"Color"]),e.unit[t+"Style"]=n[t+"Style"],c[t+"Width"](e),c[t+"Color"](e)}}),s=["boxShadow","textShadow"],s.forEach(function(t){c[t]=function(e){c.settingCssAnimation(t,e,"_shadowType")}}),this.webkitClipPath=function(t){this.settingCssAnimation("webkitClipPath",t,"_webkitClipPathType")},this.fontSize=function(t){this.settingCssAnimation("fontSize",t,"_fontSizeType")},this.lineHeight=function(t){this.settingCssAnimation("lineHeight",t,"_unitType","lineHeight")},this.opacity=function(t){this.settingCssAnimation("opacity",t)},this.WebkitTransform=function(t,e){var i,a;"object"==typeof e.animationFromTo[t]&&2===e.animationFromTo[t].length?(i=e.animationFromTo[t][0],a=e.animationFromTo[t][1]):(i=e.target.cur[t],a=e.animationFromTo[t]),("translateX"===t||"translateY"===t||"translateZ"===t)&&("string"==typeof i&&(i=this._getTranslateValue(t,e,i)),"string"==typeof a&&(a=this._getTranslateValue(t,e,a))),e.fromTo[t]=[i,a],e.target.from[t]=a,e.name.push(t)}},settingCssAnimation:function(e,i,n,r){var o;o=i.fromTo[e]=[],"object"==typeof i.animationFromTo[e]&&2===i.animationFromTo[e].length?(o[0]=i.animationFromTo[e][0],o[1]=i.animationFromTo[e][1]):(o[0]=t.getComputedStyle(i.target.dom)[e],(""===o[0]||"auto"===o[0]||"none"===o[0]||void 0===o[0])&&(o[0]=this._exceptGetStyle(i.target.dom,e)),o[1]=i.animationFromTo[e]),o[0]=a[e](o[0]),o[1]=a[e](o[1]),n&&this[n]&&this[n](e,i,r),i.name.push(e)},unitArray:function(t,e,i){var a,n,r,o,s,c=[],l=[],u=[],p=e.fromTo[t];for(a=0,n=p[0].length;n>a;a++)r=p[0][a],o=p[1][a],r.unit!==o.unit&&(s="object"==typeof i&&i[a]?i[a]:i,this._convertUnit(e.target.dom,r,o,s,t)),c.push(r.number),l.push(o.number),u.push(o.unit);e.fromTo[t]=[c,l],e.unit[t]=u},_colorType:function(t,e){e.target.cur[t]=new Uint8Array(3)},_fontSizeType:function(t,e){var i=e.fromTo[t];isNaN(i[0].number)&&this._getStringFontNumber(i[0],e.target.dom),isNaN(i[1].number)&&this._getStringFontNumber(i[1],e.target.dom),this._unitType(t,e,"fontSize")},_backgroundType:function(t,e){1===e.fromTo[t][0].length&&e.fromTo[t][0].push({number:50,unit:"%"}),1===e.fromTo[t][1].length&&e.fromTo[t][1].push({number:50,unit:"%"}),this.unitArray(t,e,["width","height"])},_unitType:function(t,e,i){var a=e.fromTo[t][0],n=e.fromTo[t][1];return a.unit!==n.unit&&this._convertUnit(e.target.dom,a,n,i,t),e.unit[t]=n.unit,e.target.unit[t]=n.unit,e.fromTo[t][0]=a.number,e.fromTo[t][1]=n.number,!1},_webkitClipPathType:function(t,e){var i=e.fromTo[t];e.unit[t+"Style"]=i[1][0],i[0].splice(0,1),i[1].splice(0,1),this.unitArray(t,e,"width")},_shadowType:function(t,e){var a,n,r,o,s,c,l,u=e.fromTo[t][0],p=e.fromTo[t][1],h=[];for(e.unit[t]=h,o=0,l=p.length;l>o;o++){for(!u[o]&&(u[o]=[]),a=u[o],n=p[o],r=[],h.push(r),s=0,c=n.length-1;c>s;s++)r.push(n[s].unit),a[s]&&n[s].unit!==a[s].unit&&this._convertUnit(e.target.dom,a[s],n[s],"width",t),n[s]=n[s].number,a[s]=a[s]?a[s].number:0;a[c]||(a[c]=new Uint8Array(3))}e.cur[t]=i.deepCopy(p)},_exceptGetStyle:function(e,i){var a,n,r;return"left"===i?a=e.offsetLeft+"px":"top"===i?a=e.offsetTop+"px":"clip"===i?a="rect(0px 0px 0px 0px)":"boxShadow"===i?a="0px 0px 0px 0px black":"textShadow"===i?a="0px 0px 0px black":"backgroundPosition"===i?a="0px 0px":"backgroundSize"===i&&(n=this._getStyle(e,"backgroundImage"),t.aa=r=new Image,r.src=n,a=r.width&&r.height?r.width+"px "+r.height+"px":"0px 0px"),void 0===a&&(a="0px"),a},_getCriterionEm:function(t,e){return"fontSize"===e?16:this._getStyle(t,"fontSize").number||16},_getCriterionPercent:function(e,i,n){var r,o,s,c,l=e.parentNode;if("lineHeight"===n)return this._getStyle(e,"fontSize").number||16;if("backgroundPosition"===n)return s=this._getStyle(e,i).number,c=this._getBackgroundImageSize(e,i),s-c+1;if("backgroundSize"===n)return this._getStyle(e,i).number;for(r=a._getFloat(t.getComputedStyle(l)[i]);""===r&&l!==document.body;)l=l.parentNode,r=a._getFloat(t.getComputedStyle(l)[i]);return 0!==r||"width"!==i&&"height"!==i||(o=i.substring(0,1).toUpperCase()+i.substring(1),r=t["inner"+o]),r},_getStyle:function(e,i){var n=t.getComputedStyle(e)[i];return n=a[i](n)},_getBackgroundImageSize:function(t,e){var i,a,n=this._getStyle(t,"backgroundSize");return"auto"===n[0].unit?(i=this._getStyle(t,"backgroundImage"),a=new Image,a.src=i,void 0===e?[a.width,a.height]:a[e]):n["width"===e?0:1].number},_getStringFontNumber:function(t,e){var i=t.unit;"normal"===i||"initial"===i?(t.number=this._getStyle(e,"fontSize").number||16,t.unit="px"):"xx-small"===i?(t.number=.5625,t.unit="em"):"x-small"===i?(t.number=.625,t.unit="em"):"small"===i?(t.number=.8125,t.unit="em"):"medium"===i?(t.number=1,t.unit="em"):"large"===i?(t.number=1.125,t.unit="em"):"x-large"===i?(t.number=1.5,t.unit="em"):"xx-large"===i&&(t.number=2,t.unit="em")},_getTranslateValue:function(t,e,i){var n,r;return n=a._unit(i),"px"!==n.unit?"translateX"===t||"translateZ"===t?r=this._convertPx(e.target.dom,n.number,n.unit,"width"):"translateY"===t&&(r=this._convertPx(e.target.dom,n.number,n.unit,"height")):r=n.number,r},_convertUnit:function(t,e,i,a,n){"em"===i.unit?e.number=this._convertEm(t,e.number,e.unit,a,n):"%"===i.unit?e.number=this._convertPer(t,e.number,e.unit,a,n):"px"===i.unit?e.number=this._convertPx(t,e.number,e.unit,a,n):"cm"===i.unit?e.number=this._convertCm(t,e.number,e.unit,a,n):"pt"===i.unit&&(e.number=this._convertPt(t,e.number,e.unit,a,n))},_convertEm:function(t,e,i,a,n){var r=this._getCriterionEm(t,a,n);return 0===e?0:"px"===i?e/r:"%"===i?e/100*this._getCriterionPercent(t,a,n)/r:"cm"===i||"pt"===i?this._convertPx(t,e,i,a,n)/r:!1},_convertPer:function(t,e,i,a,n){var r=this._getCriterionPercent(t,a,n);return 0===e?0:"px"===i?100*(e/r):"em"===i?100*(e*this._getCriterionEm(t,a,n)/r):"cm"===i||"pt"===i?100*(this._convertPx(t,e,i,a,n)/r):!1},_convertPx:function(t,e,i,a,n){return 0===e?0:"%"===i?e/100*this._getCriterionPercent(t,a,n):"em"===i?e*e*this._getCriterionEm(t,a,n):"cm"===i?37.795*e:"pt"===i?1.3*e:!1},_convertCm:function(t,e,i,a,n){var r;return 0===e?0:(r="px"!==i?this._convertPx(t,e,i,a,n):e,.02646*r)},_convertPt:function(t,e,i,a,n){var r;return 0===e?0:(r="px"!==i?this._convertPx(t,e,i,a,n):e,.75*r)}});e.CssAnimationUtil=e.base.singleTon(n)}(t,e,e.base),function(t,e){var i={optionAnalyzer:function(t,e){var i;return void 0!==t?"number"==typeof t?(i=e&&"object"==typeof e?e:{},i.duration=t):"object"==typeof t&&(i=t):(i={},i.duration=1e3),i},checkStagger:function(t,i,a){var n,r,o;for(this.animations=[],n=0,r=t.length;r>n;n++)o=e.base.deepCopy(i),i.stagger&&(o.delay=i.stagger*n+(i.delay||0),o.reverseDelay=i.stagger*(r-n)),0!==n&&i.drag&&(o.duration+=i.drag*n),0===n&&i.onStart&&(o.onStart=i.onStart),a(t[n],o,n)},createKeyFrame:function(t,i,a){var n,r,o,s,c,l,u=[];for(n in t)u.push(parseFloat(n));for(u.sort(function(t,e){return t-e}),s=u[0],n=0,o=u.length-1;o>n;n++){l=e.base.deepCopy(i),c={};for(r in t[u[n+1]])c[r]=void 0!==t[u[n]][r]?[t[u[n]][r],t[u[n+1]][r]]:t[u[n+1]][r];l.duration=i.duration*(u[n+1]-s),s=u[n+1],0===n?(i.onStart&&(l.onStart=i.onStart),i.delay&&(l.delay=i.delay),l.reverseDelay=0):(i.delay&&(l.delay=0),i.stagger&&(l.delay=0),n===o-1?i.onComplete&&(l.onComplete=i.onComplete):l.reverseDelay=0),a(c,l,n)}},effectAnalyzer:function(t,i){var a,n,r,o,s,c=e.CssAnimationUtil.getInstance()._getCriterionPercent(t.dom,"width"),l=e.CssAnimationUtil.getInstance()._getCriterionPercent(t.dom,"height");if(a=i,t.dom.style.opacity=t.dom.style.opacity?t.dom.style.opacity:1,"pulse"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY},.5:{scaleX:1.05*t.cur.scaleX,scaleY:1.05*t.cur.scaleY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY}};else if("rollIn"===a)n={0:{translateX:-100+t.cur.translateX,rotateZ:-120+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{translateX:0+t.cur.translateX,rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}};else if("rollOut"===a)n={0:{opacity:1*t.dom.style.opacity},1:{translateX:200+t.cur.translateX,rotateZ:120+t.cur.rotateZ,opacity:0*t.dom.style.opacity}};else if("bounce"===a)n={0:{translateY:0+t.cur.translateY},.2:{translateY:0+t.cur.translateY},.4:{translateY:-30+t.cur.translateY},.5:{translateY:0+t.cur.translateY},.7:{translateY:-15+t.cur.translateY},.8:{translateY:0+t.cur.translateY},.9:{translateY:-4+t.cur.translateY},1:{translateY:0+t.cur.translateY}},r=["bounce1","bounce1","bounce2","bounce1","bounce2","bounce1","","bounce1"],o="center bottom";else if("bounceIn"===a)n={0:{scaleX:.3*t.cur.scaleX,scaleY:.3*t.cur.scaleY},.2:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY},.4:{scaleX:.9*t.cur.scaleX,scaleY:.9*t.cur.scaleY},.6:{scaleX:1.03*t.cur.scaleX,scaleY:1.03*t.cur.scaleY},.8:{scaleX:.97*t.cur.scaleX,scaleY:.97*t.cur.scaleY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY}},r=["bounce1","bounce1","bounce1","bounce1","bounce1","bounce1"];
+else if("bounceInDown"===a)n={0:{translateY:-3e3+t.cur.translateY,opacity:0*t.dom.style.opacity},.6:{translateY:25+t.cur.translateY,opacity:1*t.dom.style.opacity},.75:{translateY:-10+t.cur.translateY,opacity:1*t.dom.style.opacity},.9:{translateY:5+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity}},r=["bounce1","bounce1","bounce1","bounce1","bounce1"];else if("bounceInLeft"===a)n={0:{translateX:-3e3+t.cur.translateX,opacity:0*t.dom.style.opacity},.6:{translateX:25+t.cur.translateX,opacity:1*t.dom.style.opacity},.75:{translateX:-10+t.cur.translateX,opacity:1*t.dom.style.opacity},.9:{translateX:5+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity}},r=["bounce1","bounce1","bounce1","bounce1","bounce1"];else if("bounceInRight"===a)n={0:{translateX:3e3+t.cur.translateX,opacity:0*t.dom.style.opacity},.6:{translateX:-25+t.cur.translateX,opacity:1*t.dom.style.opacity},.75:{translateX:10+t.cur.translateX,opacity:1*t.dom.style.opacity},.9:{translateX:-5+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity}},r=["bounce1","bounce1","bounce1","bounce1","bounce1"];else if("bounceInUp"===a)n={0:{translateY:3e3+t.cur.translateY,opacity:0*t.dom.style.opacity},.6:{translateY:-25+t.cur.translateY,opacity:1*t.dom.style.opacity},.75:{translateY:10+t.cur.translateY,opacity:1*t.dom.style.opacity},.9:{translateY:-5+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity}},r=["bounce1","bounce1","bounce1","bounce1","bounce1"];else if("bounceOut"===a)n={.2:{opacity:0*t.dom.style.opacity,scaleX:.9*t.cur.scaleX,scaleY:.9*t.cur.scaleY},.5:{opacity:1*t.dom.style.opacity,scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY},1:{opacity:0*t.dom.style.opacity,scaleX:.3*t.cur.scaleX,scaleY:.3*t.cur.scaleY}};else if("bounceOutDown"===a)n={0:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity},.1:{translateY:10+t.cur.translateY,opacity:1*t.dom.style.opacity},.45:{translateY:-20+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{translateY:2e3+t.cur.translateY,opacity:0*t.dom.style.opacity}};else if("bounceOutLeft"===a)n={0:{translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity},.2:{translateX:20+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{translateX:-2e3+t.cur.translateX,opacity:0*t.dom.style.opacity}};else if("bounceOutRight"===a)n={0:{translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity},.2:{translateX:-20+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{translateX:2e3+t.cur.translateX,opacity:0*t.dom.style.opacity}};else if("bounceOutUp"===a)n={0:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity},.2:{translateY:-10+t.cur.translateY,opacity:1*t.dom.style.opacity},.45:{translateY:20+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{translateY:-2e3+t.cur.translateY,opacity:0*t.dom.style.opacity}};else if("zoomIn"===a)n={0:{scaleX:.3*t.cur.scaleX,scaleY:.3*t.cur.scaleY,opacity:0*t.dom.style.opacity},.5:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity}};else if("zoomInDown"===a)n={0:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,opacity:0*t.dom.style.opacity,translateX:0+t.cur.translateX,translateY:-1e3+t.cur.translateY},.6:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX,translateY:60+t.cur.translateY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX,translateY:0+t.cur.translateY}},r=["zoomInDown","backOut"];else if("zoomInLeft"===a)n={0:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,opacity:0*t.dom.style.opacity,translateX:-1e3+t.cur.translateX},.6:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateX:10+t.cur.translateX},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateX}},r=["zoomInDown","backOut"];else if("zoomInRight"===a)n={0:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,opacity:0*t.dom.style.opacity,translateX:1e3+t.cur.translateX,translateY:t.cur.translateY},.6:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateX:-10+t.cur.translateX,translateY:t.cur.translateY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateY:t.cur.translateY}},r=["zoomInDown","backOut"];else if("zoomInUp"===a)n={0:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,opacity:0*t.dom.style.opacity,translateY:1e3+t.cur.translateY},.6:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateY:-60+t.cur.translateY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY}},r=["zoomInDown","backOut"];else if("zoomOut"===a)n={0:{opacity:1*t.dom.style.opacity},.6:{scaleX:.3*t.cur.scaleX,scaleY:.3*t.cur.scaleY,opacity:0*t.dom.style.opacity},1:{opacity:0*t.dom.style.opacity}};else if("zoomOutDown"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity},.4:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,translateY:-60+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,translateY:2e3+t.cur.translateY,opacity:0*t.dom.style.opacity}},r=["zoomInDown","backOut"],o="center bottom";else if("zoomOutLeft"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity},.4:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,translateX:42+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,translateX:-2e3+t.cur.translateX,opacity:0*t.dom.style.opacity}},o="left center";else if("zoomOutRight"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,translateX:0+t.cur.translateX,opacity:1*t.dom.style.opacity},.4:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,translateX:-42+t.cur.translateX,opacity:1*t.dom.style.opacity},1:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,translateX:2e3+t.cur.translateX,opacity:0*t.dom.style.opacity}},o="right center";else if("zoomOutUp"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity},.4:{scaleX:.475*t.cur.scaleX,scaleY:.475*t.cur.scaleY,translateY:60+t.cur.translateY,opacity:1*t.dom.style.opacity},1:{scaleX:.1*t.cur.scaleX,scaleY:.1*t.cur.scaleY,translateY:-2e3+t.cur.translateY,opacity:0*t.dom.style.opacity}},r=["zoomInDown","backOut"],o="center bottom";else if("slideInDown"===a)n={0:{translateY:-1*l+t.cur.translateY},1:{translateY:0+t.cur.translateY}},s="visible";else if("slideInLeft"===a)n={0:{translateX:-1*c+t.cur.translateX},1:{translateX:0+t.cur.translateX}},s="visible";else if("slideInRight"===a)n={0:{translateX:1*c+t.cur.translateX},1:{translateX:0+t.cur.translateX}},s="visible";else if("slideInUp"===a)n={0:{translateY:1*l+t.cur.translateY},1:{translateY:0+t.cur.translateY}},s="visible";else if("slideOutDown"===a)n={0:{translateY:0+t.cur.translateY},1:{translateY:1*l+t.cur.translateY}},s="hidden";else if("slideOutLeft"===a)n={0:{translateX:0+t.cur.translateX},1:{translateX:-1*c+t.cur.translateX}},s="hidden";else if("slideOutRight"===a)n={0:{translateX:0+t.cur.translateX},1:{translateX:1*c+t.cur.translateX}},s="hidden";else if("slideOutUp"===a)n={0:{translateY:0+t.cur.translateY},1:{translateY:-1*l+t.cur.translateY}},s="hidden";else if("flash"===a)n={0:{opacity:1*t.dom.style.opacity},.25:{opacity:0*t.dom.style.opacity},.5:{opacity:1*t.dom.style.opacity},.75:{opacity:0*t.dom.style.opacity},1:{opacity:1*t.dom.style.opacity}};else if("rubberBand"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY},.3:{scaleX:1.25*t.cur.scaleX,scaleY:.75*t.cur.scaleY},.4:{scaleX:.75*t.cur.scaleX,scaleY:1.25*t.cur.scaleY},.5:{scaleX:1.15*t.cur.scaleX,scaleY:.85*t.cur.scaleY},.65:{scaleX:.95*t.cur.scaleX,scaleY:1.05*t.cur.scaleY},.75:{scaleX:1.05*t.cur.scaleX,scaleY:.95*t.cur.scaleY},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY}};else if("shake"===a)n={0:{translateX:0+t.cur.translateX},.1:{translateX:-10+t.cur.translateX},.2:{translateX:10+t.cur.translateX},.3:{translateX:-10+t.cur.translateX},.4:{translateX:10+t.cur.translateX},.5:{translateX:-10+t.cur.translateX},.6:{translateX:10+t.cur.translateX},.7:{translateX:-10+t.cur.translateX},.8:{translateX:10+t.cur.translateX},.9:{translateX:-10+t.cur.translateX},1:{translateX:0+t.cur.translateX}};else if("swing"===a)n={0:{rotateZ:0+t.cur.rotateZ},.2:{rotateZ:15+t.cur.rotateZ},.4:{rotateZ:-10+t.cur.rotateZ},.6:{rotateZ:5+t.cur.rotateZ},.8:{rotateZ:-5+t.cur.rotateZ},1:{rotateZ:0+t.cur.rotateZ}},o="top center";else if("tada"===a)n={0:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,rotateZ:0+t.cur.rotateZ},.15:{scaleX:.9*t.cur.scaleX,scaleY:.9*t.cur.scaleY,rotateZ:-3+t.cur.rotateZ},.3:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:3+t.cur.rotateZ},.4:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:-3+t.cur.rotateZ},.5:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:3+t.cur.rotateZ},.6:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:-3+t.cur.rotateZ},.7:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:3+t.cur.rotateZ},.8:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:-3+t.cur.rotateZ},.9:{scaleX:1.1*t.cur.scaleX,scaleY:1.1*t.cur.scaleY,rotateZ:3+t.cur.rotateZ},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,rotateZ:0+t.cur.rotateZ}};else if("wobble"===a)n={0:{translateX:0+t.cur.translateX,rotateZ:0+t.cur.rotateZ},.15:{translateX:c*-.25+t.cur.translateX,rotateZ:-5+t.cur.rotateZ},.3:{translateX:.2*c+t.cur.translateX,rotateZ:3+t.cur.rotateZ},.45:{translateX:c*-.15+t.cur.translateX,rotateZ:-3+t.cur.rotateZ},.6:{translateX:.1*c+t.cur.translateX,rotateZ:2+t.cur.rotateZ},.75:{translateX:c*-.05+t.cur.translateX,rotateZ:-1+t.cur.rotateZ},1:{translateX:0+t.cur.translateX,rotateZ:0+t.cur.rotateZ}};else if("jello"===a)n={0:{skewX:0+t.cur.skewX,skewY:0+t.cur.skewY},.22:{skewX:-12.5+t.cur.skewX,skewY:-12.5+t.cur.skewY},.33:{skewX:6.25+t.cur.skewX,skewY:6.25+t.cur.skewY},.44:{skewX:-3.125+t.cur.skewX,skewY:-3.125+t.cur.skewY},.55:{skewX:1.5625+t.cur.skewX,skewY:1.5625+t.cur.skewY},.66:{skewX:-.78125+t.cur.skewX,skewY:-.78125+t.cur.skewY},.77:{skewX:.390625+t.cur.skewX,skewY:.390625+t.cur.skewY},.88:{skewX:-.1953125+t.cur.skewX,skewY:-.1953125+t.cur.skewY},1:{skewX:0+t.cur.skewX,skewY:0+t.cur.skewY}},o="center";else if("fadeIn"===a)n={0:{opacity:0*t.dom.style.opacity},1:{opacity:1*t.dom.style.opacity}};else if("fadeInDown"===a)n={0:{translateY:-1*l+t.cur.translateY,opacity:0*t.dom.style.opacity},1:{translateY:0+t.cur.translateY,opacity:1*t.dom.style.opacity}};else if("fadeInDownBig"===a)n={0:{opacity:0*t.dom.style.opacity,translateY:-2e3+t.cur.translateY},1:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY}};else if("fadeInLeft"===a)n={0:{opacity:0*t.dom.style.opacity,translateX:-1*c+t.cur.translateX},1:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX}};else if("fadeInLeftBig"===a)n={0:{opacity:0*t.dom.style.opacity,translateX:-2e3+t.cur.translateX},1:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX}};else if("fadeInRight"===a)n={0:{opacity:0*t.dom.style.opacity,translateX:1*c+t.cur.translateX},1:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX}};else if("fadeInRightBig"===a)n={0:{opacity:0*t.dom.style.opacity,translateX:2e3+t.cur.translateX},1:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX}};else if("fadeInUp"===a)n={0:{opacity:0*t.dom.style.opacity,translateY:1*l+t.cur.translateY},1:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY}};else if("fadeInUpBig"===a)n={0:{opacity:0*t.dom.style.opacity,translateY:2e3+t.cur.translateY},1:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY}};else if("fadeOut"===a)n={0:{opacity:1*t.dom.style.opacity},1:{opacity:0*t.dom.style.opacity}};else if("fadeOutDown"===a)n={0:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY},1:{opacity:0*t.dom.style.opacity,translateY:1*l+t.cur.translateY}};else if("fadeOutDownBig"===a)n={0:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY},1:{opacity:0*t.dom.style.opacity,translateY:2e3+t.cur.translateY}};else if("fadeOutLeft"===a)n={0:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX},1:{opacity:0*t.dom.style.opacity,translateX:-1*c+t.cur.translateX}};else if("fadeOutLeftBig"===a)n={0:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX},1:{opacity:0*t.dom.style.opacity,translateX:-2e3+t.cur.translateX}};else if("fadeOutRight"===a)n={0:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX},1:{opacity:0*t.dom.style.opacity,translateX:1*c+t.cur.translateX}};else if("fadeOutRightBig"===a)n={0:{opacity:1*t.dom.style.opacity,translateX:0+t.cur.translateX},1:{opacity:0*t.dom.style.opacity,translateX:2e3+t.cur.translateX}};else if("fadeOutUp"===a)n={0:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY},1:{opacity:0*t.dom.style.opacity,translateY:-1*l+t.cur.translateY}};else if("fadeOutUpBig"===a)n={0:{opacity:1*t.dom.style.opacity,translateY:0+t.cur.translateY},1:{opacity:0*t.dom.style.opacity,translateY:-2e3+t.cur.translateY}};else if("flip"===a)n={0:{rotateY:-360+t.cur.rotateY,perspective:400},.4:{rotateY:-190+t.cur.rotateY,translateZ:150+t.cur.translateZ,perspective:400},.5:{rotateY:-170+t.cur.rotateY,translateZ:150+t.cur.translateZ,perspective:400},.8:{scaleX:.95*t.cur.scaleX,scaleY:.95*t.cur.scaleY,perspective:400},1:{scaleX:1*t.cur.scaleX,scaleY:1*t.cur.scaleY,rotateY:0+t.cur.rotateY,translateZ:0+t.cur.translateZ,perspective:400}},r=["easeIn","easeIn","easeIn","easeIn","easeIn"];else if("flipInX"===a)n={0:{rotateX:90+t.cur.rotateX,perspective:400,opacity:0*t.dom.style.opacity},.4:{rotateX:-20+t.cur.rotateX,perspective:400,opacity:1*t.dom.style.opacity},.6:{rotateX:10+t.cur.rotateX,perspective:400,opacity:1*t.dom.style.opacity},.8:{rotateX:-5+t.cur.rotateX,perspective:400,opacity:1*t.dom.style.opacity},1:{rotateX:0+t.cur.rotateX,perspective:400,opacity:1*t.dom.style.opacity}},r=["easeIn","easeIn","easeIn","easeIn","easeIn"];else if("flipInY"===a)n={0:{rotateY:90+t.cur.rotateY,perspective:400,opacity:0*t.dom.style.opacity},.4:{rotateY:-20+t.cur.rotateY,perspective:400,opacity:1*t.dom.style.opacity},.6:{rotateY:10+t.cur.rotateY,perspective:400,opacity:1*t.dom.style.opacity},.8:{rotateY:-5+t.cur.rotateY,perspective:400,opacity:1*t.dom.style.opacity},1:{rotateY:0+t.cur.rotateY,perspective:400,opacity:1*t.dom.style.opacity}},r=["easeIn","easeIn","easeIn","easeIn","easeIn"];else if("flipOutX"===a)n={0:{perspective:400},.3:{perspective:400,rotateX:-20+t.cur.rotateX,opacity:1*t.dom.style.opacity},1:{perspective:400,rotateX:90+t.cur.rotateX,opacity:0*t.dom.style.opacity}};else if("flipOutY"===a)n={0:{perspective:400},.3:{perspective:400,rotateY:-15+t.cur.rotateY,opacity:1*t.dom.style.opacity},1:{perspective:400,rotateY:90+t.cur.rotateY,opacity:0*t.dom.style.opacity}};else if("lightSpeedIn"===a)n={0:{translateX:1*c+t.cur.translateX,skewX:-30+t.cur.skewX,opacity:0*t.dom.style.opacity},.6:{translateX:0+t.cur.translateX,skewX:20+t.cur.skewX,opacity:1*t.dom.style.opacity},.8:{translateX:0+t.cur.translateX,skewX:-5+t.cur.skewX,opacity:1*t.dom.style.opacity},1:{translateX:0+t.cur.translateX,skewX:0+t.cur.skewX,opacity:1*t.dom.style.opacity}};else if("lightSpeedOut"===a)n={0:{opacity:1*t.dom.style.opacity},1:{translateX:1*c+t.cur.translateX,skewX:30+t.cur.skewX,opacity:0*t.dom.style.opacity}};else if("rotateIn"===a)n={0:{rotateZ:-200+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="center";else if("rotateInDownLeft"===a)n={0:{rotateZ:-45+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="left bottom";else if("rotateInDownRight"===a)n={0:{rotateZ:45+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="right bottom";else if("rotateInUpLeft"===a)n={0:{rotateZ:45+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="left bottom";else if("rotateInUpRight"===a)n={0:{rotateZ:-90+t.cur.rotateZ,opacity:0*t.dom.style.opacity},1:{rotateZ:0+t.cur.rotateZ,opacity:1*t.dom.style.opacity}},o="right bottom";else if("rotateOut"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:200+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="center";else if("rotateOutDownLeft"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:45+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="left bottom";else if("rotateOutDownRight"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:-45+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="right bottom";else if("rotateOutUpLeft"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:-45+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="left bottom";else if("rotateOutUpRight"===a)n={0:{opacity:1*t.dom.style.opacity},1:{rotateZ:90+t.cur.rotateZ,opacity:0*t.dom.style.opacity}},o="right bottom";else{if("hinge"!==a)throw Error("the name of animation is not exists");n={0:{opacity:1*t.dom.style.opacity},.2:{rotateZ:80+t.cur.rotateZ},.4:{rotateZ:60+t.cur.rotateZ,opacity:1*t.dom.style.opacity},.6:{rotateZ:80+t.cur.rotateZ},.8:{rotateZ:60+t.cur.rotateZ,opacity:1*t.dom.style.opacity},1:{translateY:700+t.cur.translateY,opacity:0*t.dom.style.opacity}},o="top left",r=["easeInOut","easeInOut","easeInOut","easeInOut","easeInOut","easeInOut"]}return[n,r,o,s]}};e.AnimationUtil=i}(t,e,e.base),function(t,e,i){var a,n=i.Class.extend({_init:function(){return void 0!==a?a=new this:(this.targetObjects=[],this)},addTarget:function(t){this.targetObjects.push(t),t.map=new e.base.WeakMap},getObject:function(t){if(t instanceof e.AnimationObject)return t;for(var i=0,a=this.targetObjects.length;a>i;i++)if(t instanceof this.targetObjects[i].$type){var n=this.targetObjects[i].map.get(t);return void 0===n&&(n=new e[this.targetObjects[i].$namespace](t),this.targetObjects[i].map.set(t,n)),n}throw"CannotCreateObject"},"static":{getInstance:function(){return void 0===a&&(a=new n),a},plugin:function(t){function i(){e.AnimationObject.call(this),t.$constructor.apply(this,arguments)}var a=/^\$(?:namespace|constructor|type)$/;if(t.$constructor){i.prototype=new e.AnimationObject,i.prototype.constructor=i;for(var n in t)a.test(n)||(i.prototype[n]="function"==typeof t[n]&&t[n]);return e[t.$namespace]=i,this.getInstance().addTarget(t),i}}}});e.ObjectManager=n}(t,e,e.base),function(t){"use strict";(function(t,e,i){var a=e.base.Class.extend({_init:function(){this.from=new e.Transform,this.cur=i.copy(this.from),this.updateSeek=!1,this.updateSeekProperty=[]},getFrom:function(t){var e={},t=t.animation;for(var i in t)e[i]=this.from[i],this.from[i]=t[i];return e},setFrom:function(t){this.from.set(t)},translate:function(){},rotate:function(){}});e.AnimationObject=a})(t,e,e.base)}(t),function(t,e,i){"use strict";var a=e.CssAnimationUtil.getInstance(),n=e.CssStringCreator.getInstance();e.ObjectManager.plugin({$namespace:"DomObject",$type:t.HTMLElement,$constructor:function(t){this.dom=t,this.unit={},this._perspective=!1},render:function(t){var e,i,a=t.updateProperty;for(e=0;i=a[e];e++)t.targetStyle[i]=n[i](this,t.unit)},objectRender:function(t){var e=!1;for(var i in t)this.isTransform(i)||void 0===this.dom.style[i]?e||(this.dom.style.WebkitTransform=n.WebkitTransform(t),e=!0):this.dom.style[i]=n[i](t,unit)},createTweenInfo:function(t,e,i){var a={fromTo:{},animationFromTo:t,cur:this.cur,option:e,name:[],unit:{},target:this,targetStyle:this.dom.style,updateProperty:[]};return i&&this.setAnimationFromTo(a),a},setAnimationFromTo:function(t){var e,n=!1,r=t.animationFromTo;for(e in r)this.isTransform(e)?(a.WebkitTransform(e,t),n||(t.updateProperty.push("WebkitTransform"),n=!0)):"perspective"===e?(this._perspective=i.isNumber(r[e])?r[e]:i.isNumber(r[e][1])?r[e][1]:0,this.cur.perspective=this._perspective):a[e]&&(a[e](t),t.updateProperty.push(e))},isTransform:function(t){return void 0!==t&&null!==t?"translateX"===t||"translateY"===t||"translateZ"===t||"rotateX"===t||"rotateY"===t||"rotateZ"===t||"scaleX"===t||"scaleY"===t||"skewX"===t||"skewY"===t?!0:!1:void 0},perspective:function(t){void 0!==t&&null!==t&&e.base.isNumber(t)&&(this._perspective=t,this.cur.perspective=t)},set:function(t){if(void 0!==t&&null!==t){for(var e in t)this.isTransform(e)?(this.from[e]=t[e],this.cur[e]=t[e]):"perspective"===e?this.perspective(t[e]):this.dom.style[e]=t[e];this.objectRender(i.deepCopy(this.from))}}})}(t,e,e.base),function(t,e,i){"use strict";function a(t){var i,a;for(this.target=[],this.len=t.length,i=0;this.len>i;i++)this.target[i]=(a=n.getObject(t[i]).simpleAnimation)?a:new e.SimpleAnimation(t[i])}var n=e.ObjectManager.getInstance(),r={tween:function(t,i,a){var n;return this.simpleAnimation||(this.simpleAnimation=this.length?new e.SimpleAnimationGroup(this):new e.SimpleAnimation(this)),n=e.AnimationUtil.optionAnalyzer(i,a),this.simpleAnimation.add(t,n),this.simpleAnimation.play(),this},stop:function(){this.simpleAnimation||this.simpleAnimation||(this.simpleAnimation=this.length?new e.SimpleAnimationGroup(this):new e.SimpleAnimation(this)),this.simpleAnimation.stop()},transform:function(t){this.simpleAnimation||(this.simpleAnimation=this.length?new e.SimpleAnimationGroup(this):new e.SimpleAnimation(this)),this.simpleAnimation.target.set(t)}},o=function(t){this.tweenAnimator=new e.TweenAnimator,this.target=n.getObject(t),this.target.simpleAnimation=this,this.target.render&&this.tweenAnimator.setRender(this.target.render),this.target.cur&&this.tweenAnimator.setUpdateTarget(this.target.cur)};o.prototype.add=function(t,a,n){var r,o,s,c,l=n||this.tweenAnimator,u=this;return"string"==typeof t?(r=e.AnimationUtil.effectAnalyzer(this.target,t),e.AnimationUtil.createKeyFrame(r[0],a,function(t,e,i){void 0!==r[1]&&(e.ease=r[1][i]),o=u.target.createTweenInfo(t,e,!0),l.add(o),void 0!==r[2]&&(0===i?o.startCallback.on(function(){u.target.dom.style.webkitTransformOrigin=r[2]}):i===r.length&&o.completeCallback.on(function(){u.target.dom.style.webkitTransformOrigin=""})),void 0!==r[3]&&o.completeCallback.on(function(){u.target.dom.style.visibility=r[3]})}),void 0):(t.effect&&(void 0===this.parTweensGroup?(this.parTweensGroup=[],c=new e.TweenAnimator,this.parTweensGroup.push(c)):c=this.parTweensGroup[0],this.target.render&&c.setRender(this.target.render),this.target.cur&&c.setUpdateTarget(this.target.cur),this.add(t.effect,i.deepCopy(a),c)),"running"===l.getState()?(o=u.target.createTweenInfo(t,a,!1),(s=l.getLastTweenInfo())&&s.completeCallback.on(function(){u.target.setAnimationFromTo(o)})):o=this.target.createTweenInfo(t,a,!0),l.add(o),void 0)},o.prototype.play=function(){var t,e;if(this.tweenAnimator.play(),this.parTweensGroup)for(t=0,e=this.parTweensGroup.length;e>t;t++)this.parTweensGroup[t].play()},o.prototype.stop=function(){var t,e;if(this.tweenAnimator.stop(),this.parTweensGroup)for(t=0,e=this.parTweensGroup.length;e>t;t++)this.parTweensGroup[t].stop()},a.prototype.add=function(t,i){var a=0,n=this;e.AnimationUtil.checkStagger(this.target,i,function(e,r){i.onComplete&&(r.onComplete=function(){a++,a===n.len&&e.tweenAnimator.getCurrentTweenInfo().completeCallback.on(i.onComplete)}),e.add(t,r)})},a.prototype.play=function(){var t;for(t=0;this.len>t;t++)this.target[t].play()},a.prototype.stop=function(){var t;for(t=0;this.len>t;t++)this.target[t].stop()},e.SimpleAnimation=o,e.SimpleAnimationGroup=a,e.SimpleAnimationMixinObject=r}(t,e,e.base),function(t,e){"use strict";function i(t){var e,i,a=["tween","stop","transform","simpleAnimation"];for(e=0,i=a.length;i>e;e++)if(t.hasOwnProperty(a[e]))return a[e];return!1}function a(t){var e="Function or Object can apply Mixin";e+=void 0!==t?': "'+t+'" is overrided.':".",console.warn(e)}var n=e.SimpleAnimationMixinObject,r=function(t){var e;if(void 0!==t.prototype){(e=i(t.prototype))&&a(e);for(var r in n)t.prototype[r]=n[r]}else if(t instanceof Object){(e=i(t))&&a(e);for(var r in n)n.hasOwnProperty(r)&&(t[r]=n[r])}else a();return t};e.SimpleMixin=r}(t,e),function(t,e){"use strict";var i=e.ObjectManager.getInstance();e.SimpleMixin(e.DomObject),e.target=function(a){if("string"==typeof a){var n,r=a.slice(0,1),o=a.slice(1);"."===r?(n=document.getElementsByClassName(o),n.tween||e.SimpleMixin(n,function(){return n})):"#"===r&&(n=document.getElementById(o),n=i.getObject(n))}else a instanceof t.HTMLElement&&(n=i.getObject(a));return n}}(t,e)})(window);
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/js/jquery.js b/d2d_app/client/lib/tau/mobile/js/jquery.js
new file mode 100644 (file)
index 0000000..9f7b3d3
--- /dev/null
@@ -0,0 +1,9190 @@
+/*!
+ * jQuery JavaScript Library v2.1.1
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2014-05-01T17:11Z
+ */
+
+(function( global, factory ) {
+
+       if ( typeof module === "object" && typeof module.exports === "object" ) {
+               // For CommonJS and CommonJS-like environments where a proper window is present,
+               // execute the factory and get jQuery
+               // For environments that do not inherently posses a window with a document
+               // (such as Node.js), expose a jQuery-making factory as module.exports
+               // This accentuates the need for the creation of a real window
+               // e.g. var jQuery = require("jquery")(window);
+               // See ticket #14549 for more info
+               module.exports = global.document ?
+                       factory( global, true ) :
+                       function( w ) {
+                               if ( !w.document ) {
+                                       throw new Error( "jQuery requires a window with a document" );
+                               }
+                               return factory( w );
+                       };
+       } else {
+               factory( global );
+       }
+
+// Pass this if window is not defined yet
+}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//
+
+var arr = [];
+
+var slice = arr.slice;
+
+var concat = arr.concat;
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var support = {};
+
+
+
+var
+       // Use the correct document accordingly with window argument (sandbox)
+       document = window.document,
+
+       version = "2.1.1",
+
+       // Define a local copy of jQuery
+       jQuery = function( selector, context ) {
+               // The jQuery object is actually just the init constructor 'enhanced'
+               // Need init if jQuery is called (just allow error to be thrown if not included)
+               return new jQuery.fn.init( selector, context );
+       },
+
+       // Support: Android<4.1
+       // Make sure we trim BOM and NBSP
+       rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+       // Matches dashed string for camelizing
+       rmsPrefix = /^-ms-/,
+       rdashAlpha = /-([\da-z])/gi,
+
+       // Used by jQuery.camelCase as callback to replace()
+       fcamelCase = function( all, letter ) {
+               return letter.toUpperCase();
+       };
+
+jQuery.fn = jQuery.prototype = {
+       // The current version of jQuery being used
+       jquery: version,
+
+       constructor: jQuery,
+
+       // Start with an empty selector
+       selector: "",
+
+       // The default length of a jQuery object is 0
+       length: 0,
+
+       toArray: function() {
+               return slice.call( this );
+       },
+
+       // Get the Nth element in the matched element set OR
+       // Get the whole matched element set as a clean array
+       get: function( num ) {
+               return num != null ?
+
+                       // Return just the one element from the set
+                       ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
+
+                       // Return all the elements in a clean array
+                       slice.call( this );
+       },
+
+       // Take an array of elements and push it onto the stack
+       // (returning the new matched element set)
+       pushStack: function( elems ) {
+
+               // Build a new jQuery matched element set
+               var ret = jQuery.merge( this.constructor(), elems );
+
+               // Add the old object onto the stack (as a reference)
+               ret.prevObject = this;
+               ret.context = this.context;
+
+               // Return the newly-formed element set
+               return ret;
+       },
+
+       // Execute a callback for every element in the matched set.
+       // (You can seed the arguments with an array of args, but this is
+       // only used internally.)
+       each: function( callback, args ) {
+               return jQuery.each( this, callback, args );
+       },
+
+       map: function( callback ) {
+               return this.pushStack( jQuery.map(this, function( elem, i ) {
+                       return callback.call( elem, i, elem );
+               }));
+       },
+
+       slice: function() {
+               return this.pushStack( slice.apply( this, arguments ) );
+       },
+
+       first: function() {
+               return this.eq( 0 );
+       },
+
+       last: function() {
+               return this.eq( -1 );
+       },
+
+       eq: function( i ) {
+               var len = this.length,
+                       j = +i + ( i < 0 ? len : 0 );
+               return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+       },
+
+       end: function() {
+               return this.prevObject || this.constructor(null);
+       },
+
+       // For internal use only.
+       // Behaves like an Array's method, not like a jQuery method.
+       push: push,
+       sort: arr.sort,
+       splice: arr.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+       var options, name, src, copy, copyIsArray, clone,
+               target = arguments[0] || {},
+               i = 1,
+               length = arguments.length,
+               deep = false;
+
+       // Handle a deep copy situation
+       if ( typeof target === "boolean" ) {
+               deep = target;
+
+               // skip the boolean and the target
+               target = arguments[ i ] || {};
+               i++;
+       }
+
+       // Handle case when target is a string or something (possible in deep copy)
+       if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+               target = {};
+       }
+
+       // extend jQuery itself if only one argument is passed
+       if ( i === length ) {
+               target = this;
+               i--;
+       }
+
+       for ( ; i < length; i++ ) {
+               // Only deal with non-null/undefined values
+               if ( (options = arguments[ i ]) != null ) {
+                       // Extend the base object
+                       for ( name in options ) {
+                               src = target[ name ];
+                               copy = options[ name ];
+
+                               // Prevent never-ending loop
+                               if ( target === copy ) {
+                                       continue;
+                               }
+
+                               // Recurse if we're merging plain objects or arrays
+                               if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+                                       if ( copyIsArray ) {
+                                               copyIsArray = false;
+                                               clone = src && jQuery.isArray(src) ? src : [];
+
+                                       } else {
+                                               clone = src && jQuery.isPlainObject(src) ? src : {};
+                                       }
+
+                                       // Never move original objects, clone them
+                                       target[ name ] = jQuery.extend( deep, clone, copy );
+
+                               // Don't bring in undefined values
+                               } else if ( copy !== undefined ) {
+                                       target[ name ] = copy;
+                               }
+                       }
+               }
+       }
+
+       // Return the modified object
+       return target;
+};
+
+jQuery.extend({
+       // Unique for each copy of jQuery on the page
+       expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+       // Assume jQuery is ready without the ready module
+       isReady: true,
+
+       error: function( msg ) {
+               throw new Error( msg );
+       },
+
+       noop: function() {},
+
+       // See test/unit/core.js for details concerning isFunction.
+       // Since version 1.3, DOM methods and functions like alert
+       // aren't supported. They return false on IE (#2968).
+       isFunction: function( obj ) {
+               return jQuery.type(obj) === "function";
+       },
+
+       isArray: Array.isArray,
+
+       isWindow: function( obj ) {
+               return obj != null && obj === obj.window;
+       },
+
+       isNumeric: function( obj ) {
+               // parseFloat NaNs numeric-cast false positives (null|true|false|"")
+               // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+               // subtraction forces infinities to NaN
+               return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;
+       },
+
+       isPlainObject: function( obj ) {
+               // Not plain objects:
+               // - Any object or value whose internal [[Class]] property is not "[object Object]"
+               // - DOM nodes
+               // - window
+               if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+                       return false;
+               }
+
+               if ( obj.constructor &&
+                               !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
+                       return false;
+               }
+
+               // If the function hasn't returned already, we're confident that
+               // |obj| is a plain object, created by {} or constructed with new Object
+               return true;
+       },
+
+       isEmptyObject: function( obj ) {
+               var name;
+               for ( name in obj ) {
+                       return false;
+               }
+               return true;
+       },
+
+       type: function( obj ) {
+               if ( obj == null ) {
+                       return obj + "";
+               }
+               // Support: Android < 4.0, iOS < 6 (functionish RegExp)
+               return typeof obj === "object" || typeof obj === "function" ?
+                       class2type[ toString.call(obj) ] || "object" :
+                       typeof obj;
+       },
+
+       // Evaluates a script in a global context
+       globalEval: function( code ) {
+               var script,
+                       indirect = eval;
+
+               code = jQuery.trim( code );
+
+               if ( code ) {
+                       // If the code includes a valid, prologue position
+                       // strict mode pragma, execute code by injecting a
+                       // script tag into the document.
+                       if ( code.indexOf("use strict") === 1 ) {
+                               script = document.createElement("script");
+                               script.text = code;
+                               document.head.appendChild( script ).parentNode.removeChild( script );
+                       } else {
+                       // Otherwise, avoid the DOM node creation, insertion
+                       // and removal by using an indirect global eval
+                               indirect( code );
+                       }
+               }
+       },
+
+       // Convert dashed to camelCase; used by the css and data modules
+       // Microsoft forgot to hump their vendor prefix (#9572)
+       camelCase: function( string ) {
+               return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+       },
+
+       nodeName: function( elem, name ) {
+               return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+       },
+
+       // args is for internal usage only
+       each: function( obj, callback, args ) {
+               var value,
+                       i = 0,
+                       length = obj.length,
+                       isArray = isArraylike( obj );
+
+               if ( args ) {
+                       if ( isArray ) {
+                               for ( ; i < length; i++ ) {
+                                       value = callback.apply( obj[ i ], args );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( i in obj ) {
+                                       value = callback.apply( obj[ i ], args );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       }
+
+               // A special, fast, case for the most common use of each
+               } else {
+                       if ( isArray ) {
+                               for ( ; i < length; i++ ) {
+                                       value = callback.call( obj[ i ], i, obj[ i ] );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       } else {
+                               for ( i in obj ) {
+                                       value = callback.call( obj[ i ], i, obj[ i ] );
+
+                                       if ( value === false ) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               return obj;
+       },
+
+       // Support: Android<4.1
+       trim: function( text ) {
+               return text == null ?
+                       "" :
+                       ( text + "" ).replace( rtrim, "" );
+       },
+
+       // results is for internal usage only
+       makeArray: function( arr, results ) {
+               var ret = results || [];
+
+               if ( arr != null ) {
+                       if ( isArraylike( Object(arr) ) ) {
+                               jQuery.merge( ret,
+                                       typeof arr === "string" ?
+                                       [ arr ] : arr
+                               );
+                       } else {
+                               push.call( ret, arr );
+                       }
+               }
+
+               return ret;
+       },
+
+       inArray: function( elem, arr, i ) {
+               return arr == null ? -1 : indexOf.call( arr, elem, i );
+       },
+
+       merge: function( first, second ) {
+               var len = +second.length,
+                       j = 0,
+                       i = first.length;
+
+               for ( ; j < len; j++ ) {
+                       first[ i++ ] = second[ j ];
+               }
+
+               first.length = i;
+
+               return first;
+       },
+
+       grep: function( elems, callback, invert ) {
+               var callbackInverse,
+                       matches = [],
+                       i = 0,
+                       length = elems.length,
+                       callbackExpect = !invert;
+
+               // Go through the array, only saving the items
+               // that pass the validator function
+               for ( ; i < length; i++ ) {
+                       callbackInverse = !callback( elems[ i ], i );
+                       if ( callbackInverse !== callbackExpect ) {
+                               matches.push( elems[ i ] );
+                       }
+               }
+
+               return matches;
+       },
+
+       // arg is for internal usage only
+       map: function( elems, callback, arg ) {
+               var value,
+                       i = 0,
+                       length = elems.length,
+                       isArray = isArraylike( elems ),
+                       ret = [];
+
+               // Go through the array, translating each of the items to their new values
+               if ( isArray ) {
+                       for ( ; i < length; i++ ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret.push( value );
+                               }
+                       }
+
+               // Go through every key on the object,
+               } else {
+                       for ( i in elems ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret.push( value );
+                               }
+                       }
+               }
+
+               // Flatten any nested arrays
+               return concat.apply( [], ret );
+       },
+
+       // A global GUID counter for objects
+       guid: 1,
+
+       // Bind a function to a context, optionally partially applying any
+       // arguments.
+       proxy: function( fn, context ) {
+               var tmp, args, proxy;
+
+               if ( typeof context === "string" ) {
+                       tmp = fn[ context ];
+                       context = fn;
+                       fn = tmp;
+               }
+
+               // Quick check to determine if target is callable, in the spec
+               // this throws a TypeError, but we will just return undefined.
+               if ( !jQuery.isFunction( fn ) ) {
+                       return undefined;
+               }
+
+               // Simulated bind
+               args = slice.call( arguments, 2 );
+               proxy = function() {
+                       return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+               };
+
+               // Set the guid of unique handler to the same of original handler, so it can be removed
+               proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+               return proxy;
+       },
+
+       now: Date.now,
+
+       // jQuery.support is not used in Core but other projects attach their
+       // properties to it so it needs to exist.
+       support: support
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
+       class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+       var length = obj.length,
+               type = jQuery.type( obj );
+
+       if ( type === "function" || jQuery.isWindow( obj ) ) {
+               return false;
+       }
+
+       if ( obj.nodeType === 1 && length ) {
+               return true;
+       }
+
+       return type === "array" || length === 0 ||
+               typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v1.10.19
+ * http://sizzlejs.com/
+ *
+ * Copyright 2013 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2014-04-18
+ */
+(function( window ) {
+
+var i,
+       support,
+       Expr,
+       getText,
+       isXML,
+       tokenize,
+       compile,
+       select,
+       outermostContext,
+       sortInput,
+       hasDuplicate,
+
+       // Local document vars
+       setDocument,
+       document,
+       docElem,
+       documentIsHTML,
+       rbuggyQSA,
+       rbuggyMatches,
+       matches,
+       contains,
+
+       // Instance-specific data
+       expando = "sizzle" + -(new Date()),
+       preferredDoc = window.document,
+       dirruns = 0,
+       done = 0,
+       classCache = createCache(),
+       tokenCache = createCache(),
+       compilerCache = createCache(),
+       sortOrder = function( a, b ) {
+               if ( a === b ) {
+                       hasDuplicate = true;
+               }
+               return 0;
+       },
+
+       // General-purpose constants
+       strundefined = typeof undefined,
+       MAX_NEGATIVE = 1 << 31,
+
+       // Instance methods
+       hasOwn = ({}).hasOwnProperty,
+       arr = [],
+       pop = arr.pop,
+       push_native = arr.push,
+       push = arr.push,
+       slice = arr.slice,
+       // Use a stripped-down indexOf if we can't use a native one
+       indexOf = arr.indexOf || function( elem ) {
+               var i = 0,
+                       len = this.length;
+               for ( ; i < len; i++ ) {
+                       if ( this[i] === elem ) {
+                               return i;
+                       }
+               }
+               return -1;
+       },
+
+       booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+       // Regular expressions
+
+       // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
+       whitespace = "[\\x20\\t\\r\\n\\f]",
+       // http://www.w3.org/TR/css3-syntax/#characters
+       characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+       // Loosely modeled on CSS identifier characters
+       // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
+       // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+       identifier = characterEncoding.replace( "w", "w#" ),
+
+       // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+       attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
+               // Operator (capture 2)
+               "*([*^$|!~]?=)" + whitespace +
+               // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+               "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+               "*\\]",
+
+       pseudos = ":(" + characterEncoding + ")(?:\\((" +
+               // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+               // 1. quoted (capture 3; capture 4 or capture 5)
+               "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+               // 2. simple (capture 6)
+               "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+               // 3. anything else (capture 2)
+               ".*" +
+               ")\\)|)",
+
+       // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+       rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+       rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+       rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+       rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+       rpseudo = new RegExp( pseudos ),
+       ridentifier = new RegExp( "^" + identifier + "$" ),
+
+       matchExpr = {
+               "ID": new RegExp( "^#(" + characterEncoding + ")" ),
+               "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
+               "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
+               "ATTR": new RegExp( "^" + attributes ),
+               "PSEUDO": new RegExp( "^" + pseudos ),
+               "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+                       "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+                       "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+               "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+               // For use in libraries implementing .is()
+               // We use this for POS matching in `select`
+               "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+                       whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+       },
+
+       rinputs = /^(?:input|select|textarea|button)$/i,
+       rheader = /^h\d$/i,
+
+       rnative = /^[^{]+\{\s*\[native \w/,
+
+       // Easily-parseable/retrievable ID or TAG or CLASS selectors
+       rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+       rsibling = /[+~]/,
+       rescape = /'|\\/g,
+
+       // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+       runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+       funescape = function( _, escaped, escapedWhitespace ) {
+               var high = "0x" + escaped - 0x10000;
+               // NaN means non-codepoint
+               // Support: Firefox<24
+               // Workaround erroneous numeric interpretation of +"0x"
+               return high !== high || escapedWhitespace ?
+                       escaped :
+                       high < 0 ?
+                               // BMP codepoint
+                               String.fromCharCode( high + 0x10000 ) :
+                               // Supplemental Plane codepoint (surrogate pair)
+                               String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+       };
+
+// Optimize for push.apply( _, NodeList )
+try {
+       push.apply(
+               (arr = slice.call( preferredDoc.childNodes )),
+               preferredDoc.childNodes
+       );
+       // Support: Android<4.0
+       // Detect silently failing push.apply
+       arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+       push = { apply: arr.length ?
+
+               // Leverage slice if possible
+               function( target, els ) {
+                       push_native.apply( target, slice.call(els) );
+               } :
+
+               // Support: IE<9
+               // Otherwise append directly
+               function( target, els ) {
+                       var j = target.length,
+                               i = 0;
+                       // Can't trust NodeList.length
+                       while ( (target[j++] = els[i++]) ) {}
+                       target.length = j - 1;
+               }
+       };
+}
+
+function Sizzle( selector, context, results, seed ) {
+       var match, elem, m, nodeType,
+               // QSA vars
+               i, groups, old, nid, newContext, newSelector;
+
+       if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+               setDocument( context );
+       }
+
+       context = context || document;
+       results = results || [];
+
+       if ( !selector || typeof selector !== "string" ) {
+               return results;
+       }
+
+       if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
+               return [];
+       }
+
+       if ( documentIsHTML && !seed ) {
+
+               // Shortcuts
+               if ( (match = rquickExpr.exec( selector )) ) {
+                       // Speed-up: Sizzle("#ID")
+                       if ( (m = match[1]) ) {
+                               if ( nodeType === 9 ) {
+                                       elem = context.getElementById( m );
+                                       // Check parentNode to catch when Blackberry 4.6 returns
+                                       // nodes that are no longer in the document (jQuery #6963)
+                                       if ( elem && elem.parentNode ) {
+                                               // Handle the case where IE, Opera, and Webkit return items
+                                               // by name instead of ID
+                                               if ( elem.id === m ) {
+                                                       results.push( elem );
+                                                       return results;
+                                               }
+                                       } else {
+                                               return results;
+                                       }
+                               } else {
+                                       // Context is not a document
+                                       if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
+                                               contains( context, elem ) && elem.id === m ) {
+                                               results.push( elem );
+                                               return results;
+                                       }
+                               }
+
+                       // Speed-up: Sizzle("TAG")
+                       } else if ( match[2] ) {
+                               push.apply( results, context.getElementsByTagName( selector ) );
+                               return results;
+
+                       // Speed-up: Sizzle(".CLASS")
+                       } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
+                               push.apply( results, context.getElementsByClassName( m ) );
+                               return results;
+                       }
+               }
+
+               // QSA path
+               if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+                       nid = old = expando;
+                       newContext = context;
+                       newSelector = nodeType === 9 && selector;
+
+                       // qSA works strangely on Element-rooted queries
+                       // We can work around this by specifying an extra ID on the root
+                       // and working up from there (Thanks to Andrew Dupont for the technique)
+                       // IE 8 doesn't work on object elements
+                       if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+                               groups = tokenize( selector );
+
+                               if ( (old = context.getAttribute("id")) ) {
+                                       nid = old.replace( rescape, "\\$&" );
+                               } else {
+                                       context.setAttribute( "id", nid );
+                               }
+                               nid = "[id='" + nid + "'] ";
+
+                               i = groups.length;
+                               while ( i-- ) {
+                                       groups[i] = nid + toSelector( groups[i] );
+                               }
+                               newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
+                               newSelector = groups.join(",");
+                       }
+
+                       if ( newSelector ) {
+                               try {
+                                       push.apply( results,
+                                               newContext.querySelectorAll( newSelector )
+                                       );
+                                       return results;
+                               } catch(qsaError) {
+                               } finally {
+                                       if ( !old ) {
+                                               context.removeAttribute("id");
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // All others
+       return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ *     property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *     deleting the oldest entry
+ */
+function createCache() {
+       var keys = [];
+
+       function cache( key, value ) {
+               // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+               if ( keys.push( key + " " ) > Expr.cacheLength ) {
+                       // Only keep the most recent entries
+                       delete cache[ keys.shift() ];
+               }
+               return (cache[ key + " " ] = value);
+       }
+       return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+       fn[ expando ] = true;
+       return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+       var div = document.createElement("div");
+
+       try {
+               return !!fn( div );
+       } catch (e) {
+               return false;
+       } finally {
+               // Remove from its parent by default
+               if ( div.parentNode ) {
+                       div.parentNode.removeChild( div );
+               }
+               // release memory in IE
+               div = null;
+       }
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+       var arr = attrs.split("|"),
+               i = attrs.length;
+
+       while ( i-- ) {
+               Expr.attrHandle[ arr[i] ] = handler;
+       }
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+       var cur = b && a,
+               diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+                       ( ~b.sourceIndex || MAX_NEGATIVE ) -
+                       ( ~a.sourceIndex || MAX_NEGATIVE );
+
+       // Use IE sourceIndex if available on both nodes
+       if ( diff ) {
+               return diff;
+       }
+
+       // Check if b follows a
+       if ( cur ) {
+               while ( (cur = cur.nextSibling) ) {
+                       if ( cur === b ) {
+                               return -1;
+                       }
+               }
+       }
+
+       return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+       return function( elem ) {
+               var name = elem.nodeName.toLowerCase();
+               return name === "input" && elem.type === type;
+       };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+       return function( elem ) {
+               var name = elem.nodeName.toLowerCase();
+               return (name === "input" || name === "button") && elem.type === type;
+       };
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+       return markFunction(function( argument ) {
+               argument = +argument;
+               return markFunction(function( seed, matches ) {
+                       var j,
+                               matchIndexes = fn( [], seed.length, argument ),
+                               i = matchIndexes.length;
+
+                       // Match elements found at the specified indexes
+                       while ( i-- ) {
+                               if ( seed[ (j = matchIndexes[i]) ] ) {
+                                       seed[j] = !(matches[j] = seed[j]);
+                               }
+                       }
+               });
+       });
+}
+
+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+       return context && typeof context.getElementsByTagName !== strundefined && context;
+}
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+       // documentElement is verified for cases where it doesn't yet exist
+       // (such as loading iframes in IE - #4833)
+       var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+       return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+       var hasCompare,
+               doc = node ? node.ownerDocument || node : preferredDoc,
+               parent = doc.defaultView;
+
+       // If no document and documentElement is available, return
+       if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+               return document;
+       }
+
+       // Set our document
+       document = doc;
+       docElem = doc.documentElement;
+
+       // Support tests
+       documentIsHTML = !isXML( doc );
+
+       // Support: IE>8
+       // If iframe document is assigned to "document" variable and if iframe has been reloaded,
+       // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
+       // IE6-8 do not support the defaultView property so parent will be undefined
+       if ( parent && parent !== parent.top ) {
+               // IE11 does not have attachEvent, so all must suffer
+               if ( parent.addEventListener ) {
+                       parent.addEventListener( "unload", function() {
+                               setDocument();
+                       }, false );
+               } else if ( parent.attachEvent ) {
+                       parent.attachEvent( "onunload", function() {
+                               setDocument();
+                       });
+               }
+       }
+
+       /* Attributes
+       ---------------------------------------------------------------------- */
+
+       // Support: IE<8
+       // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
+       support.attributes = assert(function( div ) {
+               div.className = "i";
+               return !div.getAttribute("className");
+       });
+
+       /* getElement(s)By*
+       ---------------------------------------------------------------------- */
+
+       // Check if getElementsByTagName("*") returns only elements
+       support.getElementsByTagName = assert(function( div ) {
+               div.appendChild( doc.createComment("") );
+               return !div.getElementsByTagName("*").length;
+       });
+
+       // Check if getElementsByClassName can be trusted
+       support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
+               div.innerHTML = "<div class='a'></div><div class='a i'></div>";
+
+               // Support: Safari<4
+               // Catch class over-caching
+               div.firstChild.className = "i";
+               // Support: Opera<10
+               // Catch gEBCN failure to find non-leading classes
+               return div.getElementsByClassName("i").length === 2;
+       });
+
+       // Support: IE<10
+       // Check if getElementById returns elements by name
+       // The broken getElementById methods don't pick up programatically-set names,
+       // so use a roundabout getElementsByName test
+       support.getById = assert(function( div ) {
+               docElem.appendChild( div ).id = expando;
+               return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
+       });
+
+       // ID find and filter
+       if ( support.getById ) {
+               Expr.find["ID"] = function( id, context ) {
+                       if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
+                               var m = context.getElementById( id );
+                               // Check parentNode to catch when Blackberry 4.6 returns
+                               // nodes that are no longer in the document #6963
+                               return m && m.parentNode ? [ m ] : [];
+                       }
+               };
+               Expr.filter["ID"] = function( id ) {
+                       var attrId = id.replace( runescape, funescape );
+                       return function( elem ) {
+                               return elem.getAttribute("id") === attrId;
+                       };
+               };
+       } else {
+               // Support: IE6/7
+               // getElementById is not reliable as a find shortcut
+               delete Expr.find["ID"];
+
+               Expr.filter["ID"] =  function( id ) {
+                       var attrId = id.replace( runescape, funescape );
+                       return function( elem ) {
+                               var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+                               return node && node.value === attrId;
+                       };
+               };
+       }
+
+       // Tag
+       Expr.find["TAG"] = support.getElementsByTagName ?
+               function( tag, context ) {
+                       if ( typeof context.getElementsByTagName !== strundefined ) {
+                               return context.getElementsByTagName( tag );
+                       }
+               } :
+               function( tag, context ) {
+                       var elem,
+                               tmp = [],
+                               i = 0,
+                               results = context.getElementsByTagName( tag );
+
+                       // Filter out possible comments
+                       if ( tag === "*" ) {
+                               while ( (elem = results[i++]) ) {
+                                       if ( elem.nodeType === 1 ) {
+                                               tmp.push( elem );
+                                       }
+                               }
+
+                               return tmp;
+                       }
+                       return results;
+               };
+
+       // Class
+       Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+               if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
+                       return context.getElementsByClassName( className );
+               }
+       };
+
+       /* QSA/matchesSelector
+       ---------------------------------------------------------------------- */
+
+       // QSA and matchesSelector support
+
+       // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+       rbuggyMatches = [];
+
+       // qSa(:focus) reports false when true (Chrome 21)
+       // We allow this because of a bug in IE8/9 that throws an error
+       // whenever `document.activeElement` is accessed on an iframe
+       // So, we allow :focus to pass through QSA all the time to avoid the IE error
+       // See http://bugs.jquery.com/ticket/13378
+       rbuggyQSA = [];
+
+       if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
+               // Build QSA regex
+               // Regex strategy adopted from Diego Perini
+               assert(function( div ) {
+                       // Select is set to empty string on purpose
+                       // This is to test IE's treatment of not explicitly
+                       // setting a boolean content attribute,
+                       // since its presence should be enough
+                       // http://bugs.jquery.com/ticket/12359
+                       div.innerHTML = "<select msallowclip=''><option selected=''></option></select>";
+
+                       // Support: IE8, Opera 11-12.16
+                       // Nothing should be selected when empty strings follow ^= or $= or *=
+                       // The test attribute must be unknown in Opera but "safe" for WinRT
+                       // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+                       if ( div.querySelectorAll("[msallowclip^='']").length ) {
+                               rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+                       }
+
+                       // Support: IE8
+                       // Boolean attributes and "value" are not treated correctly
+                       if ( !div.querySelectorAll("[selected]").length ) {
+                               rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+                       }
+
+                       // Webkit/Opera - :checked should return selected option elements
+                       // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                       // IE8 throws error here and will not see later tests
+                       if ( !div.querySelectorAll(":checked").length ) {
+                               rbuggyQSA.push(":checked");
+                       }
+               });
+
+               assert(function( div ) {
+                       // Support: Windows 8 Native Apps
+                       // The type and name attributes are restricted during .innerHTML assignment
+                       var input = doc.createElement("input");
+                       input.setAttribute( "type", "hidden" );
+                       div.appendChild( input ).setAttribute( "name", "D" );
+
+                       // Support: IE8
+                       // Enforce case-sensitivity of name attribute
+                       if ( div.querySelectorAll("[name=d]").length ) {
+                               rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+                       }
+
+                       // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+                       // IE8 throws error here and will not see later tests
+                       if ( !div.querySelectorAll(":enabled").length ) {
+                               rbuggyQSA.push( ":enabled", ":disabled" );
+                       }
+
+                       // Opera 10-11 does not throw on post-comma invalid pseudos
+                       div.querySelectorAll("*,:x");
+                       rbuggyQSA.push(",.*:");
+               });
+       }
+
+       if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+               docElem.webkitMatchesSelector ||
+               docElem.mozMatchesSelector ||
+               docElem.oMatchesSelector ||
+               docElem.msMatchesSelector) )) ) {
+
+               assert(function( div ) {
+                       // Check to see if it's possible to do matchesSelector
+                       // on a disconnected node (IE 9)
+                       support.disconnectedMatch = matches.call( div, "div" );
+
+                       // This should fail with an exception
+                       // Gecko does not error, returns false instead
+                       matches.call( div, "[s!='']:x" );
+                       rbuggyMatches.push( "!=", pseudos );
+               });
+       }
+
+       rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+       rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+       /* Contains
+       ---------------------------------------------------------------------- */
+       hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+       // Element contains another
+       // Purposefully does not implement inclusive descendent
+       // As in, an element does not contain itself
+       contains = hasCompare || rnative.test( docElem.contains ) ?
+               function( a, b ) {
+                       var adown = a.nodeType === 9 ? a.documentElement : a,
+                               bup = b && b.parentNode;
+                       return a === bup || !!( bup && bup.nodeType === 1 && (
+                               adown.contains ?
+                                       adown.contains( bup ) :
+                                       a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+                       ));
+               } :
+               function( a, b ) {
+                       if ( b ) {
+                               while ( (b = b.parentNode) ) {
+                                       if ( b === a ) {
+                                               return true;
+                                       }
+                               }
+                       }
+                       return false;
+               };
+
+       /* Sorting
+       ---------------------------------------------------------------------- */
+
+       // Document order sorting
+       sortOrder = hasCompare ?
+       function( a, b ) {
+
+               // Flag for duplicate removal
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+               }
+
+               // Sort on method existence if only one input has compareDocumentPosition
+               var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+               if ( compare ) {
+                       return compare;
+               }
+
+               // Calculate position if both inputs belong to the same document
+               compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+                       a.compareDocumentPosition( b ) :
+
+                       // Otherwise we know they are disconnected
+                       1;
+
+               // Disconnected nodes
+               if ( compare & 1 ||
+                       (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+                       // Choose the first element that is related to our preferred document
+                       if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+                               return -1;
+                       }
+                       if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+                               return 1;
+                       }
+
+                       // Maintain original order
+                       return sortInput ?
+                               ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+                               0;
+               }
+
+               return compare & 4 ? -1 : 1;
+       } :
+       function( a, b ) {
+               // Exit early if the nodes are identical
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+               }
+
+               var cur,
+                       i = 0,
+                       aup = a.parentNode,
+                       bup = b.parentNode,
+                       ap = [ a ],
+                       bp = [ b ];
+
+               // Parentless nodes are either documents or disconnected
+               if ( !aup || !bup ) {
+                       return a === doc ? -1 :
+                               b === doc ? 1 :
+                               aup ? -1 :
+                               bup ? 1 :
+                               sortInput ?
+                               ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
+                               0;
+
+               // If the nodes are siblings, we can do a quick check
+               } else if ( aup === bup ) {
+                       return siblingCheck( a, b );
+               }
+
+               // Otherwise we need full lists of their ancestors for comparison
+               cur = a;
+               while ( (cur = cur.parentNode) ) {
+                       ap.unshift( cur );
+               }
+               cur = b;
+               while ( (cur = cur.parentNode) ) {
+                       bp.unshift( cur );
+               }
+
+               // Walk down the tree looking for a discrepancy
+               while ( ap[i] === bp[i] ) {
+                       i++;
+               }
+
+               return i ?
+                       // Do a sibling check if the nodes have a common ancestor
+                       siblingCheck( ap[i], bp[i] ) :
+
+                       // Otherwise nodes in our document sort first
+                       ap[i] === preferredDoc ? -1 :
+                       bp[i] === preferredDoc ? 1 :
+                       0;
+       };
+
+       return doc;
+};
+
+Sizzle.matches = function( expr, elements ) {
+       return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+       // Set document vars if needed
+       if ( ( elem.ownerDocument || elem ) !== document ) {
+               setDocument( elem );
+       }
+
+       // Make sure that attribute selectors are quoted
+       expr = expr.replace( rattributeQuotes, "='$1']" );
+
+       if ( support.matchesSelector && documentIsHTML &&
+               ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+               ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
+
+               try {
+                       var ret = matches.call( elem, expr );
+
+                       // IE 9's matchesSelector returns false on disconnected nodes
+                       if ( ret || support.disconnectedMatch ||
+                                       // As well, disconnected nodes are said to be in a document
+                                       // fragment in IE 9
+                                       elem.document && elem.document.nodeType !== 11 ) {
+                               return ret;
+                       }
+               } catch(e) {}
+       }
+
+       return Sizzle( expr, document, null, [ elem ] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+       // Set document vars if needed
+       if ( ( context.ownerDocument || context ) !== document ) {
+               setDocument( context );
+       }
+       return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+       // Set document vars if needed
+       if ( ( elem.ownerDocument || elem ) !== document ) {
+               setDocument( elem );
+       }
+
+       var fn = Expr.attrHandle[ name.toLowerCase() ],
+               // Don't get fooled by Object.prototype properties (jQuery #13807)
+               val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+                       fn( elem, name, !documentIsHTML ) :
+                       undefined;
+
+       return val !== undefined ?
+               val :
+               support.attributes || !documentIsHTML ?
+                       elem.getAttribute( name ) :
+                       (val = elem.getAttributeNode(name)) && val.specified ?
+                               val.value :
+                               null;
+};
+
+Sizzle.error = function( msg ) {
+       throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+       var elem,
+               duplicates = [],
+               j = 0,
+               i = 0;
+
+       // Unless we *know* we can detect duplicates, assume their presence
+       hasDuplicate = !support.detectDuplicates;
+       sortInput = !support.sortStable && results.slice( 0 );
+       results.sort( sortOrder );
+
+       if ( hasDuplicate ) {
+               while ( (elem = results[i++]) ) {
+                       if ( elem === results[ i ] ) {
+                               j = duplicates.push( i );
+                       }
+               }
+               while ( j-- ) {
+                       results.splice( duplicates[ j ], 1 );
+               }
+       }
+
+       // Clear input after sorting to release objects
+       // See https://github.com/jquery/sizzle/pull/225
+       sortInput = null;
+
+       return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+       var node,
+               ret = "",
+               i = 0,
+               nodeType = elem.nodeType;
+
+       if ( !nodeType ) {
+               // If no nodeType, this is expected to be an array
+               while ( (node = elem[i++]) ) {
+                       // Do not traverse comment nodes
+                       ret += getText( node );
+               }
+       } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+               // Use textContent for elements
+               // innerText usage removed for consistency of new lines (jQuery #11153)
+               if ( typeof elem.textContent === "string" ) {
+                       return elem.textContent;
+               } else {
+                       // Traverse its children
+                       for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                               ret += getText( elem );
+                       }
+               }
+       } else if ( nodeType === 3 || nodeType === 4 ) {
+               return elem.nodeValue;
+       }
+       // Do not include comment or processing instruction nodes
+
+       return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+       // Can be adjusted by the user
+       cacheLength: 50,
+
+       createPseudo: markFunction,
+
+       match: matchExpr,
+
+       attrHandle: {},
+
+       find: {},
+
+       relative: {
+               ">": { dir: "parentNode", first: true },
+               " ": { dir: "parentNode" },
+               "+": { dir: "previousSibling", first: true },
+               "~": { dir: "previousSibling" }
+       },
+
+       preFilter: {
+               "ATTR": function( match ) {
+                       match[1] = match[1].replace( runescape, funescape );
+
+                       // Move the given value to match[3] whether quoted or unquoted
+                       match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+
+                       if ( match[2] === "~=" ) {
+                               match[3] = " " + match[3] + " ";
+                       }
+
+                       return match.slice( 0, 4 );
+               },
+
+               "CHILD": function( match ) {
+                       /* matches from matchExpr["CHILD"]
+                               1 type (only|nth|...)
+                               2 what (child|of-type)
+                               3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+                               4 xn-component of xn+y argument ([+-]?\d*n|)
+                               5 sign of xn-component
+                               6 x of xn-component
+                               7 sign of y-component
+                               8 y of y-component
+                       */
+                       match[1] = match[1].toLowerCase();
+
+                       if ( match[1].slice( 0, 3 ) === "nth" ) {
+                               // nth-* requires argument
+                               if ( !match[3] ) {
+                                       Sizzle.error( match[0] );
+                               }
+
+                               // numeric x and y parameters for Expr.filter.CHILD
+                               // remember that false/true cast respectively to 0/1
+                               match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+                               match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+                       // other types prohibit arguments
+                       } else if ( match[3] ) {
+                               Sizzle.error( match[0] );
+                       }
+
+                       return match;
+               },
+
+               "PSEUDO": function( match ) {
+                       var excess,
+                               unquoted = !match[6] && match[2];
+
+                       if ( matchExpr["CHILD"].test( match[0] ) ) {
+                               return null;
+                       }
+
+                       // Accept quoted arguments as-is
+                       if ( match[3] ) {
+                               match[2] = match[4] || match[5] || "";
+
+                       // Strip excess characters from unquoted arguments
+                       } else if ( unquoted && rpseudo.test( unquoted ) &&
+                               // Get excess from tokenize (recursively)
+                               (excess = tokenize( unquoted, true )) &&
+                               // advance to the next closing parenthesis
+                               (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+                               // excess is a negative index
+                               match[0] = match[0].slice( 0, excess );
+                               match[2] = unquoted.slice( 0, excess );
+                       }
+
+                       // Return only captures needed by the pseudo filter method (type and argument)
+                       return match.slice( 0, 3 );
+               }
+       },
+
+       filter: {
+
+               "TAG": function( nodeNameSelector ) {
+                       var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+                       return nodeNameSelector === "*" ?
+                               function() { return true; } :
+                               function( elem ) {
+                                       return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+                               };
+               },
+
+               "CLASS": function( className ) {
+                       var pattern = classCache[ className + " " ];
+
+                       return pattern ||
+                               (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+                               classCache( className, function( elem ) {
+                                       return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
+                               });
+               },
+
+               "ATTR": function( name, operator, check ) {
+                       return function( elem ) {
+                               var result = Sizzle.attr( elem, name );
+
+                               if ( result == null ) {
+                                       return operator === "!=";
+                               }
+                               if ( !operator ) {
+                                       return true;
+                               }
+
+                               result += "";
+
+                               return operator === "=" ? result === check :
+                                       operator === "!=" ? result !== check :
+                                       operator === "^=" ? check && result.indexOf( check ) === 0 :
+                                       operator === "*=" ? check && result.indexOf( check ) > -1 :
+                                       operator === "$=" ? check && result.slice( -check.length ) === check :
+                                       operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+                                       operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+                                       false;
+                       };
+               },
+
+               "CHILD": function( type, what, argument, first, last ) {
+                       var simple = type.slice( 0, 3 ) !== "nth",
+                               forward = type.slice( -4 ) !== "last",
+                               ofType = what === "of-type";
+
+                       return first === 1 && last === 0 ?
+
+                               // Shortcut for :nth-*(n)
+                               function( elem ) {
+                                       return !!elem.parentNode;
+                               } :
+
+                               function( elem, context, xml ) {
+                                       var cache, outerCache, node, diff, nodeIndex, start,
+                                               dir = simple !== forward ? "nextSibling" : "previousSibling",
+                                               parent = elem.parentNode,
+                                               name = ofType && elem.nodeName.toLowerCase(),
+                                               useCache = !xml && !ofType;
+
+                                       if ( parent ) {
+
+                                               // :(first|last|only)-(child|of-type)
+                                               if ( simple ) {
+                                                       while ( dir ) {
+                                                               node = elem;
+                                                               while ( (node = node[ dir ]) ) {
+                                                                       if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+                                                                               return false;
+                                                                       }
+                                                               }
+                                                               // Reverse direction for :only-* (if we haven't yet done so)
+                                                               start = dir = type === "only" && !start && "nextSibling";
+                                                       }
+                                                       return true;
+                                               }
+
+                                               start = [ forward ? parent.firstChild : parent.lastChild ];
+
+                                               // non-xml :nth-child(...) stores cache data on `parent`
+                                               if ( forward && useCache ) {
+                                                       // Seek `elem` from a previously-cached index
+                                                       outerCache = parent[ expando ] || (parent[ expando ] = {});
+                                                       cache = outerCache[ type ] || [];
+                                                       nodeIndex = cache[0] === dirruns && cache[1];
+                                                       diff = cache[0] === dirruns && cache[2];
+                                                       node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+                                                       while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+                                                               // Fallback to seeking `elem` from the start
+                                                               (diff = nodeIndex = 0) || start.pop()) ) {
+
+                                                               // When found, cache indexes on `parent` and break
+                                                               if ( node.nodeType === 1 && ++diff && node === elem ) {
+                                                                       outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+                                                                       break;
+                                                               }
+                                                       }
+
+                                               // Use previously-cached element index if available
+                                               } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+                                                       diff = cache[1];
+
+                                               // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+                                               } else {
+                                                       // Use the same loop as above to seek `elem` from the start
+                                                       while ( (node = ++nodeIndex && node && node[ dir ] ||
+                                                               (diff = nodeIndex = 0) || start.pop()) ) {
+
+                                                               if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
+                                                                       // Cache the index of each encountered element
+                                                                       if ( useCache ) {
+                                                                               (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+                                                                       }
+
+                                                                       if ( node === elem ) {
+                                                                               break;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+
+                                               // Incorporate the offset, then check against cycle size
+                                               diff -= last;
+                                               return diff === first || ( diff % first === 0 && diff / first >= 0 );
+                                       }
+                               };
+               },
+
+               "PSEUDO": function( pseudo, argument ) {
+                       // pseudo-class names are case-insensitive
+                       // http://www.w3.org/TR/selectors/#pseudo-classes
+                       // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+                       // Remember that setFilters inherits from pseudos
+                       var args,
+                               fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+                                       Sizzle.error( "unsupported pseudo: " + pseudo );
+
+                       // The user may use createPseudo to indicate that
+                       // arguments are needed to create the filter function
+                       // just as Sizzle does
+                       if ( fn[ expando ] ) {
+                               return fn( argument );
+                       }
+
+                       // But maintain support for old signatures
+                       if ( fn.length > 1 ) {
+                               args = [ pseudo, pseudo, "", argument ];
+                               return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+                                       markFunction(function( seed, matches ) {
+                                               var idx,
+                                                       matched = fn( seed, argument ),
+                                                       i = matched.length;
+                                               while ( i-- ) {
+                                                       idx = indexOf.call( seed, matched[i] );
+                                                       seed[ idx ] = !( matches[ idx ] = matched[i] );
+                                               }
+                                       }) :
+                                       function( elem ) {
+                                               return fn( elem, 0, args );
+                                       };
+                       }
+
+                       return fn;
+               }
+       },
+
+       pseudos: {
+               // Potentially complex pseudos
+               "not": markFunction(function( selector ) {
+                       // Trim the selector passed to compile
+                       // to avoid treating leading and trailing
+                       // spaces as combinators
+                       var input = [],
+                               results = [],
+                               matcher = compile( selector.replace( rtrim, "$1" ) );
+
+                       return matcher[ expando ] ?
+                               markFunction(function( seed, matches, context, xml ) {
+                                       var elem,
+                                               unmatched = matcher( seed, null, xml, [] ),
+                                               i = seed.length;
+
+                                       // Match elements unmatched by `matcher`
+                                       while ( i-- ) {
+                                               if ( (elem = unmatched[i]) ) {
+                                                       seed[i] = !(matches[i] = elem);
+                                               }
+                                       }
+                               }) :
+                               function( elem, context, xml ) {
+                                       input[0] = elem;
+                                       matcher( input, null, xml, results );
+                                       return !results.pop();
+                               };
+               }),
+
+               "has": markFunction(function( selector ) {
+                       return function( elem ) {
+                               return Sizzle( selector, elem ).length > 0;
+                       };
+               }),
+
+               "contains": markFunction(function( text ) {
+                       return function( elem ) {
+                               return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+                       };
+               }),
+
+               // "Whether an element is represented by a :lang() selector
+               // is based solely on the element's language value
+               // being equal to the identifier C,
+               // or beginning with the identifier C immediately followed by "-".
+               // The matching of C against the element's language value is performed case-insensitively.
+               // The identifier C does not have to be a valid language name."
+               // http://www.w3.org/TR/selectors/#lang-pseudo
+               "lang": markFunction( function( lang ) {
+                       // lang value must be a valid identifier
+                       if ( !ridentifier.test(lang || "") ) {
+                               Sizzle.error( "unsupported lang: " + lang );
+                       }
+                       lang = lang.replace( runescape, funescape ).toLowerCase();
+                       return function( elem ) {
+                               var elemLang;
+                               do {
+                                       if ( (elemLang = documentIsHTML ?
+                                               elem.lang :
+                                               elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+                                               elemLang = elemLang.toLowerCase();
+                                               return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+                                       }
+                               } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+                               return false;
+                       };
+               }),
+
+               // Miscellaneous
+               "target": function( elem ) {
+                       var hash = window.location && window.location.hash;
+                       return hash && hash.slice( 1 ) === elem.id;
+               },
+
+               "root": function( elem ) {
+                       return elem === docElem;
+               },
+
+               "focus": function( elem ) {
+                       return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+               },
+
+               // Boolean properties
+               "enabled": function( elem ) {
+                       return elem.disabled === false;
+               },
+
+               "disabled": function( elem ) {
+                       return elem.disabled === true;
+               },
+
+               "checked": function( elem ) {
+                       // In CSS3, :checked should return both checked and selected elements
+                       // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                       var nodeName = elem.nodeName.toLowerCase();
+                       return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+               },
+
+               "selected": function( elem ) {
+                       // Accessing this property makes selected-by-default
+                       // options in Safari work properly
+                       if ( elem.parentNode ) {
+                               elem.parentNode.selectedIndex;
+                       }
+
+                       return elem.selected === true;
+               },
+
+               // Contents
+               "empty": function( elem ) {
+                       // http://www.w3.org/TR/selectors/#empty-pseudo
+                       // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+                       //   but not by others (comment: 8; processing instruction: 7; etc.)
+                       // nodeType < 6 works because attributes (2) do not appear as children
+                       for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                               if ( elem.nodeType < 6 ) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               },
+
+               "parent": function( elem ) {
+                       return !Expr.pseudos["empty"]( elem );
+               },
+
+               // Element/input types
+               "header": function( elem ) {
+                       return rheader.test( elem.nodeName );
+               },
+
+               "input": function( elem ) {
+                       return rinputs.test( elem.nodeName );
+               },
+
+               "button": function( elem ) {
+                       var name = elem.nodeName.toLowerCase();
+                       return name === "input" && elem.type === "button" || name === "button";
+               },
+
+               "text": function( elem ) {
+                       var attr;
+                       return elem.nodeName.toLowerCase() === "input" &&
+                               elem.type === "text" &&
+
+                               // Support: IE<8
+                               // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+                               ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+               },
+
+               // Position-in-collection
+               "first": createPositionalPseudo(function() {
+                       return [ 0 ];
+               }),
+
+               "last": createPositionalPseudo(function( matchIndexes, length ) {
+                       return [ length - 1 ];
+               }),
+
+               "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       return [ argument < 0 ? argument + length : argument ];
+               }),
+
+               "even": createPositionalPseudo(function( matchIndexes, length ) {
+                       var i = 0;
+                       for ( ; i < length; i += 2 ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "odd": createPositionalPseudo(function( matchIndexes, length ) {
+                       var i = 1;
+                       for ( ; i < length; i += 2 ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       var i = argument < 0 ? argument + length : argument;
+                       for ( ; --i >= 0; ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       var i = argument < 0 ? argument + length : argument;
+                       for ( ; ++i < length; ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               })
+       }
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+       Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+       Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+       var matched, match, tokens, type,
+               soFar, groups, preFilters,
+               cached = tokenCache[ selector + " " ];
+
+       if ( cached ) {
+               return parseOnly ? 0 : cached.slice( 0 );
+       }
+
+       soFar = selector;
+       groups = [];
+       preFilters = Expr.preFilter;
+
+       while ( soFar ) {
+
+               // Comma and first run
+               if ( !matched || (match = rcomma.exec( soFar )) ) {
+                       if ( match ) {
+                               // Don't consume trailing commas as valid
+                               soFar = soFar.slice( match[0].length ) || soFar;
+                       }
+                       groups.push( (tokens = []) );
+               }
+
+               matched = false;
+
+               // Combinators
+               if ( (match = rcombinators.exec( soFar )) ) {
+                       matched = match.shift();
+                       tokens.push({
+                               value: matched,
+                               // Cast descendant combinators to space
+                               type: match[0].replace( rtrim, " " )
+                       });
+                       soFar = soFar.slice( matched.length );
+               }
+
+               // Filters
+               for ( type in Expr.filter ) {
+                       if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+                               (match = preFilters[ type ]( match ))) ) {
+                               matched = match.shift();
+                               tokens.push({
+                                       value: matched,
+                                       type: type,
+                                       matches: match
+                               });
+                               soFar = soFar.slice( matched.length );
+                       }
+               }
+
+               if ( !matched ) {
+                       break;
+               }
+       }
+
+       // Return the length of the invalid excess
+       // if we're just parsing
+       // Otherwise, throw an error or return tokens
+       return parseOnly ?
+               soFar.length :
+               soFar ?
+                       Sizzle.error( selector ) :
+                       // Cache the tokens
+                       tokenCache( selector, groups ).slice( 0 );
+};
+
+function toSelector( tokens ) {
+       var i = 0,
+               len = tokens.length,
+               selector = "";
+       for ( ; i < len; i++ ) {
+               selector += tokens[i].value;
+       }
+       return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+       var dir = combinator.dir,
+               checkNonElements = base && dir === "parentNode",
+               doneName = done++;
+
+       return combinator.first ?
+               // Check against closest ancestor/preceding element
+               function( elem, context, xml ) {
+                       while ( (elem = elem[ dir ]) ) {
+                               if ( elem.nodeType === 1 || checkNonElements ) {
+                                       return matcher( elem, context, xml );
+                               }
+                       }
+               } :
+
+               // Check against all ancestor/preceding elements
+               function( elem, context, xml ) {
+                       var oldCache, outerCache,
+                               newCache = [ dirruns, doneName ];
+
+                       // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+                       if ( xml ) {
+                               while ( (elem = elem[ dir ]) ) {
+                                       if ( elem.nodeType === 1 || checkNonElements ) {
+                                               if ( matcher( elem, context, xml ) ) {
+                                                       return true;
+                                               }
+                                       }
+                               }
+                       } else {
+                               while ( (elem = elem[ dir ]) ) {
+                                       if ( elem.nodeType === 1 || checkNonElements ) {
+                                               outerCache = elem[ expando ] || (elem[ expando ] = {});
+                                               if ( (oldCache = outerCache[ dir ]) &&
+                                                       oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+                                                       // Assign to newCache so results back-propagate to previous elements
+                                                       return (newCache[ 2 ] = oldCache[ 2 ]);
+                                               } else {
+                                                       // Reuse newcache so results back-propagate to previous elements
+                                                       outerCache[ dir ] = newCache;
+
+                                                       // A match means we're done; a fail means we have to keep checking
+                                                       if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+                                                               return true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               };
+}
+
+function elementMatcher( matchers ) {
+       return matchers.length > 1 ?
+               function( elem, context, xml ) {
+                       var i = matchers.length;
+                       while ( i-- ) {
+                               if ( !matchers[i]( elem, context, xml ) ) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               } :
+               matchers[0];
+}
+
+function multipleContexts( selector, contexts, results ) {
+       var i = 0,
+               len = contexts.length;
+       for ( ; i < len; i++ ) {
+               Sizzle( selector, contexts[i], results );
+       }
+       return results;
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+       var elem,
+               newUnmatched = [],
+               i = 0,
+               len = unmatched.length,
+               mapped = map != null;
+
+       for ( ; i < len; i++ ) {
+               if ( (elem = unmatched[i]) ) {
+                       if ( !filter || filter( elem, context, xml ) ) {
+                               newUnmatched.push( elem );
+                               if ( mapped ) {
+                                       map.push( i );
+                               }
+                       }
+               }
+       }
+
+       return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+       if ( postFilter && !postFilter[ expando ] ) {
+               postFilter = setMatcher( postFilter );
+       }
+       if ( postFinder && !postFinder[ expando ] ) {
+               postFinder = setMatcher( postFinder, postSelector );
+       }
+       return markFunction(function( seed, results, context, xml ) {
+               var temp, i, elem,
+                       preMap = [],
+                       postMap = [],
+                       preexisting = results.length,
+
+                       // Get initial elements from seed or context
+                       elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+                       // Prefilter to get matcher input, preserving a map for seed-results synchronization
+                       matcherIn = preFilter && ( seed || !selector ) ?
+                               condense( elems, preMap, preFilter, context, xml ) :
+                               elems,
+
+                       matcherOut = matcher ?
+                               // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+                               postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+                                       // ...intermediate processing is necessary
+                                       [] :
+
+                                       // ...otherwise use results directly
+                                       results :
+                               matcherIn;
+
+               // Find primary matches
+               if ( matcher ) {
+                       matcher( matcherIn, matcherOut, context, xml );
+               }
+
+               // Apply postFilter
+               if ( postFilter ) {
+                       temp = condense( matcherOut, postMap );
+                       postFilter( temp, [], context, xml );
+
+                       // Un-match failing elements by moving them back to matcherIn
+                       i = temp.length;
+                       while ( i-- ) {
+                               if ( (elem = temp[i]) ) {
+                                       matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+                               }
+                       }
+               }
+
+               if ( seed ) {
+                       if ( postFinder || preFilter ) {
+                               if ( postFinder ) {
+                                       // Get the final matcherOut by condensing this intermediate into postFinder contexts
+                                       temp = [];
+                                       i = matcherOut.length;
+                                       while ( i-- ) {
+                                               if ( (elem = matcherOut[i]) ) {
+                                                       // Restore matcherIn since elem is not yet a final match
+                                                       temp.push( (matcherIn[i] = elem) );
+                                               }
+                                       }
+                                       postFinder( null, (matcherOut = []), temp, xml );
+                               }
+
+                               // Move matched elements from seed to results to keep them synchronized
+                               i = matcherOut.length;
+                               while ( i-- ) {
+                                       if ( (elem = matcherOut[i]) &&
+                                               (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
+
+                                               seed[temp] = !(results[temp] = elem);
+                                       }
+                               }
+                       }
+
+               // Add elements to results, through postFinder if defined
+               } else {
+                       matcherOut = condense(
+                               matcherOut === results ?
+                                       matcherOut.splice( preexisting, matcherOut.length ) :
+                                       matcherOut
+                       );
+                       if ( postFinder ) {
+                               postFinder( null, results, matcherOut, xml );
+                       } else {
+                               push.apply( results, matcherOut );
+                       }
+               }
+       });
+}
+
+function matcherFromTokens( tokens ) {
+       var checkContext, matcher, j,
+               len = tokens.length,
+               leadingRelative = Expr.relative[ tokens[0].type ],
+               implicitRelative = leadingRelative || Expr.relative[" "],
+               i = leadingRelative ? 1 : 0,
+
+               // The foundational matcher ensures that elements are reachable from top-level context(s)
+               matchContext = addCombinator( function( elem ) {
+                       return elem === checkContext;
+               }, implicitRelative, true ),
+               matchAnyContext = addCombinator( function( elem ) {
+                       return indexOf.call( checkContext, elem ) > -1;
+               }, implicitRelative, true ),
+               matchers = [ function( elem, context, xml ) {
+                       return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+                               (checkContext = context).nodeType ?
+                                       matchContext( elem, context, xml ) :
+                                       matchAnyContext( elem, context, xml ) );
+               } ];
+
+       for ( ; i < len; i++ ) {
+               if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+                       matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+               } else {
+                       matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+                       // Return special upon seeing a positional matcher
+                       if ( matcher[ expando ] ) {
+                               // Find the next relative operator (if any) for proper handling
+                               j = ++i;
+                               for ( ; j < len; j++ ) {
+                                       if ( Expr.relative[ tokens[j].type ] ) {
+                                               break;
+                                       }
+                               }
+                               return setMatcher(
+                                       i > 1 && elementMatcher( matchers ),
+                                       i > 1 && toSelector(
+                                               // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+                                               tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+                                       ).replace( rtrim, "$1" ),
+                                       matcher,
+                                       i < j && matcherFromTokens( tokens.slice( i, j ) ),
+                                       j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+                                       j < len && toSelector( tokens )
+                               );
+                       }
+                       matchers.push( matcher );
+               }
+       }
+
+       return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+       var bySet = setMatchers.length > 0,
+               byElement = elementMatchers.length > 0,
+               superMatcher = function( seed, context, xml, results, outermost ) {
+                       var elem, j, matcher,
+                               matchedCount = 0,
+                               i = "0",
+                               unmatched = seed && [],
+                               setMatched = [],
+                               contextBackup = outermostContext,
+                               // We must always have either seed elements or outermost context
+                               elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+                               // Use integer dirruns iff this is the outermost matcher
+                               dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+                               len = elems.length;
+
+                       if ( outermost ) {
+                               outermostContext = context !== document && context;
+                       }
+
+                       // Add elements passing elementMatchers directly to results
+                       // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
+                       // Support: IE<9, Safari
+                       // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
+                       for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+                               if ( byElement && elem ) {
+                                       j = 0;
+                                       while ( (matcher = elementMatchers[j++]) ) {
+                                               if ( matcher( elem, context, xml ) ) {
+                                                       results.push( elem );
+                                                       break;
+                                               }
+                                       }
+                                       if ( outermost ) {
+                                               dirruns = dirrunsUnique;
+                                       }
+                               }
+
+                               // Track unmatched elements for set filters
+                               if ( bySet ) {
+                                       // They will have gone through all possible matchers
+                                       if ( (elem = !matcher && elem) ) {
+                                               matchedCount--;
+                                       }
+
+                                       // Lengthen the array for every element, matched or not
+                                       if ( seed ) {
+                                               unmatched.push( elem );
+                                       }
+                               }
+                       }
+
+                       // Apply set filters to unmatched elements
+                       matchedCount += i;
+                       if ( bySet && i !== matchedCount ) {
+                               j = 0;
+                               while ( (matcher = setMatchers[j++]) ) {
+                                       matcher( unmatched, setMatched, context, xml );
+                               }
+
+                               if ( seed ) {
+                                       // Reintegrate element matches to eliminate the need for sorting
+                                       if ( matchedCount > 0 ) {
+                                               while ( i-- ) {
+                                                       if ( !(unmatched[i] || setMatched[i]) ) {
+                                                               setMatched[i] = pop.call( results );
+                                                       }
+                                               }
+                                       }
+
+                                       // Discard index placeholder values to get only actual matches
+                                       setMatched = condense( setMatched );
+                               }
+
+                               // Add matches to results
+                               push.apply( results, setMatched );
+
+                               // Seedless set matches succeeding multiple successful matchers stipulate sorting
+                               if ( outermost && !seed && setMatched.length > 0 &&
+                                       ( matchedCount + setMatchers.length ) > 1 ) {
+
+                                       Sizzle.uniqueSort( results );
+                               }
+                       }
+
+                       // Override manipulation of globals by nested matchers
+                       if ( outermost ) {
+                               dirruns = dirrunsUnique;
+                               outermostContext = contextBackup;
+                       }
+
+                       return unmatched;
+               };
+
+       return bySet ?
+               markFunction( superMatcher ) :
+               superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+       var i,
+               setMatchers = [],
+               elementMatchers = [],
+               cached = compilerCache[ selector + " " ];
+
+       if ( !cached ) {
+               // Generate a function of recursive functions that can be used to check each element
+               if ( !match ) {
+                       match = tokenize( selector );
+               }
+               i = match.length;
+               while ( i-- ) {
+                       cached = matcherFromTokens( match[i] );
+                       if ( cached[ expando ] ) {
+                               setMatchers.push( cached );
+                       } else {
+                               elementMatchers.push( cached );
+                       }
+               }
+
+               // Cache the compiled function
+               cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+
+               // Save selector and tokenization
+               cached.selector = selector;
+       }
+       return cached;
+};
+
+/**
+ * A low-level selection function that works with Sizzle's compiled
+ *  selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ *  selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+select = Sizzle.select = function( selector, context, results, seed ) {
+       var i, tokens, token, type, find,
+               compiled = typeof selector === "function" && selector,
+               match = !seed && tokenize( (selector = compiled.selector || selector) );
+
+       results = results || [];
+
+       // Try to minimize operations if there is no seed and only one group
+       if ( match.length === 1 ) {
+
+               // Take a shortcut and set the context if the root selector is an ID
+               tokens = match[0] = match[0].slice( 0 );
+               if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+                               support.getById && context.nodeType === 9 && documentIsHTML &&
+                               Expr.relative[ tokens[1].type ] ) {
+
+                       context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+                       if ( !context ) {
+                               return results;
+
+                       // Precompiled matchers will still verify ancestry, so step up a level
+                       } else if ( compiled ) {
+                               context = context.parentNode;
+                       }
+
+                       selector = selector.slice( tokens.shift().value.length );
+               }
+
+               // Fetch a seed set for right-to-left matching
+               i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+               while ( i-- ) {
+                       token = tokens[i];
+
+                       // Abort if we hit a combinator
+                       if ( Expr.relative[ (type = token.type) ] ) {
+                               break;
+                       }
+                       if ( (find = Expr.find[ type ]) ) {
+                               // Search, expanding context for leading sibling combinators
+                               if ( (seed = find(
+                                       token.matches[0].replace( runescape, funescape ),
+                                       rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
+                               )) ) {
+
+                                       // If seed is empty or no tokens remain, we can return early
+                                       tokens.splice( i, 1 );
+                                       selector = seed.length && toSelector( tokens );
+                                       if ( !selector ) {
+                                               push.apply( results, seed );
+                                               return results;
+                                       }
+
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       // Compile and execute a filtering function if one is not provided
+       // Provide `match` to avoid retokenization if we modified the selector above
+       ( compiled || compile( selector, match ) )(
+               seed,
+               context,
+               !documentIsHTML,
+               results,
+               rsibling.test( selector ) && testContext( context.parentNode ) || context
+       );
+       return results;
+};
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome<14
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+       // Should return 1, but returns 4 (following)
+       return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( div ) {
+       div.innerHTML = "<a href='#'></a>";
+       return div.firstChild.getAttribute("href") === "#" ;
+}) ) {
+       addHandle( "type|href|height|width", function( elem, name, isXML ) {
+               if ( !isXML ) {
+                       return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+               }
+       });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( div ) {
+       div.innerHTML = "<input/>";
+       div.firstChild.setAttribute( "value", "" );
+       return div.firstChild.getAttribute( "value" ) === "";
+}) ) {
+       addHandle( "value", function( elem, name, isXML ) {
+               if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+                       return elem.defaultValue;
+               }
+       });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+       return div.getAttribute("disabled") == null;
+}) ) {
+       addHandle( booleans, function( elem, name, isXML ) {
+               var val;
+               if ( !isXML ) {
+                       return elem[ name ] === true ? name.toLowerCase() :
+                                       (val = elem.getAttributeNode( name )) && val.specified ?
+                                       val.value :
+                               null;
+               }
+       });
+}
+
+return Sizzle;
+
+})( window );
+
+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.pseudos;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
+
+
+
+var risSimple = /^.[^:#\[\.,]*$/;
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+       if ( jQuery.isFunction( qualifier ) ) {
+               return jQuery.grep( elements, function( elem, i ) {
+                       /* jshint -W018 */
+                       return !!qualifier.call( elem, i, elem ) !== not;
+               });
+
+       }
+
+       if ( qualifier.nodeType ) {
+               return jQuery.grep( elements, function( elem ) {
+                       return ( elem === qualifier ) !== not;
+               });
+
+       }
+
+       if ( typeof qualifier === "string" ) {
+               if ( risSimple.test( qualifier ) ) {
+                       return jQuery.filter( qualifier, elements, not );
+               }
+
+               qualifier = jQuery.filter( qualifier, elements );
+       }
+
+       return jQuery.grep( elements, function( elem ) {
+               return ( indexOf.call( qualifier, elem ) >= 0 ) !== not;
+       });
+}
+
+jQuery.filter = function( expr, elems, not ) {
+       var elem = elems[ 0 ];
+
+       if ( not ) {
+               expr = ":not(" + expr + ")";
+       }
+
+       return elems.length === 1 && elem.nodeType === 1 ?
+               jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
+               jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+                       return elem.nodeType === 1;
+               }));
+};
+
+jQuery.fn.extend({
+       find: function( selector ) {
+               var i,
+                       len = this.length,
+                       ret = [],
+                       self = this;
+
+               if ( typeof selector !== "string" ) {
+                       return this.pushStack( jQuery( selector ).filter(function() {
+                               for ( i = 0; i < len; i++ ) {
+                                       if ( jQuery.contains( self[ i ], this ) ) {
+                                               return true;
+                                       }
+                               }
+                       }) );
+               }
+
+               for ( i = 0; i < len; i++ ) {
+                       jQuery.find( selector, self[ i ], ret );
+               }
+
+               // Needed because $( selector, context ) becomes $( context ).find( selector )
+               ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+               ret.selector = this.selector ? this.selector + " " + selector : selector;
+               return ret;
+       },
+       filter: function( selector ) {
+               return this.pushStack( winnow(this, selector || [], false) );
+       },
+       not: function( selector ) {
+               return this.pushStack( winnow(this, selector || [], true) );
+       },
+       is: function( selector ) {
+               return !!winnow(
+                       this,
+
+                       // If this is a positional/relative selector, check membership in the returned set
+                       // so $("p:first").is("p:last") won't return true for a doc with two "p".
+                       typeof selector === "string" && rneedsContext.test( selector ) ?
+                               jQuery( selector ) :
+                               selector || [],
+                       false
+               ).length;
+       }
+});
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+var rootjQuery,
+
+       // A simple way to check for HTML strings
+       // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+       // Strict HTML recognition (#11290: must start with <)
+       rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+       init = jQuery.fn.init = function( selector, context ) {
+               var match, elem;
+
+               // HANDLE: $(""), $(null), $(undefined), $(false)
+               if ( !selector ) {
+                       return this;
+               }
+
+               // Handle HTML strings
+               if ( typeof selector === "string" ) {
+                       if ( selector[0] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) {
+                               // Assume that strings that start and end with <> are HTML and skip the regex check
+                               match = [ null, selector, null ];
+
+                       } else {
+                               match = rquickExpr.exec( selector );
+                       }
+
+                       // Match html or make sure no context is specified for #id
+                       if ( match && (match[1] || !context) ) {
+
+                               // HANDLE: $(html) -> $(array)
+                               if ( match[1] ) {
+                                       context = context instanceof jQuery ? context[0] : context;
+
+                                       // scripts is true for back-compat
+                                       // Intentionally let the error be thrown if parseHTML is not present
+                                       jQuery.merge( this, jQuery.parseHTML(
+                                               match[1],
+                                               context && context.nodeType ? context.ownerDocument || context : document,
+                                               true
+                                       ) );
+
+                                       // HANDLE: $(html, props)
+                                       if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+                                               for ( match in context ) {
+                                                       // Properties of context are called as methods if possible
+                                                       if ( jQuery.isFunction( this[ match ] ) ) {
+                                                               this[ match ]( context[ match ] );
+
+                                                       // ...and otherwise set as attributes
+                                                       } else {
+                                                               this.attr( match, context[ match ] );
+                                                       }
+                                               }
+                                       }
+
+                                       return this;
+
+                               // HANDLE: $(#id)
+                               } else {
+                                       elem = document.getElementById( match[2] );
+
+                                       // Check parentNode to catch when Blackberry 4.6 returns
+                                       // nodes that are no longer in the document #6963
+                                       if ( elem && elem.parentNode ) {
+                                               // Inject the element directly into the jQuery object
+                                               this.length = 1;
+                                               this[0] = elem;
+                                       }
+
+                                       this.context = document;
+                                       this.selector = selector;
+                                       return this;
+                               }
+
+                       // HANDLE: $(expr, $(...))
+                       } else if ( !context || context.jquery ) {
+                               return ( context || rootjQuery ).find( selector );
+
+                       // HANDLE: $(expr, context)
+                       // (which is just equivalent to: $(context).find(expr)
+                       } else {
+                               return this.constructor( context ).find( selector );
+                       }
+
+               // HANDLE: $(DOMElement)
+               } else if ( selector.nodeType ) {
+                       this.context = this[0] = selector;
+                       this.length = 1;
+                       return this;
+
+               // HANDLE: $(function)
+               // Shortcut for document ready
+               } else if ( jQuery.isFunction( selector ) ) {
+                       return typeof rootjQuery.ready !== "undefined" ?
+                               rootjQuery.ready( selector ) :
+                               // Execute immediately if ready is not present
+                               selector( jQuery );
+               }
+
+               if ( selector.selector !== undefined ) {
+                       this.selector = selector.selector;
+                       this.context = selector.context;
+               }
+
+               return jQuery.makeArray( selector, this );
+       };
+
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
+
+// Initialize central reference
+rootjQuery = jQuery( document );
+
+
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+       // methods guaranteed to produce a unique set when starting from a unique set
+       guaranteedUnique = {
+               children: true,
+               contents: true,
+               next: true,
+               prev: true
+       };
+
+jQuery.extend({
+       dir: function( elem, dir, until ) {
+               var matched = [],
+                       truncate = until !== undefined;
+
+               while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
+                       if ( elem.nodeType === 1 ) {
+                               if ( truncate && jQuery( elem ).is( until ) ) {
+                                       break;
+                               }
+                               matched.push( elem );
+                       }
+               }
+               return matched;
+       },
+
+       sibling: function( n, elem ) {
+               var matched = [];
+
+               for ( ; n; n = n.nextSibling ) {
+                       if ( n.nodeType === 1 && n !== elem ) {
+                               matched.push( n );
+                       }
+               }
+
+               return matched;
+       }
+});
+
+jQuery.fn.extend({
+       has: function( target ) {
+               var targets = jQuery( target, this ),
+                       l = targets.length;
+
+               return this.filter(function() {
+                       var i = 0;
+                       for ( ; i < l; i++ ) {
+                               if ( jQuery.contains( this, targets[i] ) ) {
+                                       return true;
+                               }
+                       }
+               });
+       },
+
+       closest: function( selectors, context ) {
+               var cur,
+                       i = 0,
+                       l = this.length,
+                       matched = [],
+                       pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+                               jQuery( selectors, context || this.context ) :
+                               0;
+
+               for ( ; i < l; i++ ) {
+                       for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
+                               // Always skip document fragments
+                               if ( cur.nodeType < 11 && (pos ?
+                                       pos.index(cur) > -1 :
+
+                                       // Don't pass non-elements to Sizzle
+                                       cur.nodeType === 1 &&
+                                               jQuery.find.matchesSelector(cur, selectors)) ) {
+
+                                       matched.push( cur );
+                                       break;
+                               }
+                       }
+               }
+
+               return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
+       },
+
+       // Determine the position of an element within
+       // the matched set of elements
+       index: function( elem ) {
+
+               // No argument, return index in parent
+               if ( !elem ) {
+                       return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+               }
+
+               // index in selector
+               if ( typeof elem === "string" ) {
+                       return indexOf.call( jQuery( elem ), this[ 0 ] );
+               }
+
+               // Locate the position of the desired element
+               return indexOf.call( this,
+
+                       // If it receives a jQuery object, the first element is used
+                       elem.jquery ? elem[ 0 ] : elem
+               );
+       },
+
+       add: function( selector, context ) {
+               return this.pushStack(
+                       jQuery.unique(
+                               jQuery.merge( this.get(), jQuery( selector, context ) )
+                       )
+               );
+       },
+
+       addBack: function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter(selector)
+               );
+       }
+});
+
+function sibling( cur, dir ) {
+       while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
+       return cur;
+}
+
+jQuery.each({
+       parent: function( elem ) {
+               var parent = elem.parentNode;
+               return parent && parent.nodeType !== 11 ? parent : null;
+       },
+       parents: function( elem ) {
+               return jQuery.dir( elem, "parentNode" );
+       },
+       parentsUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "parentNode", until );
+       },
+       next: function( elem ) {
+               return sibling( elem, "nextSibling" );
+       },
+       prev: function( elem ) {
+               return sibling( elem, "previousSibling" );
+       },
+       nextAll: function( elem ) {
+               return jQuery.dir( elem, "nextSibling" );
+       },
+       prevAll: function( elem ) {
+               return jQuery.dir( elem, "previousSibling" );
+       },
+       nextUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "nextSibling", until );
+       },
+       prevUntil: function( elem, i, until ) {
+               return jQuery.dir( elem, "previousSibling", until );
+       },
+       siblings: function( elem ) {
+               return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
+       },
+       children: function( elem ) {
+               return jQuery.sibling( elem.firstChild );
+       },
+       contents: function( elem ) {
+               return elem.contentDocument || jQuery.merge( [], elem.childNodes );
+       }
+}, function( name, fn ) {
+       jQuery.fn[ name ] = function( until, selector ) {
+               var matched = jQuery.map( this, fn, until );
+
+               if ( name.slice( -5 ) !== "Until" ) {
+                       selector = until;
+               }
+
+               if ( selector && typeof selector === "string" ) {
+                       matched = jQuery.filter( selector, matched );
+               }
+
+               if ( this.length > 1 ) {
+                       // Remove duplicates
+                       if ( !guaranteedUnique[ name ] ) {
+                               jQuery.unique( matched );
+                       }
+
+                       // Reverse order for parents* and prev-derivatives
+                       if ( rparentsprev.test( name ) ) {
+                               matched.reverse();
+                       }
+               }
+
+               return this.pushStack( matched );
+       };
+});
+var rnotwhite = (/\S+/g);
+
+
+
+// String to Object options format cache
+var optionsCache = {};
+
+// Convert String-formatted options into Object-formatted ones and store in cache
+function createOptions( options ) {
+       var object = optionsCache[ options ] = {};
+       jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
+               object[ flag ] = true;
+       });
+       return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ *     options: an optional list of space-separated options that will change how
+ *                     the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *     once:                   will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *     memory:                 will keep track of previous values and will call any callback added
+ *                                     after the list has been fired right away with the latest "memorized"
+ *                                     values (like a Deferred)
+ *
+ *     unique:                 will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *     stopOnFalse:    interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+       // Convert options from String-formatted to Object-formatted if needed
+       // (we check in cache first)
+       options = typeof options === "string" ?
+               ( optionsCache[ options ] || createOptions( options ) ) :
+               jQuery.extend( {}, options );
+
+       var // Last fire value (for non-forgettable lists)
+               memory,
+               // Flag to know if list was already fired
+               fired,
+               // Flag to know if list is currently firing
+               firing,
+               // First callback to fire (used internally by add and fireWith)
+               firingStart,
+               // End of the loop when firing
+               firingLength,
+               // Index of currently firing callback (modified by remove if needed)
+               firingIndex,
+               // Actual callback list
+               list = [],
+               // Stack of fire calls for repeatable lists
+               stack = !options.once && [],
+               // Fire callbacks
+               fire = function( data ) {
+                       memory = options.memory && data;
+                       fired = true;
+                       firingIndex = firingStart || 0;
+                       firingStart = 0;
+                       firingLength = list.length;
+                       firing = true;
+                       for ( ; list && firingIndex < firingLength; firingIndex++ ) {
+                               if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
+                                       memory = false; // To prevent further calls using add
+                                       break;
+                               }
+                       }
+                       firing = false;
+                       if ( list ) {
+                               if ( stack ) {
+                                       if ( stack.length ) {
+                                               fire( stack.shift() );
+                                       }
+                               } else if ( memory ) {
+                                       list = [];
+                               } else {
+                                       self.disable();
+                               }
+                       }
+               },
+               // Actual Callbacks object
+               self = {
+                       // Add a callback or a collection of callbacks to the list
+                       add: function() {
+                               if ( list ) {
+                                       // First, we save the current length
+                                       var start = list.length;
+                                       (function add( args ) {
+                                               jQuery.each( args, function( _, arg ) {
+                                                       var type = jQuery.type( arg );
+                                                       if ( type === "function" ) {
+                                                               if ( !options.unique || !self.has( arg ) ) {
+                                                                       list.push( arg );
+                                                               }
+                                                       } else if ( arg && arg.length && type !== "string" ) {
+                                                               // Inspect recursively
+                                                               add( arg );
+                                                       }
+                                               });
+                                       })( arguments );
+                                       // Do we need to add the callbacks to the
+                                       // current firing batch?
+                                       if ( firing ) {
+                                               firingLength = list.length;
+                                       // With memory, if we're not firing then
+                                       // we should call right away
+                                       } else if ( memory ) {
+                                               firingStart = start;
+                                               fire( memory );
+                                       }
+                               }
+                               return this;
+                       },
+                       // Remove a callback from the list
+                       remove: function() {
+                               if ( list ) {
+                                       jQuery.each( arguments, function( _, arg ) {
+                                               var index;
+                                               while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+                                                       list.splice( index, 1 );
+                                                       // Handle firing indexes
+                                                       if ( firing ) {
+                                                               if ( index <= firingLength ) {
+                                                                       firingLength--;
+                                                               }
+                                                               if ( index <= firingIndex ) {
+                                                                       firingIndex--;
+                                                               }
+                                                       }
+                                               }
+                                       });
+                               }
+                               return this;
+                       },
+                       // Check if a given callback is in the list.
+                       // If no argument is given, return whether or not list has callbacks attached.
+                       has: function( fn ) {
+                               return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+                       },
+                       // Remove all callbacks from the list
+                       empty: function() {
+                               list = [];
+                               firingLength = 0;
+                               return this;
+                       },
+                       // Have the list do nothing anymore
+                       disable: function() {
+                               list = stack = memory = undefined;
+                               return this;
+                       },
+                       // Is it disabled?
+                       disabled: function() {
+                               return !list;
+                       },
+                       // Lock the list in its current state
+                       lock: function() {
+                               stack = undefined;
+                               if ( !memory ) {
+                                       self.disable();
+                               }
+                               return this;
+                       },
+                       // Is it locked?
+                       locked: function() {
+                               return !stack;
+                       },
+                       // Call all callbacks with the given context and arguments
+                       fireWith: function( context, args ) {
+                               if ( list && ( !fired || stack ) ) {
+                                       args = args || [];
+                                       args = [ context, args.slice ? args.slice() : args ];
+                                       if ( firing ) {
+                                               stack.push( args );
+                                       } else {
+                                               fire( args );
+                                       }
+                               }
+                               return this;
+                       },
+                       // Call all the callbacks with the given arguments
+                       fire: function() {
+                               self.fireWith( this, arguments );
+                               return this;
+                       },
+                       // To know if the callbacks have already been called at least once
+                       fired: function() {
+                               return !!fired;
+                       }
+               };
+
+       return self;
+};
+
+
+jQuery.extend({
+
+       Deferred: function( func ) {
+               var tuples = [
+                               // action, add listener, listener list, final state
+                               [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
+                               [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
+                               [ "notify", "progress", jQuery.Callbacks("memory") ]
+                       ],
+                       state = "pending",
+                       promise = {
+                               state: function() {
+                                       return state;
+                               },
+                               always: function() {
+                                       deferred.done( arguments ).fail( arguments );
+                                       return this;
+                               },
+                               then: function( /* fnDone, fnFail, fnProgress */ ) {
+                                       var fns = arguments;
+                                       return jQuery.Deferred(function( newDefer ) {
+                                               jQuery.each( tuples, function( i, tuple ) {
+                                                       var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+                                                       // deferred[ done | fail | progress ] for forwarding actions to newDefer
+                                                       deferred[ tuple[1] ](function() {
+                                                               var returned = fn && fn.apply( this, arguments );
+                                                               if ( returned && jQuery.isFunction( returned.promise ) ) {
+                                                                       returned.promise()
+                                                                               .done( newDefer.resolve )
+                                                                               .fail( newDefer.reject )
+                                                                               .progress( newDefer.notify );
+                                                               } else {
+                                                                       newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+                                                               }
+                                                       });
+                                               });
+                                               fns = null;
+                                       }).promise();
+                               },
+                               // Get a promise for this deferred
+                               // If obj is provided, the promise aspect is added to the object
+                               promise: function( obj ) {
+                                       return obj != null ? jQuery.extend( obj, promise ) : promise;
+                               }
+                       },
+                       deferred = {};
+
+               // Keep pipe for back-compat
+               promise.pipe = promise.then;
+
+               // Add list-specific methods
+               jQuery.each( tuples, function( i, tuple ) {
+                       var list = tuple[ 2 ],
+                               stateString = tuple[ 3 ];
+
+                       // promise[ done | fail | progress ] = list.add
+                       promise[ tuple[1] ] = list.add;
+
+                       // Handle state
+                       if ( stateString ) {
+                               list.add(function() {
+                                       // state = [ resolved | rejected ]
+                                       state = stateString;
+
+                               // [ reject_list | resolve_list ].disable; progress_list.lock
+                               }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+                       }
+
+                       // deferred[ resolve | reject | notify ]
+                       deferred[ tuple[0] ] = function() {
+                               deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+                               return this;
+                       };
+                       deferred[ tuple[0] + "With" ] = list.fireWith;
+               });
+
+               // Make the deferred a promise
+               promise.promise( deferred );
+
+               // Call given func if any
+               if ( func ) {
+                       func.call( deferred, deferred );
+               }
+
+               // All done!
+               return deferred;
+       },
+
+       // Deferred helper
+       when: function( subordinate /* , ..., subordinateN */ ) {
+               var i = 0,
+                       resolveValues = slice.call( arguments ),
+                       length = resolveValues.length,
+
+                       // the count of uncompleted subordinates
+                       remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+                       // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
+                       deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+                       // Update function for both resolve and progress values
+                       updateFunc = function( i, contexts, values ) {
+                               return function( value ) {
+                                       contexts[ i ] = this;
+                                       values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+                                       if ( values === progressValues ) {
+                                               deferred.notifyWith( contexts, values );
+                                       } else if ( !( --remaining ) ) {
+                                               deferred.resolveWith( contexts, values );
+                                       }
+                               };
+                       },
+
+                       progressValues, progressContexts, resolveContexts;
+
+               // add listeners to Deferred subordinates; treat others as resolved
+               if ( length > 1 ) {
+                       progressValues = new Array( length );
+                       progressContexts = new Array( length );
+                       resolveContexts = new Array( length );
+                       for ( ; i < length; i++ ) {
+                               if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+                                       resolveValues[ i ].promise()
+                                               .done( updateFunc( i, resolveContexts, resolveValues ) )
+                                               .fail( deferred.reject )
+                                               .progress( updateFunc( i, progressContexts, progressValues ) );
+                               } else {
+                                       --remaining;
+                               }
+                       }
+               }
+
+               // if we're not waiting on anything, resolve the master
+               if ( !remaining ) {
+                       deferred.resolveWith( resolveContexts, resolveValues );
+               }
+
+               return deferred.promise();
+       }
+});
+
+
+// The deferred used on DOM ready
+var readyList;
+
+jQuery.fn.ready = function( fn ) {
+       // Add the callback
+       jQuery.ready.promise().done( fn );
+
+       return this;
+};
+
+jQuery.extend({
+       // Is the DOM ready to be used? Set to true once it occurs.
+       isReady: false,
+
+       // A counter to track how many items to wait for before
+       // the ready event fires. See #6781
+       readyWait: 1,
+
+       // Hold (or release) the ready event
+       holdReady: function( hold ) {
+               if ( hold ) {
+                       jQuery.readyWait++;
+               } else {
+                       jQuery.ready( true );
+               }
+       },
+
+       // Handle when the DOM is ready
+       ready: function( wait ) {
+
+               // Abort if there are pending holds or we're already ready
+               if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+                       return;
+               }
+
+               // Remember that the DOM is ready
+               jQuery.isReady = true;
+
+               // If a normal DOM Ready event fired, decrement, and wait if need be
+               if ( wait !== true && --jQuery.readyWait > 0 ) {
+                       return;
+               }
+
+               // If there are functions bound, to execute
+               readyList.resolveWith( document, [ jQuery ] );
+
+               // Trigger any bound ready events
+               if ( jQuery.fn.triggerHandler ) {
+                       jQuery( document ).triggerHandler( "ready" );
+                       jQuery( document ).off( "ready" );
+               }
+       }
+});
+
+/**
+ * The ready event handler and self cleanup method
+ */
+function completed() {
+       document.removeEventListener( "DOMContentLoaded", completed, false );
+       window.removeEventListener( "load", completed, false );
+       jQuery.ready();
+}
+
+jQuery.ready.promise = function( obj ) {
+       if ( !readyList ) {
+
+               readyList = jQuery.Deferred();
+
+               // Catch cases where $(document).ready() is called after the browser event has already occurred.
+               // we once tried to use readyState "interactive" here, but it caused issues like the one
+               // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
+               if ( document.readyState === "complete" ) {
+                       // Handle it asynchronously to allow scripts the opportunity to delay ready
+                       setTimeout( jQuery.ready );
+
+               } else {
+
+                       // Use the handy event callback
+                       document.addEventListener( "DOMContentLoaded", completed, false );
+
+                       // A fallback to window.onload, that will always work
+                       window.addEventListener( "load", completed, false );
+               }
+       }
+       return readyList.promise( obj );
+};
+
+// Kick off the DOM ready check even if the user does not
+jQuery.ready.promise();
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+       var i = 0,
+               len = elems.length,
+               bulk = key == null;
+
+       // Sets many values
+       if ( jQuery.type( key ) === "object" ) {
+               chainable = true;
+               for ( i in key ) {
+                       jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+               }
+
+       // Sets one value
+       } else if ( value !== undefined ) {
+               chainable = true;
+
+               if ( !jQuery.isFunction( value ) ) {
+                       raw = true;
+               }
+
+               if ( bulk ) {
+                       // Bulk operations run against the entire set
+                       if ( raw ) {
+                               fn.call( elems, value );
+                               fn = null;
+
+                       // ...except when executing function values
+                       } else {
+                               bulk = fn;
+                               fn = function( elem, key, value ) {
+                                       return bulk.call( jQuery( elem ), value );
+                               };
+                       }
+               }
+
+               if ( fn ) {
+                       for ( ; i < len; i++ ) {
+                               fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+                       }
+               }
+       }
+
+       return chainable ?
+               elems :
+
+               // Gets
+               bulk ?
+                       fn.call( elems ) :
+                       len ? fn( elems[0], key ) : emptyGet;
+};
+
+
+/**
+ * Determines whether an object can have data
+ */
+jQuery.acceptData = function( owner ) {
+       // Accepts only:
+       //  - Node
+       //    - Node.ELEMENT_NODE
+       //    - Node.DOCUMENT_NODE
+       //  - Object
+       //    - Any
+       /* jshint -W018 */
+       return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+};
+
+
+function Data() {
+       // Support: Android < 4,
+       // Old WebKit does not have Object.preventExtensions/freeze method,
+       // return new empty object instead with no [[set]] accessor
+       Object.defineProperty( this.cache = {}, 0, {
+               get: function() {
+                       return {};
+               }
+       });
+
+       this.expando = jQuery.expando + Math.random();
+}
+
+Data.uid = 1;
+Data.accepts = jQuery.acceptData;
+
+Data.prototype = {
+       key: function( owner ) {
+               // We can accept data for non-element nodes in modern browsers,
+               // but we should not, see #8335.
+               // Always return the key for a frozen object.
+               if ( !Data.accepts( owner ) ) {
+                       return 0;
+               }
+
+               var descriptor = {},
+                       // Check if the owner object already has a cache key
+                       unlock = owner[ this.expando ];
+
+               // If not, create one
+               if ( !unlock ) {
+                       unlock = Data.uid++;
+
+                       // Secure it in a non-enumerable, non-writable property
+                       try {
+                               descriptor[ this.expando ] = { value: unlock };
+                               Object.defineProperties( owner, descriptor );
+
+                       // Support: Android < 4
+                       // Fallback to a less secure definition
+                       } catch ( e ) {
+                               descriptor[ this.expando ] = unlock;
+                               jQuery.extend( owner, descriptor );
+                       }
+               }
+
+               // Ensure the cache object
+               if ( !this.cache[ unlock ] ) {
+                       this.cache[ unlock ] = {};
+               }
+
+               return unlock;
+       },
+       set: function( owner, data, value ) {
+               var prop,
+                       // There may be an unlock assigned to this node,
+                       // if there is no entry for this "owner", create one inline
+                       // and set the unlock as though an owner entry had always existed
+                       unlock = this.key( owner ),
+                       cache = this.cache[ unlock ];
+
+               // Handle: [ owner, key, value ] args
+               if ( typeof data === "string" ) {
+                       cache[ data ] = value;
+
+               // Handle: [ owner, { properties } ] args
+               } else {
+                       // Fresh assignments by object are shallow copied
+                       if ( jQuery.isEmptyObject( cache ) ) {
+                               jQuery.extend( this.cache[ unlock ], data );
+                       // Otherwise, copy the properties one-by-one to the cache object
+                       } else {
+                               for ( prop in data ) {
+                                       cache[ prop ] = data[ prop ];
+                               }
+                       }
+               }
+               return cache;
+       },
+       get: function( owner, key ) {
+               // Either a valid cache is found, or will be created.
+               // New caches will be created and the unlock returned,
+               // allowing direct access to the newly created
+               // empty data object. A valid owner object must be provided.
+               var cache = this.cache[ this.key( owner ) ];
+
+               return key === undefined ?
+                       cache : cache[ key ];
+       },
+       access: function( owner, key, value ) {
+               var stored;
+               // In cases where either:
+               //
+               //   1. No key was specified
+               //   2. A string key was specified, but no value provided
+               //
+               // Take the "read" path and allow the get method to determine
+               // which value to return, respectively either:
+               //
+               //   1. The entire cache object
+               //   2. The data stored at the key
+               //
+               if ( key === undefined ||
+                               ((key && typeof key === "string") && value === undefined) ) {
+
+                       stored = this.get( owner, key );
+
+                       return stored !== undefined ?
+                               stored : this.get( owner, jQuery.camelCase(key) );
+               }
+
+               // [*]When the key is not a string, or both a key and value
+               // are specified, set or extend (existing objects) with either:
+               //
+               //   1. An object of properties
+               //   2. A key and value
+               //
+               this.set( owner, key, value );
+
+               // Since the "set" path can have two possible entry points
+               // return the expected data based on which path was taken[*]
+               return value !== undefined ? value : key;
+       },
+       remove: function( owner, key ) {
+               var i, name, camel,
+                       unlock = this.key( owner ),
+                       cache = this.cache[ unlock ];
+
+               if ( key === undefined ) {
+                       this.cache[ unlock ] = {};
+
+               } else {
+                       // Support array or space separated string of keys
+                       if ( jQuery.isArray( key ) ) {
+                               // If "name" is an array of keys...
+                               // When data is initially created, via ("key", "val") signature,
+                               // keys will be converted to camelCase.
+                               // Since there is no way to tell _how_ a key was added, remove
+                               // both plain key and camelCase key. #12786
+                               // This will only penalize the array argument path.
+                               name = key.concat( key.map( jQuery.camelCase ) );
+                       } else {
+                               camel = jQuery.camelCase( key );
+                               // Try the string as a key before any manipulation
+                               if ( key in cache ) {
+                                       name = [ key, camel ];
+                               } else {
+                                       // If a key with the spaces exists, use it.
+                                       // Otherwise, create an array by matching non-whitespace
+                                       name = camel;
+                                       name = name in cache ?
+                                               [ name ] : ( name.match( rnotwhite ) || [] );
+                               }
+                       }
+
+                       i = name.length;
+                       while ( i-- ) {
+                               delete cache[ name[ i ] ];
+                       }
+               }
+       },
+       hasData: function( owner ) {
+               return !jQuery.isEmptyObject(
+                       this.cache[ owner[ this.expando ] ] || {}
+               );
+       },
+       discard: function( owner ) {
+               if ( owner[ this.expando ] ) {
+                       delete this.cache[ owner[ this.expando ] ];
+               }
+       }
+};
+var data_priv = new Data();
+
+var data_user = new Data();
+
+
+
+/*
+       Implementation Summary
+
+       1. Enforce API surface and semantic compatibility with 1.9.x branch
+       2. Improve the module's maintainability by reducing the storage
+               paths to a single mechanism.
+       3. Use the same single mechanism to support "private" and "user" data.
+       4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+       5. Avoid exposing implementation details on user objects (eg. expando properties)
+       6. Provide a clear path for implementation upgrade to WeakMap in 2014
+*/
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+       rmultiDash = /([A-Z])/g;
+
+function dataAttr( elem, key, data ) {
+       var name;
+
+       // If nothing was found internally, try to fetch any
+       // data from the HTML5 data-* attribute
+       if ( data === undefined && elem.nodeType === 1 ) {
+               name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
+               data = elem.getAttribute( name );
+
+               if ( typeof data === "string" ) {
+                       try {
+                               data = data === "true" ? true :
+                                       data === "false" ? false :
+                                       data === "null" ? null :
+                                       // Only convert to a number if it doesn't change the string
+                                       +data + "" === data ? +data :
+                                       rbrace.test( data ) ? jQuery.parseJSON( data ) :
+                                       data;
+                       } catch( e ) {}
+
+                       // Make sure we set the data so it isn't changed later
+                       data_user.set( elem, key, data );
+               } else {
+                       data = undefined;
+               }
+       }
+       return data;
+}
+
+jQuery.extend({
+       hasData: function( elem ) {
+               return data_user.hasData( elem ) || data_priv.hasData( elem );
+       },
+
+       data: function( elem, name, data ) {
+               return data_user.access( elem, name, data );
+       },
+
+       removeData: function( elem, name ) {
+               data_user.remove( elem, name );
+       },
+
+       // TODO: Now that all calls to _data and _removeData have been replaced
+       // with direct calls to data_priv methods, these can be deprecated.
+       _data: function( elem, name, data ) {
+               return data_priv.access( elem, name, data );
+       },
+
+       _removeData: function( elem, name ) {
+               data_priv.remove( elem, name );
+       }
+});
+
+jQuery.fn.extend({
+       data: function( key, value ) {
+               var i, name, data,
+                       elem = this[ 0 ],
+                       attrs = elem && elem.attributes;
+
+               // Gets all values
+               if ( key === undefined ) {
+                       if ( this.length ) {
+                               data = data_user.get( elem );
+
+                               if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
+                                       i = attrs.length;
+                                       while ( i-- ) {
+
+                                               // Support: IE11+
+                                               // The attrs elements can be null (#14894)
+                                               if ( attrs[ i ] ) {
+                                                       name = attrs[ i ].name;
+                                                       if ( name.indexOf( "data-" ) === 0 ) {
+                                                               name = jQuery.camelCase( name.slice(5) );
+                                                               dataAttr( elem, name, data[ name ] );
+                                                       }
+                                               }
+                                       }
+                                       data_priv.set( elem, "hasDataAttrs", true );
+                               }
+                       }
+
+                       return data;
+               }
+
+               // Sets multiple values
+               if ( typeof key === "object" ) {
+                       return this.each(function() {
+                               data_user.set( this, key );
+                       });
+               }
+
+               return access( this, function( value ) {
+                       var data,
+                               camelKey = jQuery.camelCase( key );
+
+                       // The calling jQuery object (element matches) is not empty
+                       // (and therefore has an element appears at this[ 0 ]) and the
+                       // `value` parameter was not undefined. An empty jQuery object
+                       // will result in `undefined` for elem = this[ 0 ] which will
+                       // throw an exception if an attempt to read a data cache is made.
+                       if ( elem && value === undefined ) {
+                               // Attempt to get data from the cache
+                               // with the key as-is
+                               data = data_user.get( elem, key );
+                               if ( data !== undefined ) {
+                                       return data;
+                               }
+
+                               // Attempt to get data from the cache
+                               // with the key camelized
+                               data = data_user.get( elem, camelKey );
+                               if ( data !== undefined ) {
+                                       return data;
+                               }
+
+                               // Attempt to "discover" the data in
+                               // HTML5 custom data-* attrs
+                               data = dataAttr( elem, camelKey, undefined );
+                               if ( data !== undefined ) {
+                                       return data;
+                               }
+
+                               // We tried really hard, but the data doesn't exist.
+                               return;
+                       }
+
+                       // Set the data...
+                       this.each(function() {
+                               // First, attempt to store a copy or reference of any
+                               // data that might've been store with a camelCased key.
+                               var data = data_user.get( this, camelKey );
+
+                               // For HTML5 data-* attribute interop, we have to
+                               // store property names with dashes in a camelCase form.
+                               // This might not apply to all properties...*
+                               data_user.set( this, camelKey, value );
+
+                               // *... In the case of properties that might _actually_
+                               // have dashes, we need to also store a copy of that
+                               // unchanged property.
+                               if ( key.indexOf("-") !== -1 && data !== undefined ) {
+                                       data_user.set( this, key, value );
+                               }
+                       });
+               }, null, value, arguments.length > 1, null, true );
+       },
+
+       removeData: function( key ) {
+               return this.each(function() {
+                       data_user.remove( this, key );
+               });
+       }
+});
+
+
+jQuery.extend({
+       queue: function( elem, type, data ) {
+               var queue;
+
+               if ( elem ) {
+                       type = ( type || "fx" ) + "queue";
+                       queue = data_priv.get( elem, type );
+
+                       // Speed up dequeue by getting out quickly if this is just a lookup
+                       if ( data ) {
+                               if ( !queue || jQuery.isArray( data ) ) {
+                                       queue = data_priv.access( elem, type, jQuery.makeArray(data) );
+                               } else {
+                                       queue.push( data );
+                               }
+                       }
+                       return queue || [];
+               }
+       },
+
+       dequeue: function( elem, type ) {
+               type = type || "fx";
+
+               var queue = jQuery.queue( elem, type ),
+                       startLength = queue.length,
+                       fn = queue.shift(),
+                       hooks = jQuery._queueHooks( elem, type ),
+                       next = function() {
+                               jQuery.dequeue( elem, type );
+                       };
+
+               // If the fx queue is dequeued, always remove the progress sentinel
+               if ( fn === "inprogress" ) {
+                       fn = queue.shift();
+                       startLength--;
+               }
+
+               if ( fn ) {
+
+                       // Add a progress sentinel to prevent the fx queue from being
+                       // automatically dequeued
+                       if ( type === "fx" ) {
+                               queue.unshift( "inprogress" );
+                       }
+
+                       // clear up the last queue stop function
+                       delete hooks.stop;
+                       fn.call( elem, next, hooks );
+               }
+
+               if ( !startLength && hooks ) {
+                       hooks.empty.fire();
+               }
+       },
+
+       // not intended for public consumption - generates a queueHooks object, or returns the current one
+       _queueHooks: function( elem, type ) {
+               var key = type + "queueHooks";
+               return data_priv.get( elem, key ) || data_priv.access( elem, key, {
+                       empty: jQuery.Callbacks("once memory").add(function() {
+                               data_priv.remove( elem, [ type + "queue", key ] );
+                       })
+               });
+       }
+});
+
+jQuery.fn.extend({
+       queue: function( type, data ) {
+               var setter = 2;
+
+               if ( typeof type !== "string" ) {
+                       data = type;
+                       type = "fx";
+                       setter--;
+               }
+
+               if ( arguments.length < setter ) {
+                       return jQuery.queue( this[0], type );
+               }
+
+               return data === undefined ?
+                       this :
+                       this.each(function() {
+                               var queue = jQuery.queue( this, type, data );
+
+                               // ensure a hooks for this queue
+                               jQuery._queueHooks( this, type );
+
+                               if ( type === "fx" && queue[0] !== "inprogress" ) {
+                                       jQuery.dequeue( this, type );
+                               }
+                       });
+       },
+       dequeue: function( type ) {
+               return this.each(function() {
+                       jQuery.dequeue( this, type );
+               });
+       },
+       clearQueue: function( type ) {
+               return this.queue( type || "fx", [] );
+       },
+       // Get a promise resolved when queues of a certain type
+       // are emptied (fx is the type by default)
+       promise: function( type, obj ) {
+               var tmp,
+                       count = 1,
+                       defer = jQuery.Deferred(),
+                       elements = this,
+                       i = this.length,
+                       resolve = function() {
+                               if ( !( --count ) ) {
+                                       defer.resolveWith( elements, [ elements ] );
+                               }
+                       };
+
+               if ( typeof type !== "string" ) {
+                       obj = type;
+                       type = undefined;
+               }
+               type = type || "fx";
+
+               while ( i-- ) {
+                       tmp = data_priv.get( elements[ i ], type + "queueHooks" );
+                       if ( tmp && tmp.empty ) {
+                               count++;
+                               tmp.empty.add( resolve );
+                       }
+               }
+               resolve();
+               return defer.promise( obj );
+       }
+});
+var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHidden = function( elem, el ) {
+               // isHidden might be called from jQuery#filter function;
+               // in that case, element will be second argument
+               elem = el || elem;
+               return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+       };
+
+var rcheckableType = (/^(?:checkbox|radio)$/i);
+
+
+
+(function() {
+       var fragment = document.createDocumentFragment(),
+               div = fragment.appendChild( document.createElement( "div" ) ),
+               input = document.createElement( "input" );
+
+       // #11217 - WebKit loses check when the name is after the checked attribute
+       // Support: Windows Web Apps (WWA)
+       // `name` and `type` need .setAttribute for WWA
+       input.setAttribute( "type", "radio" );
+       input.setAttribute( "checked", "checked" );
+       input.setAttribute( "name", "t" );
+
+       div.appendChild( input );
+
+       // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
+       // old WebKit doesn't clone checked state correctly in fragments
+       support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+       // Make sure textarea (and checkbox) defaultValue is properly cloned
+       // Support: IE9-IE11+
+       div.innerHTML = "<textarea>x</textarea>";
+       support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+})();
+var strundefined = typeof undefined;
+
+
+
+support.focusinBubbles = "onfocusin" in window;
+
+
+var
+       rkeyEvent = /^key/,
+       rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
+       rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+       rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+function returnTrue() {
+       return true;
+}
+
+function returnFalse() {
+       return false;
+}
+
+function safeActiveElement() {
+       try {
+               return document.activeElement;
+       } catch ( err ) { }
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+       global: {},
+
+       add: function( elem, types, handler, data, selector ) {
+
+               var handleObjIn, eventHandle, tmp,
+                       events, t, handleObj,
+                       special, handlers, type, namespaces, origType,
+                       elemData = data_priv.get( elem );
+
+               // Don't attach events to noData or text/comment nodes (but allow plain objects)
+               if ( !elemData ) {
+                       return;
+               }
+
+               // Caller can pass in an object of custom data in lieu of the handler
+               if ( handler.handler ) {
+                       handleObjIn = handler;
+                       handler = handleObjIn.handler;
+                       selector = handleObjIn.selector;
+               }
+
+               // Make sure that the handler has a unique ID, used to find/remove it later
+               if ( !handler.guid ) {
+                       handler.guid = jQuery.guid++;
+               }
+
+               // Init the element's event structure and main handler, if this is the first
+               if ( !(events = elemData.events) ) {
+                       events = elemData.events = {};
+               }
+               if ( !(eventHandle = elemData.handle) ) {
+                       eventHandle = elemData.handle = function( e ) {
+                               // Discard the second event of a jQuery.event.trigger() and
+                               // when an event is called after a page has unloaded
+                               return typeof jQuery !== strundefined && jQuery.event.triggered !== e.type ?
+                                       jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+                       };
+               }
+
+               // Handle multiple events separated by a space
+               types = ( types || "" ).match( rnotwhite ) || [ "" ];
+               t = types.length;
+               while ( t-- ) {
+                       tmp = rtypenamespace.exec( types[t] ) || [];
+                       type = origType = tmp[1];
+                       namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+                       // There *must* be a type, no attaching namespace-only handlers
+                       if ( !type ) {
+                               continue;
+                       }
+
+                       // If event changes its type, use the special event handlers for the changed type
+                       special = jQuery.event.special[ type ] || {};
+
+                       // If selector defined, determine special event api type, otherwise given type
+                       type = ( selector ? special.delegateType : special.bindType ) || type;
+
+                       // Update special based on newly reset type
+                       special = jQuery.event.special[ type ] || {};
+
+                       // handleObj is passed to all event handlers
+                       handleObj = jQuery.extend({
+                               type: type,
+                               origType: origType,
+                               data: data,
+                               handler: handler,
+                               guid: handler.guid,
+                               selector: selector,
+                               needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+                               namespace: namespaces.join(".")
+                       }, handleObjIn );
+
+                       // Init the event handler queue if we're the first
+                       if ( !(handlers = events[ type ]) ) {
+                               handlers = events[ type ] = [];
+                               handlers.delegateCount = 0;
+
+                               // Only use addEventListener if the special events handler returns false
+                               if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+                                       if ( elem.addEventListener ) {
+                                               elem.addEventListener( type, eventHandle, false );
+                                       }
+                               }
+                       }
+
+                       if ( special.add ) {
+                               special.add.call( elem, handleObj );
+
+                               if ( !handleObj.handler.guid ) {
+                                       handleObj.handler.guid = handler.guid;
+                               }
+                       }
+
+                       // Add to the element's handler list, delegates in front
+                       if ( selector ) {
+                               handlers.splice( handlers.delegateCount++, 0, handleObj );
+                       } else {
+                               handlers.push( handleObj );
+                       }
+
+                       // Keep track of which events have ever been used, for event optimization
+                       jQuery.event.global[ type ] = true;
+               }
+
+       },
+
+       // Detach an event or set of events from an element
+       remove: function( elem, types, handler, selector, mappedTypes ) {
+
+               var j, origCount, tmp,
+                       events, t, handleObj,
+                       special, handlers, type, namespaces, origType,
+                       elemData = data_priv.hasData( elem ) && data_priv.get( elem );
+
+               if ( !elemData || !(events = elemData.events) ) {
+                       return;
+               }
+
+               // Once for each type.namespace in types; type may be omitted
+               types = ( types || "" ).match( rnotwhite ) || [ "" ];
+               t = types.length;
+               while ( t-- ) {
+                       tmp = rtypenamespace.exec( types[t] ) || [];
+                       type = origType = tmp[1];
+                       namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+                       // Unbind all events (on this namespace, if provided) for the element
+                       if ( !type ) {
+                               for ( type in events ) {
+                                       jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+                               }
+                               continue;
+                       }
+
+                       special = jQuery.event.special[ type ] || {};
+                       type = ( selector ? special.delegateType : special.bindType ) || type;
+                       handlers = events[ type ] || [];
+                       tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+
+                       // Remove matching events
+                       origCount = j = handlers.length;
+                       while ( j-- ) {
+                               handleObj = handlers[ j ];
+
+                               if ( ( mappedTypes || origType === handleObj.origType ) &&
+                                       ( !handler || handler.guid === handleObj.guid ) &&
+                                       ( !tmp || tmp.test( handleObj.namespace ) ) &&
+                                       ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+                                       handlers.splice( j, 1 );
+
+                                       if ( handleObj.selector ) {
+                                               handlers.delegateCount--;
+                                       }
+                                       if ( special.remove ) {
+                                               special.remove.call( elem, handleObj );
+                                       }
+                               }
+                       }
+
+                       // Remove generic event handler if we removed something and no more handlers exist
+                       // (avoids potential for endless recursion during removal of special event handlers)
+                       if ( origCount && !handlers.length ) {
+                               if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+                                       jQuery.removeEvent( elem, type, elemData.handle );
+                               }
+
+                               delete events[ type ];
+                       }
+               }
+
+               // Remove the expando if it's no longer used
+               if ( jQuery.isEmptyObject( events ) ) {
+                       delete elemData.handle;
+                       data_priv.remove( elem, "events" );
+               }
+       },
+
+       trigger: function( event, data, elem, onlyHandlers ) {
+
+               var i, cur, tmp, bubbleType, ontype, handle, special,
+                       eventPath = [ elem || document ],
+                       type = hasOwn.call( event, "type" ) ? event.type : event,
+                       namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+
+               cur = tmp = elem = elem || document;
+
+               // Don't do events on text and comment nodes
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
+               }
+
+               // focus/blur morphs to focusin/out; ensure we're not firing them right now
+               if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+                       return;
+               }
+
+               if ( type.indexOf(".") >= 0 ) {
+                       // Namespaced trigger; create a regexp to match event type in handle()
+                       namespaces = type.split(".");
+                       type = namespaces.shift();
+                       namespaces.sort();
+               }
+               ontype = type.indexOf(":") < 0 && "on" + type;
+
+               // Caller can pass in a jQuery.Event object, Object, or just an event type string
+               event = event[ jQuery.expando ] ?
+                       event :
+                       new jQuery.Event( type, typeof event === "object" && event );
+
+               // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+               event.isTrigger = onlyHandlers ? 2 : 3;
+               event.namespace = namespaces.join(".");
+               event.namespace_re = event.namespace ?
+                       new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+                       null;
+
+               // Clean up the event in case it is being reused
+               event.result = undefined;
+               if ( !event.target ) {
+                       event.target = elem;
+               }
+
+               // Clone any incoming data and prepend the event, creating the handler arg list
+               data = data == null ?
+                       [ event ] :
+                       jQuery.makeArray( data, [ event ] );
+
+               // Allow special events to draw outside the lines
+               special = jQuery.event.special[ type ] || {};
+               if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+                       return;
+               }
+
+               // Determine event propagation path in advance, per W3C events spec (#9951)
+               // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+               if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+                       bubbleType = special.delegateType || type;
+                       if ( !rfocusMorph.test( bubbleType + type ) ) {
+                               cur = cur.parentNode;
+                       }
+                       for ( ; cur; cur = cur.parentNode ) {
+                               eventPath.push( cur );
+                               tmp = cur;
+                       }
+
+                       // Only add window if we got to document (e.g., not plain obj or detached DOM)
+                       if ( tmp === (elem.ownerDocument || document) ) {
+                               eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+                       }
+               }
+
+               // Fire handlers on the event path
+               i = 0;
+               while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+
+                       event.type = i > 1 ?
+                               bubbleType :
+                               special.bindType || type;
+
+                       // jQuery handler
+                       handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
+                       if ( handle ) {
+                               handle.apply( cur, data );
+                       }
+
+                       // Native handler
+                       handle = ontype && cur[ ontype ];
+                       if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
+                               event.result = handle.apply( cur, data );
+                               if ( event.result === false ) {
+                                       event.preventDefault();
+                               }
+                       }
+               }
+               event.type = type;
+
+               // If nobody prevented the default action, do it now
+               if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+                       if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
+                               jQuery.acceptData( elem ) ) {
+
+                               // Call a native DOM method on the target with the same name name as the event.
+                               // Don't do default actions on window, that's where global variables be (#6170)
+                               if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
+
+                                       // Don't re-trigger an onFOO event when we call its FOO() method
+                                       tmp = elem[ ontype ];
+
+                                       if ( tmp ) {
+                                               elem[ ontype ] = null;
+                                       }
+
+                                       // Prevent re-triggering of the same event, since we already bubbled it above
+                                       jQuery.event.triggered = type;
+                                       elem[ type ]();
+                                       jQuery.event.triggered = undefined;
+
+                                       if ( tmp ) {
+                                               elem[ ontype ] = tmp;
+                                       }
+                               }
+                       }
+               }
+
+               return event.result;
+       },
+
+       dispatch: function( event ) {
+
+               // Make a writable jQuery.Event from the native event object
+               event = jQuery.event.fix( event );
+
+               var i, j, ret, matched, handleObj,
+                       handlerQueue = [],
+                       args = slice.call( arguments ),
+                       handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
+                       special = jQuery.event.special[ event.type ] || {};
+
+               // Use the fix-ed jQuery.Event rather than the (read-only) native event
+               args[0] = event;
+               event.delegateTarget = this;
+
+               // Call the preDispatch hook for the mapped type, and let it bail if desired
+               if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+                       return;
+               }
+
+               // Determine handlers
+               handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+               // Run delegates first; they may want to stop propagation beneath us
+               i = 0;
+               while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+                       event.currentTarget = matched.elem;
+
+                       j = 0;
+                       while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+
+                               // Triggered event must either 1) have no namespace, or
+                               // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+                               if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+
+                                       event.handleObj = handleObj;
+                                       event.data = handleObj.data;
+
+                                       ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+                                                       .apply( matched.elem, args );
+
+                                       if ( ret !== undefined ) {
+                                               if ( (event.result = ret) === false ) {
+                                                       event.preventDefault();
+                                                       event.stopPropagation();
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // Call the postDispatch hook for the mapped type
+               if ( special.postDispatch ) {
+                       special.postDispatch.call( this, event );
+               }
+
+               return event.result;
+       },
+
+       handlers: function( event, handlers ) {
+               var i, matches, sel, handleObj,
+                       handlerQueue = [],
+                       delegateCount = handlers.delegateCount,
+                       cur = event.target;
+
+               // Find delegate handlers
+               // Black-hole SVG <use> instance trees (#13180)
+               // Avoid non-left-click bubbling in Firefox (#3861)
+               if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
+
+                       for ( ; cur !== this; cur = cur.parentNode || this ) {
+
+                               // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+                               if ( cur.disabled !== true || event.type !== "click" ) {
+                                       matches = [];
+                                       for ( i = 0; i < delegateCount; i++ ) {
+                                               handleObj = handlers[ i ];
+
+                                               // Don't conflict with Object.prototype properties (#13203)
+                                               sel = handleObj.selector + " ";
+
+                                               if ( matches[ sel ] === undefined ) {
+                                                       matches[ sel ] = handleObj.needsContext ?
+                                                               jQuery( sel, this ).index( cur ) >= 0 :
+                                                               jQuery.find( sel, this, null, [ cur ] ).length;
+                                               }
+                                               if ( matches[ sel ] ) {
+                                                       matches.push( handleObj );
+                                               }
+                                       }
+                                       if ( matches.length ) {
+                                               handlerQueue.push({ elem: cur, handlers: matches });
+                                       }
+                               }
+                       }
+               }
+
+               // Add the remaining (directly-bound) handlers
+               if ( delegateCount < handlers.length ) {
+                       handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+               }
+
+               return handlerQueue;
+       },
+
+       // Includes some event props shared by KeyEvent and MouseEvent
+       props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+       fixHooks: {},
+
+       keyHooks: {
+               props: "char charCode key keyCode".split(" "),
+               filter: function( event, original ) {
+
+                       // Add which for key events
+                       if ( event.which == null ) {
+                               event.which = original.charCode != null ? original.charCode : original.keyCode;
+                       }
+
+                       return event;
+               }
+       },
+
+       mouseHooks: {
+               props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
+               filter: function( event, original ) {
+                       var eventDoc, doc, body,
+                               button = original.button;
+
+                       // Calculate pageX/Y if missing and clientX/Y available
+                       if ( event.pageX == null && original.clientX != null ) {
+                               eventDoc = event.target.ownerDocument || document;
+                               doc = eventDoc.documentElement;
+                               body = eventDoc.body;
+
+                               event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
+                               event.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );
+                       }
+
+                       // Add which for click: 1 === left; 2 === middle; 3 === right
+                       // Note: button is not normalized, so don't use it
+                       if ( !event.which && button !== undefined ) {
+                               event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
+                       }
+
+                       return event;
+               }
+       },
+
+       fix: function( event ) {
+               if ( event[ jQuery.expando ] ) {
+                       return event;
+               }
+
+               // Create a writable copy of the event object and normalize some properties
+               var i, prop, copy,
+                       type = event.type,
+                       originalEvent = event,
+                       fixHook = this.fixHooks[ type ];
+
+               if ( !fixHook ) {
+                       this.fixHooks[ type ] = fixHook =
+                               rmouseEvent.test( type ) ? this.mouseHooks :
+                               rkeyEvent.test( type ) ? this.keyHooks :
+                               {};
+               }
+               copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+               event = new jQuery.Event( originalEvent );
+
+               i = copy.length;
+               while ( i-- ) {
+                       prop = copy[ i ];
+                       event[ prop ] = originalEvent[ prop ];
+               }
+
+               // Support: Cordova 2.5 (WebKit) (#13255)
+               // All events should have a target; Cordova deviceready doesn't
+               if ( !event.target ) {
+                       event.target = document;
+               }
+
+               // Support: Safari 6.0+, Chrome < 28
+               // Target should not be a text node (#504, #13143)
+               if ( event.target.nodeType === 3 ) {
+                       event.target = event.target.parentNode;
+               }
+
+               return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+       },
+
+       special: {
+               load: {
+                       // Prevent triggered image.load events from bubbling to window.load
+                       noBubble: true
+               },
+               focus: {
+                       // Fire native event if possible so blur/focus sequence is correct
+                       trigger: function() {
+                               if ( this !== safeActiveElement() && this.focus ) {
+                                       this.focus();
+                                       return false;
+                               }
+                       },
+                       delegateType: "focusin"
+               },
+               blur: {
+                       trigger: function() {
+                               if ( this === safeActiveElement() && this.blur ) {
+                                       this.blur();
+                                       return false;
+                               }
+                       },
+                       delegateType: "focusout"
+               },
+               click: {
+                       // For checkbox, fire native event so checked state will be right
+                       trigger: function() {
+                               if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
+                                       this.click();
+                                       return false;
+                               }
+                       },
+
+                       // For cross-browser consistency, don't fire native .click() on links
+                       _default: function( event ) {
+                               return jQuery.nodeName( event.target, "a" );
+                       }
+               },
+
+               beforeunload: {
+                       postDispatch: function( event ) {
+
+                               // Support: Firefox 20+
+                               // Firefox doesn't alert if the returnValue field is not set.
+                               if ( event.result !== undefined && event.originalEvent ) {
+                                       event.originalEvent.returnValue = event.result;
+                               }
+                       }
+               }
+       },
+
+       simulate: function( type, elem, event, bubble ) {
+               // Piggyback on a donor event to simulate a different one.
+               // Fake originalEvent to avoid donor's stopPropagation, but if the
+               // simulated event prevents default then we do the same on the donor.
+               var e = jQuery.extend(
+                       new jQuery.Event(),
+                       event,
+                       {
+                               type: type,
+                               isSimulated: true,
+                               originalEvent: {}
+                       }
+               );
+               if ( bubble ) {
+                       jQuery.event.trigger( e, null, elem );
+               } else {
+                       jQuery.event.dispatch.call( elem, e );
+               }
+               if ( e.isDefaultPrevented() ) {
+                       event.preventDefault();
+               }
+       }
+};
+
+jQuery.removeEvent = function( elem, type, handle ) {
+       if ( elem.removeEventListener ) {
+               elem.removeEventListener( type, handle, false );
+       }
+};
+
+jQuery.Event = function( src, props ) {
+       // Allow instantiation without the 'new' keyword
+       if ( !(this instanceof jQuery.Event) ) {
+               return new jQuery.Event( src, props );
+       }
+
+       // Event object
+       if ( src && src.type ) {
+               this.originalEvent = src;
+               this.type = src.type;
+
+               // Events bubbling up the document may have been marked as prevented
+               // by a handler lower down the tree; reflect the correct value.
+               this.isDefaultPrevented = src.defaultPrevented ||
+                               src.defaultPrevented === undefined &&
+                               // Support: Android < 4.0
+                               src.returnValue === false ?
+                       returnTrue :
+                       returnFalse;
+
+       // Event type
+       } else {
+               this.type = src;
+       }
+
+       // Put explicitly provided properties onto the event object
+       if ( props ) {
+               jQuery.extend( this, props );
+       }
+
+       // Create a timestamp if incoming event doesn't have one
+       this.timeStamp = src && src.timeStamp || jQuery.now();
+
+       // Mark it as fixed
+       this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+       isDefaultPrevented: returnFalse,
+       isPropagationStopped: returnFalse,
+       isImmediatePropagationStopped: returnFalse,
+
+       preventDefault: function() {
+               var e = this.originalEvent;
+
+               this.isDefaultPrevented = returnTrue;
+
+               if ( e && e.preventDefault ) {
+                       e.preventDefault();
+               }
+       },
+       stopPropagation: function() {
+               var e = this.originalEvent;
+
+               this.isPropagationStopped = returnTrue;
+
+               if ( e && e.stopPropagation ) {
+                       e.stopPropagation();
+               }
+       },
+       stopImmediatePropagation: function() {
+               var e = this.originalEvent;
+
+               this.isImmediatePropagationStopped = returnTrue;
+
+               if ( e && e.stopImmediatePropagation ) {
+                       e.stopImmediatePropagation();
+               }
+
+               this.stopPropagation();
+       }
+};
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+// Support: Chrome 15+
+jQuery.each({
+       mouseenter: "mouseover",
+       mouseleave: "mouseout",
+       pointerenter: "pointerover",
+       pointerleave: "pointerout"
+}, function( orig, fix ) {
+       jQuery.event.special[ orig ] = {
+               delegateType: fix,
+               bindType: fix,
+
+               handle: function( event ) {
+                       var ret,
+                               target = this,
+                               related = event.relatedTarget,
+                               handleObj = event.handleObj;
+
+                       // For mousenter/leave call the handler if related is outside the target.
+                       // NB: No relatedTarget if the mouse left/entered the browser window
+                       if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
+                               event.type = handleObj.origType;
+                               ret = handleObj.handler.apply( this, arguments );
+                               event.type = fix;
+                       }
+                       return ret;
+               }
+       };
+});
+
+// Create "bubbling" focus and blur events
+// Support: Firefox, Chrome, Safari
+if ( !support.focusinBubbles ) {
+       jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+               // Attach a single capturing handler on the document while someone wants focusin/focusout
+               var handler = function( event ) {
+                               jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
+                       };
+
+               jQuery.event.special[ fix ] = {
+                       setup: function() {
+                               var doc = this.ownerDocument || this,
+                                       attaches = data_priv.access( doc, fix );
+
+                               if ( !attaches ) {
+                                       doc.addEventListener( orig, handler, true );
+                               }
+                               data_priv.access( doc, fix, ( attaches || 0 ) + 1 );
+                       },
+                       teardown: function() {
+                               var doc = this.ownerDocument || this,
+                                       attaches = data_priv.access( doc, fix ) - 1;
+
+                               if ( !attaches ) {
+                                       doc.removeEventListener( orig, handler, true );
+                                       data_priv.remove( doc, fix );
+
+                               } else {
+                                       data_priv.access( doc, fix, attaches );
+                               }
+                       }
+               };
+       });
+}
+
+jQuery.fn.extend({
+
+       on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
+               var origFn, type;
+
+               // Types can be a map of types/handlers
+               if ( typeof types === "object" ) {
+                       // ( types-Object, selector, data )
+                       if ( typeof selector !== "string" ) {
+                               // ( types-Object, data )
+                               data = data || selector;
+                               selector = undefined;
+                       }
+                       for ( type in types ) {
+                               this.on( type, selector, data, types[ type ], one );
+                       }
+                       return this;
+               }
+
+               if ( data == null && fn == null ) {
+                       // ( types, fn )
+                       fn = selector;
+                       data = selector = undefined;
+               } else if ( fn == null ) {
+                       if ( typeof selector === "string" ) {
+                               // ( types, selector, fn )
+                               fn = data;
+                               data = undefined;
+                       } else {
+                               // ( types, data, fn )
+                               fn = data;
+                               data = selector;
+                               selector = undefined;
+                       }
+               }
+               if ( fn === false ) {
+                       fn = returnFalse;
+               } else if ( !fn ) {
+                       return this;
+               }
+
+               if ( one === 1 ) {
+                       origFn = fn;
+                       fn = function( event ) {
+                               // Can use an empty set, since event contains the info
+                               jQuery().off( event );
+                               return origFn.apply( this, arguments );
+                       };
+                       // Use same guid so caller can remove using origFn
+                       fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+               }
+               return this.each( function() {
+                       jQuery.event.add( this, types, fn, data, selector );
+               });
+       },
+       one: function( types, selector, data, fn ) {
+               return this.on( types, selector, data, fn, 1 );
+       },
+       off: function( types, selector, fn ) {
+               var handleObj, type;
+               if ( types && types.preventDefault && types.handleObj ) {
+                       // ( event )  dispatched jQuery.Event
+                       handleObj = types.handleObj;
+                       jQuery( types.delegateTarget ).off(
+                               handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
+                               handleObj.selector,
+                               handleObj.handler
+                       );
+                       return this;
+               }
+               if ( typeof types === "object" ) {
+                       // ( types-object [, selector] )
+                       for ( type in types ) {
+                               this.off( type, selector, types[ type ] );
+                       }
+                       return this;
+               }
+               if ( selector === false || typeof selector === "function" ) {
+                       // ( types [, fn] )
+                       fn = selector;
+                       selector = undefined;
+               }
+               if ( fn === false ) {
+                       fn = returnFalse;
+               }
+               return this.each(function() {
+                       jQuery.event.remove( this, types, fn, selector );
+               });
+       },
+
+       trigger: function( type, data ) {
+               return this.each(function() {
+                       jQuery.event.trigger( type, data, this );
+               });
+       },
+       triggerHandler: function( type, data ) {
+               var elem = this[0];
+               if ( elem ) {
+                       return jQuery.event.trigger( type, data, elem, true );
+               }
+       }
+});
+
+
+var
+       rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+       rtagName = /<([\w:]+)/,
+       rhtml = /<|&#?\w+;/,
+       rnoInnerhtml = /<(?:script|style|link)/i,
+       // checked="checked" or checked
+       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+       rscriptType = /^$|\/(?:java|ecma)script/i,
+       rscriptTypeMasked = /^true\/(.*)/,
+       rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
+
+       // We have to close these tags to support XHTML (#13200)
+       wrapMap = {
+
+               // Support: IE 9
+               option: [ 1, "<select multiple='multiple'>", "</select>" ],
+
+               thead: [ 1, "<table>", "</table>" ],
+               col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
+               tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+               td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+               _default: [ 0, "", "" ]
+       };
+
+// Support: IE 9
+wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// Support: 1.x compatibility
+// Manipulating tables requires a tbody
+function manipulationTarget( elem, content ) {
+       return jQuery.nodeName( elem, "table" ) &&
+               jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
+
+               elem.getElementsByTagName("tbody")[0] ||
+                       elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
+               elem;
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+       elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
+       return elem;
+}
+function restoreScript( elem ) {
+       var match = rscriptTypeMasked.exec( elem.type );
+
+       if ( match ) {
+               elem.type = match[ 1 ];
+       } else {
+               elem.removeAttribute("type");
+       }
+
+       return elem;
+}
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+       var i = 0,
+               l = elems.length;
+
+       for ( ; i < l; i++ ) {
+               data_priv.set(
+                       elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
+               );
+       }
+}
+
+function cloneCopyEvent( src, dest ) {
+       var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
+
+       if ( dest.nodeType !== 1 ) {
+               return;
+       }
+
+       // 1. Copy private data: events, handlers, etc.
+       if ( data_priv.hasData( src ) ) {
+               pdataOld = data_priv.access( src );
+               pdataCur = data_priv.set( dest, pdataOld );
+               events = pdataOld.events;
+
+               if ( events ) {
+                       delete pdataCur.handle;
+                       pdataCur.events = {};
+
+                       for ( type in events ) {
+                               for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+                                       jQuery.event.add( dest, type, events[ type ][ i ] );
+                               }
+                       }
+               }
+       }
+
+       // 2. Copy user data
+       if ( data_user.hasData( src ) ) {
+               udataOld = data_user.access( src );
+               udataCur = jQuery.extend( {}, udataOld );
+
+               data_user.set( dest, udataCur );
+       }
+}
+
+function getAll( context, tag ) {
+       var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
+                       context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
+                       [];
+
+       return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+               jQuery.merge( [ context ], ret ) :
+               ret;
+}
+
+// Support: IE >= 9
+function fixInput( src, dest ) {
+       var nodeName = dest.nodeName.toLowerCase();
+
+       // Fails to persist the checked state of a cloned checkbox or radio button.
+       if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
+               dest.checked = src.checked;
+
+       // Fails to return the selected option to the default selected state when cloning options
+       } else if ( nodeName === "input" || nodeName === "textarea" ) {
+               dest.defaultValue = src.defaultValue;
+       }
+}
+
+jQuery.extend({
+       clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+               var i, l, srcElements, destElements,
+                       clone = elem.cloneNode( true ),
+                       inPage = jQuery.contains( elem.ownerDocument, elem );
+
+               // Support: IE >= 9
+               // Fix Cloning issues
+               if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
+                               !jQuery.isXMLDoc( elem ) ) {
+
+                       // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+                       destElements = getAll( clone );
+                       srcElements = getAll( elem );
+
+                       for ( i = 0, l = srcElements.length; i < l; i++ ) {
+                               fixInput( srcElements[ i ], destElements[ i ] );
+                       }
+               }
+
+               // Copy the events from the original to the clone
+               if ( dataAndEvents ) {
+                       if ( deepDataAndEvents ) {
+                               srcElements = srcElements || getAll( elem );
+                               destElements = destElements || getAll( clone );
+
+                               for ( i = 0, l = srcElements.length; i < l; i++ ) {
+                                       cloneCopyEvent( srcElements[ i ], destElements[ i ] );
+                               }
+                       } else {
+                               cloneCopyEvent( elem, clone );
+                       }
+               }
+
+               // Preserve script evaluation history
+               destElements = getAll( clone, "script" );
+               if ( destElements.length > 0 ) {
+                       setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+               }
+
+               // Return the cloned set
+               return clone;
+       },
+
+       buildFragment: function( elems, context, scripts, selection ) {
+               var elem, tmp, tag, wrap, contains, j,
+                       fragment = context.createDocumentFragment(),
+                       nodes = [],
+                       i = 0,
+                       l = elems.length;
+
+               for ( ; i < l; i++ ) {
+                       elem = elems[ i ];
+
+                       if ( elem || elem === 0 ) {
+
+                               // Add nodes directly
+                               if ( jQuery.type( elem ) === "object" ) {
+                                       // Support: QtWebKit
+                                       // jQuery.merge because push.apply(_, arraylike) throws
+                                       jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+                               // Convert non-html into a text node
+                               } else if ( !rhtml.test( elem ) ) {
+                                       nodes.push( context.createTextNode( elem ) );
+
+                               // Convert html into DOM nodes
+                               } else {
+                                       tmp = tmp || fragment.appendChild( context.createElement("div") );
+
+                                       // Deserialize a standard representation
+                                       tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+                                       wrap = wrapMap[ tag ] || wrapMap._default;
+                                       tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
+
+                                       // Descend through wrappers to the right content
+                                       j = wrap[ 0 ];
+                                       while ( j-- ) {
+                                               tmp = tmp.lastChild;
+                                       }
+
+                                       // Support: QtWebKit
+                                       // jQuery.merge because push.apply(_, arraylike) throws
+                                       jQuery.merge( nodes, tmp.childNodes );
+
+                                       // Remember the top-level container
+                                       tmp = fragment.firstChild;
+
+                                       // Fixes #12346
+                                       // Support: Webkit, IE
+                                       tmp.textContent = "";
+                               }
+                       }
+               }
+
+               // Remove wrapper from fragment
+               fragment.textContent = "";
+
+               i = 0;
+               while ( (elem = nodes[ i++ ]) ) {
+
+                       // #4087 - If origin and destination elements are the same, and this is
+                       // that element, do not do anything
+                       if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
+                               continue;
+                       }
+
+                       contains = jQuery.contains( elem.ownerDocument, elem );
+
+                       // Append to fragment
+                       tmp = getAll( fragment.appendChild( elem ), "script" );
+
+                       // Preserve script evaluation history
+                       if ( contains ) {
+                               setGlobalEval( tmp );
+                       }
+
+                       // Capture executables
+                       if ( scripts ) {
+                               j = 0;
+                               while ( (elem = tmp[ j++ ]) ) {
+                                       if ( rscriptType.test( elem.type || "" ) ) {
+                                               scripts.push( elem );
+                                       }
+                               }
+                       }
+               }
+
+               return fragment;
+       },
+
+       cleanData: function( elems ) {
+               var data, elem, type, key,
+                       special = jQuery.event.special,
+                       i = 0;
+
+               for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
+                       if ( jQuery.acceptData( elem ) ) {
+                               key = elem[ data_priv.expando ];
+
+                               if ( key && (data = data_priv.cache[ key ]) ) {
+                                       if ( data.events ) {
+                                               for ( type in data.events ) {
+                                                       if ( special[ type ] ) {
+                                                               jQuery.event.remove( elem, type );
+
+                                                       // This is a shortcut to avoid jQuery.event.remove's overhead
+                                                       } else {
+                                                               jQuery.removeEvent( elem, type, data.handle );
+                                                       }
+                                               }
+                                       }
+                                       if ( data_priv.cache[ key ] ) {
+                                               // Discard any remaining `private` data
+                                               delete data_priv.cache[ key ];
+                                       }
+                               }
+                       }
+                       // Discard any remaining `user` data
+                       delete data_user.cache[ elem[ data_user.expando ] ];
+               }
+       }
+});
+
+jQuery.fn.extend({
+       text: function( value ) {
+               return access( this, function( value ) {
+                       return value === undefined ?
+                               jQuery.text( this ) :
+                               this.empty().each(function() {
+                                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                                               this.textContent = value;
+                                       }
+                               });
+               }, null, value, arguments.length );
+       },
+
+       append: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                               var target = manipulationTarget( this, elem );
+                               target.appendChild( elem );
+                       }
+               });
+       },
+
+       prepend: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                               var target = manipulationTarget( this, elem );
+                               target.insertBefore( elem, target.firstChild );
+                       }
+               });
+       },
+
+       before: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.parentNode ) {
+                               this.parentNode.insertBefore( elem, this );
+                       }
+               });
+       },
+
+       after: function() {
+               return this.domManip( arguments, function( elem ) {
+                       if ( this.parentNode ) {
+                               this.parentNode.insertBefore( elem, this.nextSibling );
+                       }
+               });
+       },
+
+       remove: function( selector, keepData /* Internal Use Only */ ) {
+               var elem,
+                       elems = selector ? jQuery.filter( selector, this ) : this,
+                       i = 0;
+
+               for ( ; (elem = elems[i]) != null; i++ ) {
+                       if ( !keepData && elem.nodeType === 1 ) {
+                               jQuery.cleanData( getAll( elem ) );
+                       }
+
+                       if ( elem.parentNode ) {
+                               if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
+                                       setGlobalEval( getAll( elem, "script" ) );
+                               }
+                               elem.parentNode.removeChild( elem );
+                       }
+               }
+
+               return this;
+       },
+
+       empty: function() {
+               var elem,
+                       i = 0;
+
+               for ( ; (elem = this[i]) != null; i++ ) {
+                       if ( elem.nodeType === 1 ) {
+
+                               // Prevent memory leaks
+                               jQuery.cleanData( getAll( elem, false ) );
+
+                               // Remove any remaining nodes
+                               elem.textContent = "";
+                       }
+               }
+
+               return this;
+       },
+
+       clone: function( dataAndEvents, deepDataAndEvents ) {
+               dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+               deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+               return this.map(function() {
+                       return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+               });
+       },
+
+       html: function( value ) {
+               return access( this, function( value ) {
+                       var elem = this[ 0 ] || {},
+                               i = 0,
+                               l = this.length;
+
+                       if ( value === undefined && elem.nodeType === 1 ) {
+                               return elem.innerHTML;
+                       }
+
+                       // See if we can take a shortcut and just use innerHTML
+                       if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+                               !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
+
+                               value = value.replace( rxhtmlTag, "<$1></$2>" );
+
+                               try {
+                                       for ( ; i < l; i++ ) {
+                                               elem = this[ i ] || {};
+
+                                               // Remove element nodes and prevent memory leaks
+                                               if ( elem.nodeType === 1 ) {
+                                                       jQuery.cleanData( getAll( elem, false ) );
+                                                       elem.innerHTML = value;
+                                               }
+                                       }
+
+                                       elem = 0;
+
+                               // If using innerHTML throws an exception, use the fallback method
+                               } catch( e ) {}
+                       }
+
+                       if ( elem ) {
+                               this.empty().append( value );
+                       }
+               }, null, value, arguments.length );
+       },
+
+       replaceWith: function() {
+               var arg = arguments[ 0 ];
+
+               // Make the changes, replacing each context element with the new content
+               this.domManip( arguments, function( elem ) {
+                       arg = this.parentNode;
+
+                       jQuery.cleanData( getAll( this ) );
+
+                       if ( arg ) {
+                               arg.replaceChild( elem, this );
+                       }
+               });
+
+               // Force removal if there was no new content (e.g., from empty arguments)
+               return arg && (arg.length || arg.nodeType) ? this : this.remove();
+       },
+
+       detach: function( selector ) {
+               return this.remove( selector, true );
+       },
+
+       domManip: function( args, callback ) {
+
+               // Flatten any nested arrays
+               args = concat.apply( [], args );
+
+               var fragment, first, scripts, hasScripts, node, doc,
+                       i = 0,
+                       l = this.length,
+                       set = this,
+                       iNoClone = l - 1,
+                       value = args[ 0 ],
+                       isFunction = jQuery.isFunction( value );
+
+               // We can't cloneNode fragments that contain checked, in WebKit
+               if ( isFunction ||
+                               ( l > 1 && typeof value === "string" &&
+                                       !support.checkClone && rchecked.test( value ) ) ) {
+                       return this.each(function( index ) {
+                               var self = set.eq( index );
+                               if ( isFunction ) {
+                                       args[ 0 ] = value.call( this, index, self.html() );
+                               }
+                               self.domManip( args, callback );
+                       });
+               }
+
+               if ( l ) {
+                       fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
+                       first = fragment.firstChild;
+
+                       if ( fragment.childNodes.length === 1 ) {
+                               fragment = first;
+                       }
+
+                       if ( first ) {
+                               scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+                               hasScripts = scripts.length;
+
+                               // Use the original fragment for the last item instead of the first because it can end up
+                               // being emptied incorrectly in certain situations (#8070).
+                               for ( ; i < l; i++ ) {
+                                       node = fragment;
+
+                                       if ( i !== iNoClone ) {
+                                               node = jQuery.clone( node, true, true );
+
+                                               // Keep references to cloned scripts for later restoration
+                                               if ( hasScripts ) {
+                                                       // Support: QtWebKit
+                                                       // jQuery.merge because push.apply(_, arraylike) throws
+                                                       jQuery.merge( scripts, getAll( node, "script" ) );
+                                               }
+                                       }
+
+                                       callback.call( this[ i ], node, i );
+                               }
+
+                               if ( hasScripts ) {
+                                       doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+                                       // Reenable scripts
+                                       jQuery.map( scripts, restoreScript );
+
+                                       // Evaluate executable scripts on first document insertion
+                                       for ( i = 0; i < hasScripts; i++ ) {
+                                               node = scripts[ i ];
+                                               if ( rscriptType.test( node.type || "" ) &&
+                                                       !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
+
+                                                       if ( node.src ) {
+                                                               // Optional AJAX dependency, but won't run scripts if not present
+                                                               if ( jQuery._evalUrl ) {
+                                                                       jQuery._evalUrl( node.src );
+                                                               }
+                                                       } else {
+                                                               jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               return this;
+       }
+});
+
+jQuery.each({
+       appendTo: "append",
+       prependTo: "prepend",
+       insertBefore: "before",
+       insertAfter: "after",
+       replaceAll: "replaceWith"
+}, function( name, original ) {
+       jQuery.fn[ name ] = function( selector ) {
+               var elems,
+                       ret = [],
+                       insert = jQuery( selector ),
+                       last = insert.length - 1,
+                       i = 0;
+
+               for ( ; i <= last; i++ ) {
+                       elems = i === last ? this : this.clone( true );
+                       jQuery( insert[ i ] )[ original ]( elems );
+
+                       // Support: QtWebKit
+                       // .get() because push.apply(_, arraylike) throws
+                       push.apply( ret, elems.get() );
+               }
+
+               return this.pushStack( ret );
+       };
+});
+
+
+var iframe,
+       elemdisplay = {};
+
+/**
+ * Retrieve the actual display of a element
+ * @param {String} name nodeName of the element
+ * @param {Object} doc Document object
+ */
+// Called only from within defaultDisplay
+function actualDisplay( name, doc ) {
+       var style,
+               elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+
+               // getDefaultComputedStyle might be reliably used only on attached element
+               display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
+
+                       // Use of this method is a temporary fix (more like optmization) until something better comes along,
+                       // since it was removed from specification and supported only in FF
+                       style.display : jQuery.css( elem[ 0 ], "display" );
+
+       // We don't have any data stored on the element,
+       // so use "detach" method as fast way to get rid of the element
+       elem.detach();
+
+       return display;
+}
+
+/**
+ * Try to determine the default display value of an element
+ * @param {String} nodeName
+ */
+function defaultDisplay( nodeName ) {
+       var doc = document,
+               display = elemdisplay[ nodeName ];
+
+       if ( !display ) {
+               display = actualDisplay( nodeName, doc );
+
+               // If the simple way fails, read from inside an iframe
+               if ( display === "none" || !display ) {
+
+                       // Use the already-created iframe if possible
+                       iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
+
+                       // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+                       doc = iframe[ 0 ].contentDocument;
+
+                       // Support: IE
+                       doc.write();
+                       doc.close();
+
+                       display = actualDisplay( nodeName, doc );
+                       iframe.detach();
+               }
+
+               // Store the correct default display
+               elemdisplay[ nodeName ] = display;
+       }
+
+       return display;
+}
+var rmargin = (/^margin/);
+
+var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
+
+var getStyles = function( elem ) {
+               return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
+       };
+
+
+
+function curCSS( elem, name, computed ) {
+       var width, minWidth, maxWidth, ret,
+               style = elem.style;
+
+       computed = computed || getStyles( elem );
+
+       // Support: IE9
+       // getPropertyValue is only needed for .css('filter') in IE9, see #12537
+       if ( computed ) {
+               ret = computed.getPropertyValue( name ) || computed[ name ];
+       }
+
+       if ( computed ) {
+
+               if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+                       ret = jQuery.style( elem, name );
+               }
+
+               // Support: iOS < 6
+               // A tribute to the "awesome hack by Dean Edwards"
+               // iOS < 6 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
+               // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
+               if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+                       // Remember the original values
+                       width = style.width;
+                       minWidth = style.minWidth;
+                       maxWidth = style.maxWidth;
+
+                       // Put in the new values to get a computed value out
+                       style.minWidth = style.maxWidth = style.width = ret;
+                       ret = computed.width;
+
+                       // Revert the changed values
+                       style.width = width;
+                       style.minWidth = minWidth;
+                       style.maxWidth = maxWidth;
+               }
+       }
+
+       return ret !== undefined ?
+               // Support: IE
+               // IE returns zIndex value as an integer.
+               ret + "" :
+               ret;
+}
+
+
+function addGetHookIf( conditionFn, hookFn ) {
+       // Define the hook, we'll check on the first run if it's really needed.
+       return {
+               get: function() {
+                       if ( conditionFn() ) {
+                               // Hook not needed (or it's not possible to use it due to missing dependency),
+                               // remove it.
+                               // Since there are no other hooks for marginRight, remove the whole object.
+                               delete this.get;
+                               return;
+                       }
+
+                       // Hook needed; redefine it so that the support test is not executed again.
+
+                       return (this.get = hookFn).apply( this, arguments );
+               }
+       };
+}
+
+
+(function() {
+       var pixelPositionVal, boxSizingReliableVal,
+               docElem = document.documentElement,
+               container = document.createElement( "div" ),
+               div = document.createElement( "div" );
+
+       if ( !div.style ) {
+               return;
+       }
+
+       div.style.backgroundClip = "content-box";
+       div.cloneNode( true ).style.backgroundClip = "";
+       support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+       container.style.cssText = "border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;" +
+               "position:absolute";
+       container.appendChild( div );
+
+       // Executing both pixelPosition & boxSizingReliable tests require only one layout
+       // so they're executed at the same time to save the second computation.
+       function computePixelPositionAndBoxSizingReliable() {
+               div.style.cssText =
+                       // Support: Firefox<29, Android 2.3
+                       // Vendor-prefix box-sizing
+                       "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
+                       "box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
+                       "border:1px;padding:1px;width:4px;position:absolute";
+               div.innerHTML = "";
+               docElem.appendChild( container );
+
+               var divStyle = window.getComputedStyle( div, null );
+               pixelPositionVal = divStyle.top !== "1%";
+               boxSizingReliableVal = divStyle.width === "4px";
+
+               docElem.removeChild( container );
+       }
+
+       // Support: node.js jsdom
+       // Don't assume that getComputedStyle is a property of the global object
+       if ( window.getComputedStyle ) {
+               jQuery.extend( support, {
+                       pixelPosition: function() {
+                               // This test is executed only once but we still do memoizing
+                               // since we can use the boxSizingReliable pre-computing.
+                               // No need to check if the test was already performed, though.
+                               computePixelPositionAndBoxSizingReliable();
+                               return pixelPositionVal;
+                       },
+                       boxSizingReliable: function() {
+                               if ( boxSizingReliableVal == null ) {
+                                       computePixelPositionAndBoxSizingReliable();
+                               }
+                               return boxSizingReliableVal;
+                       },
+                       reliableMarginRight: function() {
+                               // Support: Android 2.3
+                               // Check if div with explicit width and no margin-right incorrectly
+                               // gets computed margin-right based on width of container. (#3333)
+                               // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+                               // This support function is only executed once so no memoizing is needed.
+                               var ret,
+                                       marginDiv = div.appendChild( document.createElement( "div" ) );
+
+                               // Reset CSS: box-sizing; display; margin; border; padding
+                               marginDiv.style.cssText = div.style.cssText =
+                                       // Support: Firefox<29, Android 2.3
+                                       // Vendor-prefix box-sizing
+                                       "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
+                                       "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
+                               marginDiv.style.marginRight = marginDiv.style.width = "0";
+                               div.style.width = "1px";
+                               docElem.appendChild( container );
+
+                               ret = !parseFloat( window.getComputedStyle( marginDiv, null ).marginRight );
+
+                               docElem.removeChild( container );
+
+                               return ret;
+                       }
+               });
+       }
+})();
+
+
+// A method for quickly swapping in/out CSS properties to get correct calculations.
+jQuery.swap = function( elem, options, callback, args ) {
+       var ret, name,
+               old = {};
+
+       // Remember the old values, and insert the new ones
+       for ( name in options ) {
+               old[ name ] = elem.style[ name ];
+               elem.style[ name ] = options[ name ];
+       }
+
+       ret = callback.apply( elem, args || [] );
+
+       // Revert the old values
+       for ( name in options ) {
+               elem.style[ name ] = old[ name ];
+       }
+
+       return ret;
+};
+
+
+var
+       // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
+       // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+       rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+       rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
+       rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
+
+       cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+       cssNormalTransform = {
+               letterSpacing: "0",
+               fontWeight: "400"
+       },
+
+       cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
+
+// return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( style, name ) {
+
+       // shortcut for names that are not vendor prefixed
+       if ( name in style ) {
+               return name;
+       }
+
+       // check for vendor prefixed names
+       var capName = name[0].toUpperCase() + name.slice(1),
+               origName = name,
+               i = cssPrefixes.length;
+
+       while ( i-- ) {
+               name = cssPrefixes[ i ] + capName;
+               if ( name in style ) {
+                       return name;
+               }
+       }
+
+       return origName;
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+       var matches = rnumsplit.exec( value );
+       return matches ?
+               // Guard against undefined "subtract", e.g., when used as in cssHooks
+               Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+               value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+       var i = extra === ( isBorderBox ? "border" : "content" ) ?
+               // If we already have the right measurement, avoid augmentation
+               4 :
+               // Otherwise initialize for horizontal or vertical properties
+               name === "width" ? 1 : 0,
+
+               val = 0;
+
+       for ( ; i < 4; i += 2 ) {
+               // both box models exclude margin, so add it if we want it
+               if ( extra === "margin" ) {
+                       val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+               }
+
+               if ( isBorderBox ) {
+                       // border-box includes padding, so remove it if we want content
+                       if ( extra === "content" ) {
+                               val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+                       }
+
+                       // at this point, extra isn't border nor margin, so remove border
+                       if ( extra !== "margin" ) {
+                               val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+                       }
+               } else {
+                       // at this point, extra isn't content, so add padding
+                       val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+                       // at this point, extra isn't content nor padding, so add border
+                       if ( extra !== "padding" ) {
+                               val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+                       }
+               }
+       }
+
+       return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+       // Start with offset property, which is equivalent to the border-box value
+       var valueIsBorderBox = true,
+               val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+               styles = getStyles( elem ),
+               isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+       // some non-html elements return undefined for offsetWidth, so check for null/undefined
+       // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
+       // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
+       if ( val <= 0 || val == null ) {
+               // Fall back to computed then uncomputed css if necessary
+               val = curCSS( elem, name, styles );
+               if ( val < 0 || val == null ) {
+                       val = elem.style[ name ];
+               }
+
+               // Computed unit is not pixels. Stop here and return.
+               if ( rnumnonpx.test(val) ) {
+                       return val;
+               }
+
+               // we need the check for style in case a browser which returns unreliable values
+               // for getComputedStyle silently falls back to the reliable elem.style
+               valueIsBorderBox = isBorderBox &&
+                       ( support.boxSizingReliable() || val === elem.style[ name ] );
+
+               // Normalize "", auto, and prepare for extra
+               val = parseFloat( val ) || 0;
+       }
+
+       // use the active box-sizing model to add/subtract irrelevant styles
+       return ( val +
+               augmentWidthOrHeight(
+                       elem,
+                       name,
+                       extra || ( isBorderBox ? "border" : "content" ),
+                       valueIsBorderBox,
+                       styles
+               )
+       ) + "px";
+}
+
+function showHide( elements, show ) {
+       var display, elem, hidden,
+               values = [],
+               index = 0,
+               length = elements.length;
+
+       for ( ; index < length; index++ ) {
+               elem = elements[ index ];
+               if ( !elem.style ) {
+                       continue;
+               }
+
+               values[ index ] = data_priv.get( elem, "olddisplay" );
+               display = elem.style.display;
+               if ( show ) {
+                       // Reset the inline display of this element to learn if it is
+                       // being hidden by cascaded rules or not
+                       if ( !values[ index ] && display === "none" ) {
+                               elem.style.display = "";
+                       }
+
+                       // Set elements which have been overridden with display: none
+                       // in a stylesheet to whatever the default browser style is
+                       // for such an element
+                       if ( elem.style.display === "" && isHidden( elem ) ) {
+                               values[ index ] = data_priv.access( elem, "olddisplay", defaultDisplay(elem.nodeName) );
+                       }
+               } else {
+                       hidden = isHidden( elem );
+
+                       if ( display !== "none" || !hidden ) {
+                               data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
+                       }
+               }
+       }
+
+       // Set the display of most of the elements in a second loop
+       // to avoid the constant reflow
+       for ( index = 0; index < length; index++ ) {
+               elem = elements[ index ];
+               if ( !elem.style ) {
+                       continue;
+               }
+               if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
+                       elem.style.display = show ? values[ index ] || "" : "none";
+               }
+       }
+
+       return elements;
+}
+
+jQuery.extend({
+       // Add in style property hooks for overriding the default
+       // behavior of getting and setting a style property
+       cssHooks: {
+               opacity: {
+                       get: function( elem, computed ) {
+                               if ( computed ) {
+                                       // We should always get a number back from opacity
+                                       var ret = curCSS( elem, "opacity" );
+                                       return ret === "" ? "1" : ret;
+                               }
+                       }
+               }
+       },
+
+       // Don't automatically add "px" to these possibly-unitless properties
+       cssNumber: {
+               "columnCount": true,
+               "fillOpacity": true,
+               "flexGrow": true,
+               "flexShrink": true,
+               "fontWeight": true,
+               "lineHeight": true,
+               "opacity": true,
+               "order": true,
+               "orphans": true,
+               "widows": true,
+               "zIndex": true,
+               "zoom": true
+       },
+
+       // Add in properties whose names you wish to fix before
+       // setting or getting the value
+       cssProps: {
+               // normalize float css property
+               "float": "cssFloat"
+       },
+
+       // Get and set the style property on a DOM Node
+       style: function( elem, name, value, extra ) {
+               // Don't set styles on text and comment nodes
+               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+                       return;
+               }
+
+               // Make sure that we're working with the right name
+               var ret, type, hooks,
+                       origName = jQuery.camelCase( name ),
+                       style = elem.style;
+
+               name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
+
+               // gets hook for the prefixed version
+               // followed by the unprefixed version
+               hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+               // Check if we're setting a value
+               if ( value !== undefined ) {
+                       type = typeof value;
+
+                       // convert relative number strings (+= or -=) to relative numbers. #7345
+                       if ( type === "string" && (ret = rrelNum.exec( value )) ) {
+                               value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
+                               // Fixes bug #9237
+                               type = "number";
+                       }
+
+                       // Make sure that null and NaN values aren't set. See: #7116
+                       if ( value == null || value !== value ) {
+                               return;
+                       }
+
+                       // If a number was passed in, add 'px' to the (except for certain CSS properties)
+                       if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
+                               value += "px";
+                       }
+
+                       // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
+                       // but it would mean to define eight (for every problematic property) identical functions
+                       if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
+                               style[ name ] = "inherit";
+                       }
+
+                       // If a hook was provided, use that value, otherwise just set the specified value
+                       if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
+                               style[ name ] = value;
+                       }
+
+               } else {
+                       // If a hook was provided get the non-computed value from there
+                       if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+                               return ret;
+                       }
+
+                       // Otherwise just get the value from the style object
+                       return style[ name ];
+               }
+       },
+
+       css: function( elem, name, extra, styles ) {
+               var val, num, hooks,
+                       origName = jQuery.camelCase( name );
+
+               // Make sure that we're working with the right name
+               name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
+
+               // gets hook for the prefixed version
+               // followed by the unprefixed version
+               hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+               // If a hook was provided get the computed value from there
+               if ( hooks && "get" in hooks ) {
+                       val = hooks.get( elem, true, extra );
+               }
+
+               // Otherwise, if a way to get the computed value exists, use that
+               if ( val === undefined ) {
+                       val = curCSS( elem, name, styles );
+               }
+
+               //convert "normal" to computed value
+               if ( val === "normal" && name in cssNormalTransform ) {
+                       val = cssNormalTransform[ name ];
+               }
+
+               // Return, converting to number if forced or a qualifier was provided and val looks numeric
+               if ( extra === "" || extra ) {
+                       num = parseFloat( val );
+                       return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
+               }
+               return val;
+       }
+});
+
+jQuery.each([ "height", "width" ], function( i, name ) {
+       jQuery.cssHooks[ name ] = {
+               get: function( elem, computed, extra ) {
+                       if ( computed ) {
+                               // certain elements can have dimension info if we invisibly show them
+                               // however, it must have a current display style that would benefit from this
+                               return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
+                                       jQuery.swap( elem, cssShow, function() {
+                                               return getWidthOrHeight( elem, name, extra );
+                                       }) :
+                                       getWidthOrHeight( elem, name, extra );
+                       }
+               },
+
+               set: function( elem, value, extra ) {
+                       var styles = extra && getStyles( elem );
+                       return setPositiveNumber( elem, value, extra ?
+                               augmentWidthOrHeight(
+                                       elem,
+                                       name,
+                                       extra,
+                                       jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+                                       styles
+                               ) : 0
+                       );
+               }
+       };
+});
+
+// Support: Android 2.3
+jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
+       function( elem, computed ) {
+               if ( computed ) {
+                       // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+                       // Work around by temporarily setting element display to inline-block
+                       return jQuery.swap( elem, { "display": "inline-block" },
+                               curCSS, [ elem, "marginRight" ] );
+               }
+       }
+);
+
+// These hooks are used by animate to expand properties
+jQuery.each({
+       margin: "",
+       padding: "",
+       border: "Width"
+}, function( prefix, suffix ) {
+       jQuery.cssHooks[ prefix + suffix ] = {
+               expand: function( value ) {
+                       var i = 0,
+                               expanded = {},
+
+                               // assumes a single number if not a string
+                               parts = typeof value === "string" ? value.split(" ") : [ value ];
+
+                       for ( ; i < 4; i++ ) {
+                               expanded[ prefix + cssExpand[ i ] + suffix ] =
+                                       parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+                       }
+
+                       return expanded;
+               }
+       };
+
+       if ( !rmargin.test( prefix ) ) {
+               jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+       }
+});
+
+jQuery.fn.extend({
+       css: function( name, value ) {
+               return access( this, function( elem, name, value ) {
+                       var styles, len,
+                               map = {},
+                               i = 0;
+
+                       if ( jQuery.isArray( name ) ) {
+                               styles = getStyles( elem );
+                               len = name.length;
+
+                               for ( ; i < len; i++ ) {
+                                       map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+                               }
+
+                               return map;
+                       }
+
+                       return value !== undefined ?
+                               jQuery.style( elem, name, value ) :
+                               jQuery.css( elem, name );
+               }, name, value, arguments.length > 1 );
+       },
+       show: function() {
+               return showHide( this, true );
+       },
+       hide: function() {
+               return showHide( this );
+       },
+       toggle: function( state ) {
+               if ( typeof state === "boolean" ) {
+                       return state ? this.show() : this.hide();
+               }
+
+               return this.each(function() {
+                       if ( isHidden( this ) ) {
+                               jQuery( this ).show();
+                       } else {
+                               jQuery( this ).hide();
+                       }
+               });
+       }
+});
+
+
+function Tween( elem, options, prop, end, easing ) {
+       return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+       constructor: Tween,
+       init: function( elem, options, prop, end, easing, unit ) {
+               this.elem = elem;
+               this.prop = prop;
+               this.easing = easing || "swing";
+               this.options = options;
+               this.start = this.now = this.cur();
+               this.end = end;
+               this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+       },
+       cur: function() {
+               var hooks = Tween.propHooks[ this.prop ];
+
+               return hooks && hooks.get ?
+                       hooks.get( this ) :
+                       Tween.propHooks._default.get( this );
+       },
+       run: function( percent ) {
+               var eased,
+                       hooks = Tween.propHooks[ this.prop ];
+
+               if ( this.options.duration ) {
+                       this.pos = eased = jQuery.easing[ this.easing ](
+                               percent, this.options.duration * percent, 0, 1, this.options.duration
+                       );
+               } else {
+                       this.pos = eased = percent;
+               }
+               this.now = ( this.end - this.start ) * eased + this.start;
+
+               if ( this.options.step ) {
+                       this.options.step.call( this.elem, this.now, this );
+               }
+
+               if ( hooks && hooks.set ) {
+                       hooks.set( this );
+               } else {
+                       Tween.propHooks._default.set( this );
+               }
+               return this;
+       }
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+       _default: {
+               get: function( tween ) {
+                       var result;
+
+                       if ( tween.elem[ tween.prop ] != null &&
+                               (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
+                               return tween.elem[ tween.prop ];
+                       }
+
+                       // passing an empty string as a 3rd parameter to .css will automatically
+                       // attempt a parseFloat and fallback to a string if the parse fails
+                       // so, simple values such as "10px" are parsed to Float.
+                       // complex values such as "rotate(1rad)" are returned as is.
+                       result = jQuery.css( tween.elem, tween.prop, "" );
+                       // Empty strings, null, undefined and "auto" are converted to 0.
+                       return !result || result === "auto" ? 0 : result;
+               },
+               set: function( tween ) {
+                       // use step hook for back compat - use cssHook if its there - use .style if its
+                       // available and use plain properties where available
+                       if ( jQuery.fx.step[ tween.prop ] ) {
+                               jQuery.fx.step[ tween.prop ]( tween );
+                       } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
+                               jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+                       } else {
+                               tween.elem[ tween.prop ] = tween.now;
+                       }
+               }
+       }
+};
+
+// Support: IE9
+// Panic based approach to setting things on disconnected nodes
+
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+       set: function( tween ) {
+               if ( tween.elem.nodeType && tween.elem.parentNode ) {
+                       tween.elem[ tween.prop ] = tween.now;
+               }
+       }
+};
+
+jQuery.easing = {
+       linear: function( p ) {
+               return p;
+       },
+       swing: function( p ) {
+               return 0.5 - Math.cos( p * Math.PI ) / 2;
+       }
+};
+
+jQuery.fx = Tween.prototype.init;
+
+// Back Compat <1.8 extension point
+jQuery.fx.step = {};
+
+
+
+
+var
+       fxNow, timerId,
+       rfxtypes = /^(?:toggle|show|hide)$/,
+       rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
+       rrun = /queueHooks$/,
+       animationPrefilters = [ defaultPrefilter ],
+       tweeners = {
+               "*": [ function( prop, value ) {
+                       var tween = this.createTween( prop, value ),
+                               target = tween.cur(),
+                               parts = rfxnum.exec( value ),
+                               unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+                               // Starting value computation is required for potential unit mismatches
+                               start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
+                                       rfxnum.exec( jQuery.css( tween.elem, prop ) ),
+                               scale = 1,
+                               maxIterations = 20;
+
+                       if ( start && start[ 3 ] !== unit ) {
+                               // Trust units reported by jQuery.css
+                               unit = unit || start[ 3 ];
+
+                               // Make sure we update the tween properties later on
+                               parts = parts || [];
+
+                               // Iteratively approximate from a nonzero starting point
+                               start = +target || 1;
+
+                               do {
+                                       // If previous iteration zeroed out, double until we get *something*
+                                       // Use a string for doubling factor so we don't accidentally see scale as unchanged below
+                                       scale = scale || ".5";
+
+                                       // Adjust and apply
+                                       start = start / scale;
+                                       jQuery.style( tween.elem, prop, start + unit );
+
+                               // Update scale, tolerating zero or NaN from tween.cur()
+                               // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
+                               } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
+                       }
+
+                       // Update tween properties
+                       if ( parts ) {
+                               start = tween.start = +start || +target || 0;
+                               tween.unit = unit;
+                               // If a +=/-= token was provided, we're doing a relative animation
+                               tween.end = parts[ 1 ] ?
+                                       start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
+                                       +parts[ 2 ];
+                       }
+
+                       return tween;
+               } ]
+       };
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+       setTimeout(function() {
+               fxNow = undefined;
+       });
+       return ( fxNow = jQuery.now() );
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+       var which,
+               i = 0,
+               attrs = { height: type };
+
+       // if we include width, step value is 1 to do all cssExpand values,
+       // if we don't include width, step value is 2 to skip over Left and Right
+       includeWidth = includeWidth ? 1 : 0;
+       for ( ; i < 4 ; i += 2 - includeWidth ) {
+               which = cssExpand[ i ];
+               attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+       }
+
+       if ( includeWidth ) {
+               attrs.opacity = attrs.width = type;
+       }
+
+       return attrs;
+}
+
+function createTween( value, prop, animation ) {
+       var tween,
+               collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
+               index = 0,
+               length = collection.length;
+       for ( ; index < length; index++ ) {
+               if ( (tween = collection[ index ].call( animation, prop, value )) ) {
+
+                       // we're done with this property
+                       return tween;
+               }
+       }
+}
+
+function defaultPrefilter( elem, props, opts ) {
+       /* jshint validthis: true */
+       var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
+               anim = this,
+               orig = {},
+               style = elem.style,
+               hidden = elem.nodeType && isHidden( elem ),
+               dataShow = data_priv.get( elem, "fxshow" );
+
+       // handle queue: false promises
+       if ( !opts.queue ) {
+               hooks = jQuery._queueHooks( elem, "fx" );
+               if ( hooks.unqueued == null ) {
+                       hooks.unqueued = 0;
+                       oldfire = hooks.empty.fire;
+                       hooks.empty.fire = function() {
+                               if ( !hooks.unqueued ) {
+                                       oldfire();
+                               }
+                       };
+               }
+               hooks.unqueued++;
+
+               anim.always(function() {
+                       // doing this makes sure that the complete handler will be called
+                       // before this completes
+                       anim.always(function() {
+                               hooks.unqueued--;
+                               if ( !jQuery.queue( elem, "fx" ).length ) {
+                                       hooks.empty.fire();
+                               }
+                       });
+               });
+       }
+
+       // height/width overflow pass
+       if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
+               // Make sure that nothing sneaks out
+               // Record all 3 overflow attributes because IE9-10 do not
+               // change the overflow attribute when overflowX and
+               // overflowY are set to the same value
+               opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+               // Set display property to inline-block for height/width
+               // animations on inline elements that are having width/height animated
+               display = jQuery.css( elem, "display" );
+
+               // Test default display if display is currently "none"
+               checkDisplay = display === "none" ?
+                       data_priv.get( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
+
+               if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
+                       style.display = "inline-block";
+               }
+       }
+
+       if ( opts.overflow ) {
+               style.overflow = "hidden";
+               anim.always(function() {
+                       style.overflow = opts.overflow[ 0 ];
+                       style.overflowX = opts.overflow[ 1 ];
+                       style.overflowY = opts.overflow[ 2 ];
+               });
+       }
+
+       // show/hide pass
+       for ( prop in props ) {
+               value = props[ prop ];
+               if ( rfxtypes.exec( value ) ) {
+                       delete props[ prop ];
+                       toggle = toggle || value === "toggle";
+                       if ( value === ( hidden ? "hide" : "show" ) ) {
+
+                               // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
+                               if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
+                                       hidden = true;
+                               } else {
+                                       continue;
+                               }
+                       }
+                       orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+
+               // Any non-fx value stops us from restoring the original display value
+               } else {
+                       display = undefined;
+               }
+       }
+
+       if ( !jQuery.isEmptyObject( orig ) ) {
+               if ( dataShow ) {
+                       if ( "hidden" in dataShow ) {
+                               hidden = dataShow.hidden;
+                       }
+               } else {
+                       dataShow = data_priv.access( elem, "fxshow", {} );
+               }
+
+               // store state if its toggle - enables .stop().toggle() to "reverse"
+               if ( toggle ) {
+                       dataShow.hidden = !hidden;
+               }
+               if ( hidden ) {
+                       jQuery( elem ).show();
+               } else {
+                       anim.done(function() {
+                               jQuery( elem ).hide();
+                       });
+               }
+               anim.done(function() {
+                       var prop;
+
+                       data_priv.remove( elem, "fxshow" );
+                       for ( prop in orig ) {
+                               jQuery.style( elem, prop, orig[ prop ] );
+                       }
+               });
+               for ( prop in orig ) {
+                       tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+
+                       if ( !( prop in dataShow ) ) {
+                               dataShow[ prop ] = tween.start;
+                               if ( hidden ) {
+                                       tween.end = tween.start;
+                                       tween.start = prop === "width" || prop === "height" ? 1 : 0;
+                               }
+                       }
+               }
+
+       // If this is a noop like .hide().hide(), restore an overwritten display value
+       } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
+               style.display = display;
+       }
+}
+
+function propFilter( props, specialEasing ) {
+       var index, name, easing, value, hooks;
+
+       // camelCase, specialEasing and expand cssHook pass
+       for ( index in props ) {
+               name = jQuery.camelCase( index );
+               easing = specialEasing[ name ];
+               value = props[ index ];
+               if ( jQuery.isArray( value ) ) {
+                       easing = value[ 1 ];
+                       value = props[ index ] = value[ 0 ];
+               }
+
+               if ( index !== name ) {
+                       props[ name ] = value;
+                       delete props[ index ];
+               }
+
+               hooks = jQuery.cssHooks[ name ];
+               if ( hooks && "expand" in hooks ) {
+                       value = hooks.expand( value );
+                       delete props[ name ];
+
+                       // not quite $.extend, this wont overwrite keys already present.
+                       // also - reusing 'index' from above because we have the correct "name"
+                       for ( index in value ) {
+                               if ( !( index in props ) ) {
+                                       props[ index ] = value[ index ];
+                                       specialEasing[ index ] = easing;
+                               }
+                       }
+               } else {
+                       specialEasing[ name ] = easing;
+               }
+       }
+}
+
+function Animation( elem, properties, options ) {
+       var result,
+               stopped,
+               index = 0,
+               length = animationPrefilters.length,
+               deferred = jQuery.Deferred().always( function() {
+                       // don't match elem in the :animated selector
+                       delete tick.elem;
+               }),
+               tick = function() {
+                       if ( stopped ) {
+                               return false;
+                       }
+                       var currentTime = fxNow || createFxNow(),
+                               remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
+                               // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
+                               temp = remaining / animation.duration || 0,
+                               percent = 1 - temp,
+                               index = 0,
+                               length = animation.tweens.length;
+
+                       for ( ; index < length ; index++ ) {
+                               animation.tweens[ index ].run( percent );
+                       }
+
+                       deferred.notifyWith( elem, [ animation, percent, remaining ]);
+
+                       if ( percent < 1 && length ) {
+                               return remaining;
+                       } else {
+                               deferred.resolveWith( elem, [ animation ] );
+                               return false;
+                       }
+               },
+               animation = deferred.promise({
+                       elem: elem,
+                       props: jQuery.extend( {}, properties ),
+                       opts: jQuery.extend( true, { specialEasing: {} }, options ),
+                       originalProperties: properties,
+                       originalOptions: options,
+                       startTime: fxNow || createFxNow(),
+                       duration: options.duration,
+                       tweens: [],
+                       createTween: function( prop, end ) {
+                               var tween = jQuery.Tween( elem, animation.opts, prop, end,
+                                               animation.opts.specialEasing[ prop ] || animation.opts.easing );
+                               animation.tweens.push( tween );
+                               return tween;
+                       },
+                       stop: function( gotoEnd ) {
+                               var index = 0,
+                                       // if we are going to the end, we want to run all the tweens
+                                       // otherwise we skip this part
+                                       length = gotoEnd ? animation.tweens.length : 0;
+                               if ( stopped ) {
+                                       return this;
+                               }
+                               stopped = true;
+                               for ( ; index < length ; index++ ) {
+                                       animation.tweens[ index ].run( 1 );
+                               }
+
+                               // resolve when we played the last frame
+                               // otherwise, reject
+                               if ( gotoEnd ) {
+                                       deferred.resolveWith( elem, [ animation, gotoEnd ] );
+                               } else {
+                                       deferred.rejectWith( elem, [ animation, gotoEnd ] );
+                               }
+                               return this;
+                       }
+               }),
+               props = animation.props;
+
+       propFilter( props, animation.opts.specialEasing );
+
+       for ( ; index < length ; index++ ) {
+               result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
+               if ( result ) {
+                       return result;
+               }
+       }
+
+       jQuery.map( props, createTween, animation );
+
+       if ( jQuery.isFunction( animation.opts.start ) ) {
+               animation.opts.start.call( elem, animation );
+       }
+
+       jQuery.fx.timer(
+               jQuery.extend( tick, {
+                       elem: elem,
+                       anim: animation,
+                       queue: animation.opts.queue
+               })
+       );
+
+       // attach callbacks from options
+       return animation.progress( animation.opts.progress )
+               .done( animation.opts.done, animation.opts.complete )
+               .fail( animation.opts.fail )
+               .always( animation.opts.always );
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+       tweener: function( props, callback ) {
+               if ( jQuery.isFunction( props ) ) {
+                       callback = props;
+                       props = [ "*" ];
+               } else {
+                       props = props.split(" ");
+               }
+
+               var prop,
+                       index = 0,
+                       length = props.length;
+
+               for ( ; index < length ; index++ ) {
+                       prop = props[ index ];
+                       tweeners[ prop ] = tweeners[ prop ] || [];
+                       tweeners[ prop ].unshift( callback );
+               }
+       },
+
+       prefilter: function( callback, prepend ) {
+               if ( prepend ) {
+                       animationPrefilters.unshift( callback );
+               } else {
+                       animationPrefilters.push( callback );
+               }
+       }
+});
+
+jQuery.speed = function( speed, easing, fn ) {
+       var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+               complete: fn || !fn && easing ||
+                       jQuery.isFunction( speed ) && speed,
+               duration: speed,
+               easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+       };
+
+       opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+               opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
+
+       // normalize opt.queue - true/undefined/null -> "fx"
+       if ( opt.queue == null || opt.queue === true ) {
+               opt.queue = "fx";
+       }
+
+       // Queueing
+       opt.old = opt.complete;
+
+       opt.complete = function() {
+               if ( jQuery.isFunction( opt.old ) ) {
+                       opt.old.call( this );
+               }
+
+               if ( opt.queue ) {
+                       jQuery.dequeue( this, opt.queue );
+               }
+       };
+
+       return opt;
+};
+
+jQuery.fn.extend({
+       fadeTo: function( speed, to, easing, callback ) {
+
+               // show any hidden elements after setting opacity to 0
+               return this.filter( isHidden ).css( "opacity", 0 ).show()
+
+                       // animate to the value specified
+                       .end().animate({ opacity: to }, speed, easing, callback );
+       },
+       animate: function( prop, speed, easing, callback ) {
+               var empty = jQuery.isEmptyObject( prop ),
+                       optall = jQuery.speed( speed, easing, callback ),
+                       doAnimation = function() {
+                               // Operate on a copy of prop so per-property easing won't be lost
+                               var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+                               // Empty animations, or finishing resolves immediately
+                               if ( empty || data_priv.get( this, "finish" ) ) {
+                                       anim.stop( true );
+                               }
+                       };
+                       doAnimation.finish = doAnimation;
+
+               return empty || optall.queue === false ?
+                       this.each( doAnimation ) :
+                       this.queue( optall.queue, doAnimation );
+       },
+       stop: function( type, clearQueue, gotoEnd ) {
+               var stopQueue = function( hooks ) {
+                       var stop = hooks.stop;
+                       delete hooks.stop;
+                       stop( gotoEnd );
+               };
+
+               if ( typeof type !== "string" ) {
+                       gotoEnd = clearQueue;
+                       clearQueue = type;
+                       type = undefined;
+               }
+               if ( clearQueue && type !== false ) {
+                       this.queue( type || "fx", [] );
+               }
+
+               return this.each(function() {
+                       var dequeue = true,
+                               index = type != null && type + "queueHooks",
+                               timers = jQuery.timers,
+                               data = data_priv.get( this );
+
+                       if ( index ) {
+                               if ( data[ index ] && data[ index ].stop ) {
+                                       stopQueue( data[ index ] );
+                               }
+                       } else {
+                               for ( index in data ) {
+                                       if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+                                               stopQueue( data[ index ] );
+                                       }
+                               }
+                       }
+
+                       for ( index = timers.length; index--; ) {
+                               if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
+                                       timers[ index ].anim.stop( gotoEnd );
+                                       dequeue = false;
+                                       timers.splice( index, 1 );
+                               }
+                       }
+
+                       // start the next in the queue if the last step wasn't forced
+                       // timers currently will call their complete callbacks, which will dequeue
+                       // but only if they were gotoEnd
+                       if ( dequeue || !gotoEnd ) {
+                               jQuery.dequeue( this, type );
+                       }
+               });
+       },
+       finish: function( type ) {
+               if ( type !== false ) {
+                       type = type || "fx";
+               }
+               return this.each(function() {
+                       var index,
+                               data = data_priv.get( this ),
+                               queue = data[ type + "queue" ],
+                               hooks = data[ type + "queueHooks" ],
+                               timers = jQuery.timers,
+                               length = queue ? queue.length : 0;
+
+                       // enable finishing flag on private data
+                       data.finish = true;
+
+                       // empty the queue first
+                       jQuery.queue( this, type, [] );
+
+                       if ( hooks && hooks.stop ) {
+                               hooks.stop.call( this, true );
+                       }
+
+                       // look for any active animations, and finish them
+                       for ( index = timers.length; index--; ) {
+                               if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+                                       timers[ index ].anim.stop( true );
+                                       timers.splice( index, 1 );
+                               }
+                       }
+
+                       // look for any animations in the old queue and finish them
+                       for ( index = 0; index < length; index++ ) {
+                               if ( queue[ index ] && queue[ index ].finish ) {
+                                       queue[ index ].finish.call( this );
+                               }
+                       }
+
+                       // turn off finishing flag
+                       delete data.finish;
+               });
+       }
+});
+
+jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
+       var cssFn = jQuery.fn[ name ];
+       jQuery.fn[ name ] = function( speed, easing, callback ) {
+               return speed == null || typeof speed === "boolean" ?
+                       cssFn.apply( this, arguments ) :
+                       this.animate( genFx( name, true ), speed, easing, callback );
+       };
+});
+
+// Generate shortcuts for custom animations
+jQuery.each({
+       slideDown: genFx("show"),
+       slideUp: genFx("hide"),
+       slideToggle: genFx("toggle"),
+       fadeIn: { opacity: "show" },
+       fadeOut: { opacity: "hide" },
+       fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+       jQuery.fn[ name ] = function( speed, easing, callback ) {
+               return this.animate( props, speed, easing, callback );
+       };
+});
+
+jQuery.timers = [];
+jQuery.fx.tick = function() {
+       var timer,
+               i = 0,
+               timers = jQuery.timers;
+
+       fxNow = jQuery.now();
+
+       for ( ; i < timers.length; i++ ) {
+               timer = timers[ i ];
+               // Checks the timer has not already been removed
+               if ( !timer() && timers[ i ] === timer ) {
+                       timers.splice( i--, 1 );
+               }
+       }
+
+       if ( !timers.length ) {
+               jQuery.fx.stop();
+       }
+       fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+       jQuery.timers.push( timer );
+       if ( timer() ) {
+               jQuery.fx.start();
+       } else {
+               jQuery.timers.pop();
+       }
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+       if ( !timerId ) {
+               timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+       }
+};
+
+jQuery.fx.stop = function() {
+       clearInterval( timerId );
+       timerId = null;
+};
+
+jQuery.fx.speeds = {
+       slow: 600,
+       fast: 200,
+       // Default speed
+       _default: 400
+};
+
+
+// Based off of the plugin by Clint Helfers, with permission.
+// http://blindsignals.com/index.php/2009/07/jquery-delay/
+jQuery.fn.delay = function( time, type ) {
+       time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+       type = type || "fx";
+
+       return this.queue( type, function( next, hooks ) {
+               var timeout = setTimeout( next, time );
+               hooks.stop = function() {
+                       clearTimeout( timeout );
+               };
+       });
+};
+
+
+(function() {
+       var input = document.createElement( "input" ),
+               select = document.createElement( "select" ),
+               opt = select.appendChild( document.createElement( "option" ) );
+
+       input.type = "checkbox";
+
+       // Support: iOS 5.1, Android 4.x, Android 2.3
+       // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
+       support.checkOn = input.value !== "";
+
+       // Must access the parent to make an option select properly
+       // Support: IE9, IE10
+       support.optSelected = opt.selected;
+
+       // Make sure that the options inside disabled selects aren't marked as disabled
+       // (WebKit marks them as disabled)
+       select.disabled = true;
+       support.optDisabled = !opt.disabled;
+
+       // Check if an input maintains its value after becoming a radio
+       // Support: IE9, IE10
+       input = document.createElement( "input" );
+       input.value = "t";
+       input.type = "radio";
+       support.radioValue = input.value === "t";
+})();
+
+
+var nodeHook, boolHook,
+       attrHandle = jQuery.expr.attrHandle;
+
+jQuery.fn.extend({
+       attr: function( name, value ) {
+               return access( this, jQuery.attr, name, value, arguments.length > 1 );
+       },
+
+       removeAttr: function( name ) {
+               return this.each(function() {
+                       jQuery.removeAttr( this, name );
+               });
+       }
+});
+
+jQuery.extend({
+       attr: function( elem, name, value ) {
+               var hooks, ret,
+                       nType = elem.nodeType;
+
+               // don't get/set attributes on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+                       return;
+               }
+
+               // Fallback to prop when attributes are not supported
+               if ( typeof elem.getAttribute === strundefined ) {
+                       return jQuery.prop( elem, name, value );
+               }
+
+               // All attributes are lowercase
+               // Grab necessary hook if one is defined
+               if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+                       name = name.toLowerCase();
+                       hooks = jQuery.attrHooks[ name ] ||
+                               ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
+               }
+
+               if ( value !== undefined ) {
+
+                       if ( value === null ) {
+                               jQuery.removeAttr( elem, name );
+
+                       } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+                               return ret;
+
+                       } else {
+                               elem.setAttribute( name, value + "" );
+                               return value;
+                       }
+
+               } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+                       return ret;
+
+               } else {
+                       ret = jQuery.find.attr( elem, name );
+
+                       // Non-existent attributes return null, we normalize to undefined
+                       return ret == null ?
+                               undefined :
+                               ret;
+               }
+       },
+
+       removeAttr: function( elem, value ) {
+               var name, propName,
+                       i = 0,
+                       attrNames = value && value.match( rnotwhite );
+
+               if ( attrNames && elem.nodeType === 1 ) {
+                       while ( (name = attrNames[i++]) ) {
+                               propName = jQuery.propFix[ name ] || name;
+
+                               // Boolean attributes get special treatment (#10870)
+                               if ( jQuery.expr.match.bool.test( name ) ) {
+                                       // Set corresponding property to false
+                                       elem[ propName ] = false;
+                               }
+
+                               elem.removeAttribute( name );
+                       }
+               }
+       },
+
+       attrHooks: {
+               type: {
+                       set: function( elem, value ) {
+                               if ( !support.radioValue && value === "radio" &&
+                                       jQuery.nodeName( elem, "input" ) ) {
+                                       // Setting the type on a radio button after the value resets the value in IE6-9
+                                       // Reset value to default in case type is set after value during creation
+                                       var val = elem.value;
+                                       elem.setAttribute( "type", value );
+                                       if ( val ) {
+                                               elem.value = val;
+                                       }
+                                       return value;
+                               }
+                       }
+               }
+       }
+});
+
+// Hooks for boolean attributes
+boolHook = {
+       set: function( elem, value, name ) {
+               if ( value === false ) {
+                       // Remove boolean attributes when set to false
+                       jQuery.removeAttr( elem, name );
+               } else {
+                       elem.setAttribute( name, name );
+               }
+               return name;
+       }
+};
+jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+       var getter = attrHandle[ name ] || jQuery.find.attr;
+
+       attrHandle[ name ] = function( elem, name, isXML ) {
+               var ret, handle;
+               if ( !isXML ) {
+                       // Avoid an infinite loop by temporarily removing this function from the getter
+                       handle = attrHandle[ name ];
+                       attrHandle[ name ] = ret;
+                       ret = getter( elem, name, isXML ) != null ?
+                               name.toLowerCase() :
+                               null;
+                       attrHandle[ name ] = handle;
+               }
+               return ret;
+       };
+});
+
+
+
+
+var rfocusable = /^(?:input|select|textarea|button)$/i;
+
+jQuery.fn.extend({
+       prop: function( name, value ) {
+               return access( this, jQuery.prop, name, value, arguments.length > 1 );
+       },
+
+       removeProp: function( name ) {
+               return this.each(function() {
+                       delete this[ jQuery.propFix[ name ] || name ];
+               });
+       }
+});
+
+jQuery.extend({
+       propFix: {
+               "for": "htmlFor",
+               "class": "className"
+       },
+
+       prop: function( elem, name, value ) {
+               var ret, hooks, notxml,
+                       nType = elem.nodeType;
+
+               // don't get/set properties on text, comment and attribute nodes
+               if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+                       return;
+               }
+
+               notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+               if ( notxml ) {
+                       // Fix name and attach hooks
+                       name = jQuery.propFix[ name ] || name;
+                       hooks = jQuery.propHooks[ name ];
+               }
+
+               if ( value !== undefined ) {
+                       return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
+                               ret :
+                               ( elem[ name ] = value );
+
+               } else {
+                       return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
+                               ret :
+                               elem[ name ];
+               }
+       },
+
+       propHooks: {
+               tabIndex: {
+                       get: function( elem ) {
+                               return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
+                                       elem.tabIndex :
+                                       -1;
+                       }
+               }
+       }
+});
+
+// Support: IE9+
+// Selectedness for an option in an optgroup can be inaccurate
+if ( !support.optSelected ) {
+       jQuery.propHooks.selected = {
+               get: function( elem ) {
+                       var parent = elem.parentNode;
+                       if ( parent && parent.parentNode ) {
+                               parent.parentNode.selectedIndex;
+                       }
+                       return null;
+               }
+       };
+}
+
+jQuery.each([
+       "tabIndex",
+       "readOnly",
+       "maxLength",
+       "cellSpacing",
+       "cellPadding",
+       "rowSpan",
+       "colSpan",
+       "useMap",
+       "frameBorder",
+       "contentEditable"
+], function() {
+       jQuery.propFix[ this.toLowerCase() ] = this;
+});
+
+
+
+
+var rclass = /[\t\r\n\f]/g;
+
+jQuery.fn.extend({
+       addClass: function( value ) {
+               var classes, elem, cur, clazz, j, finalValue,
+                       proceed = typeof value === "string" && value,
+                       i = 0,
+                       len = this.length;
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function( j ) {
+                               jQuery( this ).addClass( value.call( this, j, this.className ) );
+                       });
+               }
+
+               if ( proceed ) {
+                       // The disjunction here is for better compressibility (see removeClass)
+                       classes = ( value || "" ).match( rnotwhite ) || [];
+
+                       for ( ; i < len; i++ ) {
+                               elem = this[ i ];
+                               cur = elem.nodeType === 1 && ( elem.className ?
+                                       ( " " + elem.className + " " ).replace( rclass, " " ) :
+                                       " "
+                               );
+
+                               if ( cur ) {
+                                       j = 0;
+                                       while ( (clazz = classes[j++]) ) {
+                                               if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+                                                       cur += clazz + " ";
+                                               }
+                                       }
+
+                                       // only assign if different to avoid unneeded rendering.
+                                       finalValue = jQuery.trim( cur );
+                                       if ( elem.className !== finalValue ) {
+                                               elem.className = finalValue;
+                                       }
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       removeClass: function( value ) {
+               var classes, elem, cur, clazz, j, finalValue,
+                       proceed = arguments.length === 0 || typeof value === "string" && value,
+                       i = 0,
+                       len = this.length;
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function( j ) {
+                               jQuery( this ).removeClass( value.call( this, j, this.className ) );
+                       });
+               }
+               if ( proceed ) {
+                       classes = ( value || "" ).match( rnotwhite ) || [];
+
+                       for ( ; i < len; i++ ) {
+                               elem = this[ i ];
+                               // This expression is here for better compressibility (see addClass)
+                               cur = elem.nodeType === 1 && ( elem.className ?
+                                       ( " " + elem.className + " " ).replace( rclass, " " ) :
+                                       ""
+                               );
+
+                               if ( cur ) {
+                                       j = 0;
+                                       while ( (clazz = classes[j++]) ) {
+                                               // Remove *all* instances
+                                               while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
+                                                       cur = cur.replace( " " + clazz + " ", " " );
+                                               }
+                                       }
+
+                                       // only assign if different to avoid unneeded rendering.
+                                       finalValue = value ? jQuery.trim( cur ) : "";
+                                       if ( elem.className !== finalValue ) {
+                                               elem.className = finalValue;
+                                       }
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       toggleClass: function( value, stateVal ) {
+               var type = typeof value;
+
+               if ( typeof stateVal === "boolean" && type === "string" ) {
+                       return stateVal ? this.addClass( value ) : this.removeClass( value );
+               }
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each(function( i ) {
+                               jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
+                       });
+               }
+
+               return this.each(function() {
+                       if ( type === "string" ) {
+                               // toggle individual class names
+                               var className,
+                                       i = 0,
+                                       self = jQuery( this ),
+                                       classNames = value.match( rnotwhite ) || [];
+
+                               while ( (className = classNames[ i++ ]) ) {
+                                       // check each className given, space separated list
+                                       if ( self.hasClass( className ) ) {
+                                               self.removeClass( className );
+                                       } else {
+                                               self.addClass( className );
+                                       }
+                               }
+
+                       // Toggle whole class name
+                       } else if ( type === strundefined || type === "boolean" ) {
+                               if ( this.className ) {
+                                       // store className if set
+                                       data_priv.set( this, "__className__", this.className );
+                               }
+
+                               // If the element has a class name or if we're passed "false",
+                               // then remove the whole classname (if there was one, the above saved it).
+                               // Otherwise bring back whatever was previously saved (if anything),
+                               // falling back to the empty string if nothing was stored.
+                               this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
+                       }
+               });
+       },
+
+       hasClass: function( selector ) {
+               var className = " " + selector + " ",
+                       i = 0,
+                       l = this.length;
+               for ( ; i < l; i++ ) {
+                       if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
+                               return true;
+                       }
+               }
+
+               return false;
+       }
+});
+
+
+
+
+var rreturn = /\r/g;
+
+jQuery.fn.extend({
+       val: function( value ) {
+               var hooks, ret, isFunction,
+                       elem = this[0];
+
+               if ( !arguments.length ) {
+                       if ( elem ) {
+                               hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+                               if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
+                                       return ret;
+                               }
+
+                               ret = elem.value;
+
+                               return typeof ret === "string" ?
+                                       // handle most common string cases
+                                       ret.replace(rreturn, "") :
+                                       // handle cases where value is null/undef or number
+                                       ret == null ? "" : ret;
+                       }
+
+                       return;
+               }
+
+               isFunction = jQuery.isFunction( value );
+
+               return this.each(function( i ) {
+                       var val;
+
+                       if ( this.nodeType !== 1 ) {
+                               return;
+                       }
+
+                       if ( isFunction ) {
+                               val = value.call( this, i, jQuery( this ).val() );
+                       } else {
+                               val = value;
+                       }
+
+                       // Treat null/undefined as ""; convert numbers to string
+                       if ( val == null ) {
+                               val = "";
+
+                       } else if ( typeof val === "number" ) {
+                               val += "";
+
+                       } else if ( jQuery.isArray( val ) ) {
+                               val = jQuery.map( val, function( value ) {
+                                       return value == null ? "" : value + "";
+                               });
+                       }
+
+                       hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
+
+                       // If set returns undefined, fall back to normal setting
+                       if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
+                               this.value = val;
+                       }
+               });
+       }
+});
+
+jQuery.extend({
+       valHooks: {
+               option: {
+                       get: function( elem ) {
+                               var val = jQuery.find.attr( elem, "value" );
+                               return val != null ?
+                                       val :
+                                       // Support: IE10-11+
+                                       // option.text throws exceptions (#14686, #14858)
+                                       jQuery.trim( jQuery.text( elem ) );
+                       }
+               },
+               select: {
+                       get: function( elem ) {
+                               var value, option,
+                                       options = elem.options,
+                                       index = elem.selectedIndex,
+                                       one = elem.type === "select-one" || index < 0,
+                                       values = one ? null : [],
+                                       max = one ? index + 1 : options.length,
+                                       i = index < 0 ?
+                                               max :
+                                               one ? index : 0;
+
+                               // Loop through all the selected options
+                               for ( ; i < max; i++ ) {
+                                       option = options[ i ];
+
+                                       // IE6-9 doesn't update selected after form reset (#2551)
+                                       if ( ( option.selected || i === index ) &&
+                                                       // Don't return options that are disabled or in a disabled optgroup
+                                                       ( support.optDisabled ? !option.disabled : option.getAttribute( "disabled" ) === null ) &&
+                                                       ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
+
+                                               // Get the specific value for the option
+                                               value = jQuery( option ).val();
+
+                                               // We don't need an array for one selects
+                                               if ( one ) {
+                                                       return value;
+                                               }
+
+                                               // Multi-Selects return an array
+                                               values.push( value );
+                                       }
+                               }
+
+                               return values;
+                       },
+
+                       set: function( elem, value ) {
+                               var optionSet, option,
+                                       options = elem.options,
+                                       values = jQuery.makeArray( value ),
+                                       i = options.length;
+
+                               while ( i-- ) {
+                                       option = options[ i ];
+                                       if ( (option.selected = jQuery.inArray( option.value, values ) >= 0) ) {
+                                               optionSet = true;
+                                       }
+                               }
+
+                               // force browsers to behave consistently when non-matching value is set
+                               if ( !optionSet ) {
+                                       elem.selectedIndex = -1;
+                               }
+                               return values;
+                       }
+               }
+       }
+});
+
+// Radios and checkboxes getter/setter
+jQuery.each([ "radio", "checkbox" ], function() {
+       jQuery.valHooks[ this ] = {
+               set: function( elem, value ) {
+                       if ( jQuery.isArray( value ) ) {
+                               return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
+                       }
+               }
+       };
+       if ( !support.checkOn ) {
+               jQuery.valHooks[ this ].get = function( elem ) {
+                       // Support: Webkit
+                       // "" is returned instead of "on" if a value isn't specified
+                       return elem.getAttribute("value") === null ? "on" : elem.value;
+               };
+       }
+});
+
+
+
+
+// Return jQuery for attributes-only inclusion
+
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+       "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+       "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
+
+       // Handle event binding
+       jQuery.fn[ name ] = function( data, fn ) {
+               return arguments.length > 0 ?
+                       this.on( name, null, data, fn ) :
+                       this.trigger( name );
+       };
+});
+
+jQuery.fn.extend({
+       hover: function( fnOver, fnOut ) {
+               return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+       },
+
+       bind: function( types, data, fn ) {
+               return this.on( types, null, data, fn );
+       },
+       unbind: function( types, fn ) {
+               return this.off( types, null, fn );
+       },
+
+       delegate: function( selector, types, data, fn ) {
+               return this.on( types, selector, data, fn );
+       },
+       undelegate: function( selector, types, fn ) {
+               // ( namespace ) or ( selector, types [, fn] )
+               return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
+       }
+});
+
+
+var nonce = jQuery.now();
+
+var rquery = (/\?/);
+
+
+
+// Support: Android 2.3
+// Workaround failure to string-cast null input
+jQuery.parseJSON = function( data ) {
+       return JSON.parse( data + "" );
+};
+
+
+// Cross-browser xml parsing
+jQuery.parseXML = function( data ) {
+       var xml, tmp;
+       if ( !data || typeof data !== "string" ) {
+               return null;
+       }
+
+       // Support: IE9
+       try {
+               tmp = new DOMParser();
+               xml = tmp.parseFromString( data, "text/xml" );
+       } catch ( e ) {
+               xml = undefined;
+       }
+
+       if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
+               jQuery.error( "Invalid XML: " + data );
+       }
+       return xml;
+};
+
+
+var
+       // Document location
+       ajaxLocParts,
+       ajaxLocation,
+
+       rhash = /#.*$/,
+       rts = /([?&])_=[^&]*/,
+       rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
+       // #7653, #8125, #8152: local protocol detection
+       rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+       rnoContent = /^(?:GET|HEAD)$/,
+       rprotocol = /^\/\//,
+       rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
+
+       /* Prefilters
+        * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+        * 2) These are called:
+        *    - BEFORE asking for a transport
+        *    - AFTER param serialization (s.data is a string if s.processData is true)
+        * 3) key is the dataType
+        * 4) the catchall symbol "*" can be used
+        * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+        */
+       prefilters = {},
+
+       /* Transports bindings
+        * 1) key is the dataType
+        * 2) the catchall symbol "*" can be used
+        * 3) selection will start with transport dataType and THEN go to "*" if needed
+        */
+       transports = {},
+
+       // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+       allTypes = "*/".concat("*");
+
+// #8138, IE may throw an exception when accessing
+// a field from window.location if document.domain has been set
+try {
+       ajaxLocation = location.href;
+} catch( e ) {
+       // Use the href attribute of an A element
+       // since IE will modify it given document.location
+       ajaxLocation = document.createElement( "a" );
+       ajaxLocation.href = "";
+       ajaxLocation = ajaxLocation.href;
+}
+
+// Segment location into parts
+ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+       // dataTypeExpression is optional and defaults to "*"
+       return function( dataTypeExpression, func ) {
+
+               if ( typeof dataTypeExpression !== "string" ) {
+                       func = dataTypeExpression;
+                       dataTypeExpression = "*";
+               }
+
+               var dataType,
+                       i = 0,
+                       dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
+
+               if ( jQuery.isFunction( func ) ) {
+                       // For each dataType in the dataTypeExpression
+                       while ( (dataType = dataTypes[i++]) ) {
+                               // Prepend if requested
+                               if ( dataType[0] === "+" ) {
+                                       dataType = dataType.slice( 1 ) || "*";
+                                       (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
+
+                               // Otherwise append
+                               } else {
+                                       (structure[ dataType ] = structure[ dataType ] || []).push( func );
+                               }
+                       }
+               }
+       };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+       var inspected = {},
+               seekingTransport = ( structure === transports );
+
+       function inspect( dataType ) {
+               var selected;
+               inspected[ dataType ] = true;
+               jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+                       var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+                       if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+                               options.dataTypes.unshift( dataTypeOrTransport );
+                               inspect( dataTypeOrTransport );
+                               return false;
+                       } else if ( seekingTransport ) {
+                               return !( selected = dataTypeOrTransport );
+                       }
+               });
+               return selected;
+       }
+
+       return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+       var key, deep,
+               flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+       for ( key in src ) {
+               if ( src[ key ] !== undefined ) {
+                       ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
+               }
+       }
+       if ( deep ) {
+               jQuery.extend( true, target, deep );
+       }
+
+       return target;
+}
+
+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+       var ct, type, finalDataType, firstDataType,
+               contents = s.contents,
+               dataTypes = s.dataTypes;
+
+       // Remove auto dataType and get content-type in the process
+       while ( dataTypes[ 0 ] === "*" ) {
+               dataTypes.shift();
+               if ( ct === undefined ) {
+                       ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
+               }
+       }
+
+       // Check if we're dealing with a known content-type
+       if ( ct ) {
+               for ( type in contents ) {
+                       if ( contents[ type ] && contents[ type ].test( ct ) ) {
+                               dataTypes.unshift( type );
+                               break;
+                       }
+               }
+       }
+
+       // Check to see if we have a response for the expected dataType
+       if ( dataTypes[ 0 ] in responses ) {
+               finalDataType = dataTypes[ 0 ];
+       } else {
+               // Try convertible dataTypes
+               for ( type in responses ) {
+                       if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
+                               finalDataType = type;
+                               break;
+                       }
+                       if ( !firstDataType ) {
+                               firstDataType = type;
+                       }
+               }
+               // Or just use first one
+               finalDataType = finalDataType || firstDataType;
+       }
+
+       // If we found a dataType
+       // We add the dataType to the list if needed
+       // and return the corresponding response
+       if ( finalDataType ) {
+               if ( finalDataType !== dataTypes[ 0 ] ) {
+                       dataTypes.unshift( finalDataType );
+               }
+               return responses[ finalDataType ];
+       }
+}
+
+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+       var conv2, current, conv, tmp, prev,
+               converters = {},
+               // Work with a copy of dataTypes in case we need to modify it for conversion
+               dataTypes = s.dataTypes.slice();
+
+       // Create converters map with lowercased keys
+       if ( dataTypes[ 1 ] ) {
+               for ( conv in s.converters ) {
+                       converters[ conv.toLowerCase() ] = s.converters[ conv ];
+               }
+       }
+
+       current = dataTypes.shift();
+
+       // Convert to each sequential dataType
+       while ( current ) {
+
+               if ( s.responseFields[ current ] ) {
+                       jqXHR[ s.responseFields[ current ] ] = response;
+               }
+
+               // Apply the dataFilter if provided
+               if ( !prev && isSuccess && s.dataFilter ) {
+                       response = s.dataFilter( response, s.dataType );
+               }
+
+               prev = current;
+               current = dataTypes.shift();
+
+               if ( current ) {
+
+               // There's only work to do if current dataType is non-auto
+                       if ( current === "*" ) {
+
+                               current = prev;
+
+                       // Convert response if prev dataType is non-auto and differs from current
+                       } else if ( prev !== "*" && prev !== current ) {
+
+                               // Seek a direct converter
+                               conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+                               // If none found, seek a pair
+                               if ( !conv ) {
+                                       for ( conv2 in converters ) {
+
+                                               // If conv2 outputs current
+                                               tmp = conv2.split( " " );
+                                               if ( tmp[ 1 ] === current ) {
+
+                                                       // If prev can be converted to accepted input
+                                                       conv = converters[ prev + " " + tmp[ 0 ] ] ||
+                                                               converters[ "* " + tmp[ 0 ] ];
+                                                       if ( conv ) {
+                                                               // Condense equivalence converters
+                                                               if ( conv === true ) {
+                                                                       conv = converters[ conv2 ];
+
+                                                               // Otherwise, insert the intermediate dataType
+                                                               } else if ( converters[ conv2 ] !== true ) {
+                                                                       current = tmp[ 0 ];
+                                                                       dataTypes.unshift( tmp[ 1 ] );
+                                                               }
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // Apply converter (if not an equivalence)
+                               if ( conv !== true ) {
+
+                                       // Unless errors are allowed to bubble, catch and return them
+                                       if ( conv && s[ "throws" ] ) {
+                                               response = conv( response );
+                                       } else {
+                                               try {
+                                                       response = conv( response );
+                                               } catch ( e ) {
+                                                       return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return { state: "success", data: response };
+}
+
+jQuery.extend({
+
+       // Counter for holding the number of active queries
+       active: 0,
+
+       // Last-Modified header cache for next request
+       lastModified: {},
+       etag: {},
+
+       ajaxSettings: {
+               url: ajaxLocation,
+               type: "GET",
+               isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+               global: true,
+               processData: true,
+               async: true,
+               contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+               /*
+               timeout: 0,
+               data: null,
+               dataType: null,
+               username: null,
+               password: null,
+               cache: null,
+               throws: false,
+               traditional: false,
+               headers: {},
+               */
+
+               accepts: {
+                       "*": allTypes,
+                       text: "text/plain",
+                       html: "text/html",
+                       xml: "application/xml, text/xml",
+                       json: "application/json, text/javascript"
+               },
+
+               contents: {
+                       xml: /xml/,
+                       html: /html/,
+                       json: /json/
+               },
+
+               responseFields: {
+                       xml: "responseXML",
+                       text: "responseText",
+                       json: "responseJSON"
+               },
+
+               // Data converters
+               // Keys separate source (or catchall "*") and destination types with a single space
+               converters: {
+
+                       // Convert anything to text
+                       "* text": String,
+
+                       // Text to html (true = no transformation)
+                       "text html": true,
+
+                       // Evaluate text as a json expression
+                       "text json": jQuery.parseJSON,
+
+                       // Parse text as xml
+                       "text xml": jQuery.parseXML
+               },
+
+               // For options that shouldn't be deep extended:
+               // you can add your own custom options here if
+               // and when you create one that shouldn't be
+               // deep extended (see ajaxExtend)
+               flatOptions: {
+                       url: true,
+                       context: true
+               }
+       },
+
+       // Creates a full fledged settings object into target
+       // with both ajaxSettings and settings fields.
+       // If target is omitted, writes into ajaxSettings.
+       ajaxSetup: function( target, settings ) {
+               return settings ?
+
+                       // Building a settings object
+                       ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+                       // Extending ajaxSettings
+                       ajaxExtend( jQuery.ajaxSettings, target );
+       },
+
+       ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+       ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+       // Main method
+       ajax: function( url, options ) {
+
+               // If url is an object, simulate pre-1.5 signature
+               if ( typeof url === "object" ) {
+                       options = url;
+                       url = undefined;
+               }
+
+               // Force options to be an object
+               options = options || {};
+
+               var transport,
+                       // URL without anti-cache param
+                       cacheURL,
+                       // Response headers
+                       responseHeadersString,
+                       responseHeaders,
+                       // timeout handle
+                       timeoutTimer,
+                       // Cross-domain detection vars
+                       parts,
+                       // To know if global events are to be dispatched
+                       fireGlobals,
+                       // Loop variable
+                       i,
+                       // Create the final options object
+                       s = jQuery.ajaxSetup( {}, options ),
+                       // Callbacks context
+                       callbackContext = s.context || s,
+                       // Context for global events is callbackContext if it is a DOM node or jQuery collection
+                       globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
+                               jQuery( callbackContext ) :
+                               jQuery.event,
+                       // Deferreds
+                       deferred = jQuery.Deferred(),
+                       completeDeferred = jQuery.Callbacks("once memory"),
+                       // Status-dependent callbacks
+                       statusCode = s.statusCode || {},
+                       // Headers (they are sent all at once)
+                       requestHeaders = {},
+                       requestHeadersNames = {},
+                       // The jqXHR state
+                       state = 0,
+                       // Default abort message
+                       strAbort = "canceled",
+                       // Fake xhr
+                       jqXHR = {
+                               readyState: 0,
+
+                               // Builds headers hashtable if needed
+                               getResponseHeader: function( key ) {
+                                       var match;
+                                       if ( state === 2 ) {
+                                               if ( !responseHeaders ) {
+                                                       responseHeaders = {};
+                                                       while ( (match = rheaders.exec( responseHeadersString )) ) {
+                                                               responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
+                                                       }
+                                               }
+                                               match = responseHeaders[ key.toLowerCase() ];
+                                       }
+                                       return match == null ? null : match;
+                               },
+
+                               // Raw string
+                               getAllResponseHeaders: function() {
+                                       return state === 2 ? responseHeadersString : null;
+                               },
+
+                               // Caches the header
+                               setRequestHeader: function( name, value ) {
+                                       var lname = name.toLowerCase();
+                                       if ( !state ) {
+                                               name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+                                               requestHeaders[ name ] = value;
+                                       }
+                                       return this;
+                               },
+
+                               // Overrides response content-type header
+                               overrideMimeType: function( type ) {
+                                       if ( !state ) {
+                                               s.mimeType = type;
+                                       }
+                                       return this;
+                               },
+
+                               // Status-dependent callbacks
+                               statusCode: function( map ) {
+                                       var code;
+                                       if ( map ) {
+                                               if ( state < 2 ) {
+                                                       for ( code in map ) {
+                                                               // Lazy-add the new callback in a way that preserves old ones
+                                                               statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+                                                       }
+                                               } else {
+                                                       // Execute the appropriate callbacks
+                                                       jqXHR.always( map[ jqXHR.status ] );
+                                               }
+                                       }
+                                       return this;
+                               },
+
+                               // Cancel the request
+                               abort: function( statusText ) {
+                                       var finalText = statusText || strAbort;
+                                       if ( transport ) {
+                                               transport.abort( finalText );
+                                       }
+                                       done( 0, finalText );
+                                       return this;
+                               }
+                       };
+
+               // Attach deferreds
+               deferred.promise( jqXHR ).complete = completeDeferred.add;
+               jqXHR.success = jqXHR.done;
+               jqXHR.error = jqXHR.fail;
+
+               // Remove hash character (#7531: and string promotion)
+               // Add protocol if not provided (prefilters might expect it)
+               // Handle falsy url in the settings object (#10093: consistency with old signature)
+               // We also use the url parameter if available
+               s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
+                       .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+               // Alias method option to type as per ticket #12004
+               s.type = options.method || options.type || s.method || s.type;
+
+               // Extract dataTypes list
+               s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
+
+               // A cross-domain request is in order when we have a protocol:host:port mismatch
+               if ( s.crossDomain == null ) {
+                       parts = rurl.exec( s.url.toLowerCase() );
+                       s.crossDomain = !!( parts &&
+                               ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
+                                       ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
+                                               ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
+                       );
+               }
+
+               // Convert data if not already a string
+               if ( s.data && s.processData && typeof s.data !== "string" ) {
+                       s.data = jQuery.param( s.data, s.traditional );
+               }
+
+               // Apply prefilters
+               inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+               // If request was aborted inside a prefilter, stop there
+               if ( state === 2 ) {
+                       return jqXHR;
+               }
+
+               // We can fire global events as of now if asked to
+               fireGlobals = s.global;
+
+               // Watch for a new set of requests
+               if ( fireGlobals && jQuery.active++ === 0 ) {
+                       jQuery.event.trigger("ajaxStart");
+               }
+
+               // Uppercase the type
+               s.type = s.type.toUpperCase();
+
+               // Determine if request has content
+               s.hasContent = !rnoContent.test( s.type );
+
+               // Save the URL in case we're toying with the If-Modified-Since
+               // and/or If-None-Match header later on
+               cacheURL = s.url;
+
+               // More options handling for requests with no content
+               if ( !s.hasContent ) {
+
+                       // If data is available, append data to url
+                       if ( s.data ) {
+                               cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+                               // #9682: remove data so that it's not used in an eventual retry
+                               delete s.data;
+                       }
+
+                       // Add anti-cache in url if needed
+                       if ( s.cache === false ) {
+                               s.url = rts.test( cacheURL ) ?
+
+                                       // If there is already a '_' parameter, set its value
+                                       cacheURL.replace( rts, "$1_=" + nonce++ ) :
+
+                                       // Otherwise add one to the end
+                                       cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
+                       }
+               }
+
+               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+               if ( s.ifModified ) {
+                       if ( jQuery.lastModified[ cacheURL ] ) {
+                               jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+                       }
+                       if ( jQuery.etag[ cacheURL ] ) {
+                               jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+                       }
+               }
+
+               // Set the correct header, if data is being sent
+               if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+                       jqXHR.setRequestHeader( "Content-Type", s.contentType );
+               }
+
+               // Set the Accepts header for the server, depending on the dataType
+               jqXHR.setRequestHeader(
+                       "Accept",
+                       s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
+                               s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+                               s.accepts[ "*" ]
+               );
+
+               // Check for headers option
+               for ( i in s.headers ) {
+                       jqXHR.setRequestHeader( i, s.headers[ i ] );
+               }
+
+               // Allow custom headers/mimetypes and early abort
+               if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
+                       // Abort if not done already and return
+                       return jqXHR.abort();
+               }
+
+               // aborting is no longer a cancellation
+               strAbort = "abort";
+
+               // Install callbacks on deferreds
+               for ( i in { success: 1, error: 1, complete: 1 } ) {
+                       jqXHR[ i ]( s[ i ] );
+               }
+
+               // Get transport
+               transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+               // If no transport, we auto-abort
+               if ( !transport ) {
+                       done( -1, "No Transport" );
+               } else {
+                       jqXHR.readyState = 1;
+
+                       // Send global event
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+                       }
+                       // Timeout
+                       if ( s.async && s.timeout > 0 ) {
+                               timeoutTimer = setTimeout(function() {
+                                       jqXHR.abort("timeout");
+                               }, s.timeout );
+                       }
+
+                       try {
+                               state = 1;
+                               transport.send( requestHeaders, done );
+                       } catch ( e ) {
+                               // Propagate exception as error if not done
+                               if ( state < 2 ) {
+                                       done( -1, e );
+                               // Simply rethrow otherwise
+                               } else {
+                                       throw e;
+                               }
+                       }
+               }
+
+               // Callback for when everything is done
+               function done( status, nativeStatusText, responses, headers ) {
+                       var isSuccess, success, error, response, modified,
+                               statusText = nativeStatusText;
+
+                       // Called once
+                       if ( state === 2 ) {
+                               return;
+                       }
+
+                       // State is "done" now
+                       state = 2;
+
+                       // Clear timeout if it exists
+                       if ( timeoutTimer ) {
+                               clearTimeout( timeoutTimer );
+                       }
+
+                       // Dereference transport for early garbage collection
+                       // (no matter how long the jqXHR object will be used)
+                       transport = undefined;
+
+                       // Cache response headers
+                       responseHeadersString = headers || "";
+
+                       // Set readyState
+                       jqXHR.readyState = status > 0 ? 4 : 0;
+
+                       // Determine if successful
+                       isSuccess = status >= 200 && status < 300 || status === 304;
+
+                       // Get response data
+                       if ( responses ) {
+                               response = ajaxHandleResponses( s, jqXHR, responses );
+                       }
+
+                       // Convert no matter what (that way responseXXX fields are always set)
+                       response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+                       // If successful, handle type chaining
+                       if ( isSuccess ) {
+
+                               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+                               if ( s.ifModified ) {
+                                       modified = jqXHR.getResponseHeader("Last-Modified");
+                                       if ( modified ) {
+                                               jQuery.lastModified[ cacheURL ] = modified;
+                                       }
+                                       modified = jqXHR.getResponseHeader("etag");
+                                       if ( modified ) {
+                                               jQuery.etag[ cacheURL ] = modified;
+                                       }
+                               }
+
+                               // if no content
+                               if ( status === 204 || s.type === "HEAD" ) {
+                                       statusText = "nocontent";
+
+                               // if not modified
+                               } else if ( status === 304 ) {
+                                       statusText = "notmodified";
+
+                               // If we have data, let's convert it
+                               } else {
+                                       statusText = response.state;
+                                       success = response.data;
+                                       error = response.error;
+                                       isSuccess = !error;
+                               }
+                       } else {
+                               // We extract error from statusText
+                               // then normalize statusText and status for non-aborts
+                               error = statusText;
+                               if ( status || !statusText ) {
+                                       statusText = "error";
+                                       if ( status < 0 ) {
+                                               status = 0;
+                                       }
+                               }
+                       }
+
+                       // Set data for the fake xhr object
+                       jqXHR.status = status;
+                       jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+                       // Success/Error
+                       if ( isSuccess ) {
+                               deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+                       } else {
+                               deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+                       }
+
+                       // Status-dependent callbacks
+                       jqXHR.statusCode( statusCode );
+                       statusCode = undefined;
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+                                       [ jqXHR, s, isSuccess ? success : error ] );
+                       }
+
+                       // Complete
+                       completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+                               // Handle the global AJAX counter
+                               if ( !( --jQuery.active ) ) {
+                                       jQuery.event.trigger("ajaxStop");
+                               }
+                       }
+               }
+
+               return jqXHR;
+       },
+
+       getJSON: function( url, data, callback ) {
+               return jQuery.get( url, data, callback, "json" );
+       },
+
+       getScript: function( url, callback ) {
+               return jQuery.get( url, undefined, callback, "script" );
+       }
+});
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+       jQuery[ method ] = function( url, data, callback, type ) {
+               // shift arguments if data argument was omitted
+               if ( jQuery.isFunction( data ) ) {
+                       type = type || callback;
+                       callback = data;
+                       data = undefined;
+               }
+
+               return jQuery.ajax({
+                       url: url,
+                       type: method,
+                       dataType: type,
+                       data: data,
+                       success: callback
+               });
+       };
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
+       jQuery.fn[ type ] = function( fn ) {
+               return this.on( type, fn );
+       };
+});
+
+
+jQuery._evalUrl = function( url ) {
+       return jQuery.ajax({
+               url: url,
+               type: "GET",
+               dataType: "script",
+               async: false,
+               global: false,
+               "throws": true
+       });
+};
+
+
+jQuery.fn.extend({
+       wrapAll: function( html ) {
+               var wrap;
+
+               if ( jQuery.isFunction( html ) ) {
+                       return this.each(function( i ) {
+                               jQuery( this ).wrapAll( html.call(this, i) );
+                       });
+               }
+
+               if ( this[ 0 ] ) {
+
+                       // The elements to wrap the target around
+                       wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
+
+                       if ( this[ 0 ].parentNode ) {
+                               wrap.insertBefore( this[ 0 ] );
+                       }
+
+                       wrap.map(function() {
+                               var elem = this;
+
+                               while ( elem.firstElementChild ) {
+                                       elem = elem.firstElementChild;
+                               }
+
+                               return elem;
+                       }).append( this );
+               }
+
+               return this;
+       },
+
+       wrapInner: function( html ) {
+               if ( jQuery.isFunction( html ) ) {
+                       return this.each(function( i ) {
+                               jQuery( this ).wrapInner( html.call(this, i) );
+                       });
+               }
+
+               return this.each(function() {
+                       var self = jQuery( this ),
+                               contents = self.contents();
+
+                       if ( contents.length ) {
+                               contents.wrapAll( html );
+
+                       } else {
+                               self.append( html );
+                       }
+               });
+       },
+
+       wrap: function( html ) {
+               var isFunction = jQuery.isFunction( html );
+
+               return this.each(function( i ) {
+                       jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
+               });
+       },
+
+       unwrap: function() {
+               return this.parent().each(function() {
+                       if ( !jQuery.nodeName( this, "body" ) ) {
+                               jQuery( this ).replaceWith( this.childNodes );
+                       }
+               }).end();
+       }
+});
+
+
+jQuery.expr.filters.hidden = function( elem ) {
+       // Support: Opera <= 12.12
+       // Opera reports offsetWidths and offsetHeights less than zero on some elements
+       return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
+};
+jQuery.expr.filters.visible = function( elem ) {
+       return !jQuery.expr.filters.hidden( elem );
+};
+
+
+
+
+var r20 = /%20/g,
+       rbracket = /\[\]$/,
+       rCRLF = /\r?\n/g,
+       rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+       rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+function buildParams( prefix, obj, traditional, add ) {
+       var name;
+
+       if ( jQuery.isArray( obj ) ) {
+               // Serialize array item.
+               jQuery.each( obj, function( i, v ) {
+                       if ( traditional || rbracket.test( prefix ) ) {
+                               // Treat each array item as a scalar.
+                               add( prefix, v );
+
+                       } else {
+                               // Item is non-scalar (array or object), encode its numeric index.
+                               buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
+                       }
+               });
+
+       } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+               // Serialize object item.
+               for ( name in obj ) {
+                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+               }
+
+       } else {
+               // Serialize scalar item.
+               add( prefix, obj );
+       }
+}
+
+// Serialize an array of form elements or a set of
+// key/values into a query string
+jQuery.param = function( a, traditional ) {
+       var prefix,
+               s = [],
+               add = function( key, value ) {
+                       // If value is a function, invoke it and return its value
+                       value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
+                       s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
+               };
+
+       // Set traditional to true for jQuery <= 1.3.2 behavior.
+       if ( traditional === undefined ) {
+               traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
+       }
+
+       // If an array was passed in, assume that it is an array of form elements.
+       if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+               // Serialize the form elements
+               jQuery.each( a, function() {
+                       add( this.name, this.value );
+               });
+
+       } else {
+               // If traditional, encode the "old" way (the way 1.3.2 or older
+               // did it), otherwise encode params recursively.
+               for ( prefix in a ) {
+                       buildParams( prefix, a[ prefix ], traditional, add );
+               }
+       }
+
+       // Return the resulting serialization
+       return s.join( "&" ).replace( r20, "+" );
+};
+
+jQuery.fn.extend({
+       serialize: function() {
+               return jQuery.param( this.serializeArray() );
+       },
+       serializeArray: function() {
+               return this.map(function() {
+                       // Can add propHook for "elements" to filter or add form elements
+                       var elements = jQuery.prop( this, "elements" );
+                       return elements ? jQuery.makeArray( elements ) : this;
+               })
+               .filter(function() {
+                       var type = this.type;
+
+                       // Use .is( ":disabled" ) so that fieldset[disabled] works
+                       return this.name && !jQuery( this ).is( ":disabled" ) &&
+                               rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+                               ( this.checked || !rcheckableType.test( type ) );
+               })
+               .map(function( i, elem ) {
+                       var val = jQuery( this ).val();
+
+                       return val == null ?
+                               null :
+                               jQuery.isArray( val ) ?
+                                       jQuery.map( val, function( val ) {
+                                               return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+                                       }) :
+                                       { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+               }).get();
+       }
+});
+
+
+jQuery.ajaxSettings.xhr = function() {
+       try {
+               return new XMLHttpRequest();
+       } catch( e ) {}
+};
+
+var xhrId = 0,
+       xhrCallbacks = {},
+       xhrSuccessStatus = {
+               // file protocol always yields status code 0, assume 200
+               0: 200,
+               // Support: IE9
+               // #1450: sometimes IE returns 1223 when it should be 204
+               1223: 204
+       },
+       xhrSupported = jQuery.ajaxSettings.xhr();
+
+// Support: IE9
+// Open requests must be manually aborted on unload (#5280)
+if ( window.ActiveXObject ) {
+       jQuery( window ).on( "unload", function() {
+               for ( var key in xhrCallbacks ) {
+                       xhrCallbacks[ key ]();
+               }
+       });
+}
+
+support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+support.ajax = xhrSupported = !!xhrSupported;
+
+jQuery.ajaxTransport(function( options ) {
+       var callback;
+
+       // Cross domain only allowed if supported through XMLHttpRequest
+       if ( support.cors || xhrSupported && !options.crossDomain ) {
+               return {
+                       send: function( headers, complete ) {
+                               var i,
+                                       xhr = options.xhr(),
+                                       id = ++xhrId;
+
+                               xhr.open( options.type, options.url, options.async, options.username, options.password );
+
+                               // Apply custom fields if provided
+                               if ( options.xhrFields ) {
+                                       for ( i in options.xhrFields ) {
+                                               xhr[ i ] = options.xhrFields[ i ];
+                                       }
+                               }
+
+                               // Override mime type if needed
+                               if ( options.mimeType && xhr.overrideMimeType ) {
+                                       xhr.overrideMimeType( options.mimeType );
+                               }
+
+                               // X-Requested-With header
+                               // For cross-domain requests, seeing as conditions for a preflight are
+                               // akin to a jigsaw puzzle, we simply never set it to be sure.
+                               // (it can always be set on a per-request basis or even using ajaxSetup)
+                               // For same-domain requests, won't change header if already provided.
+                               if ( !options.crossDomain && !headers["X-Requested-With"] ) {
+                                       headers["X-Requested-With"] = "XMLHttpRequest";
+                               }
+
+                               // Set headers
+                               for ( i in headers ) {
+                                       xhr.setRequestHeader( i, headers[ i ] );
+                               }
+
+                               // Callback
+                               callback = function( type ) {
+                                       return function() {
+                                               if ( callback ) {
+                                                       delete xhrCallbacks[ id ];
+                                                       callback = xhr.onload = xhr.onerror = null;
+
+                                                       if ( type === "abort" ) {
+                                                               xhr.abort();
+                                                       } else if ( type === "error" ) {
+                                                               complete(
+                                                                       // file: protocol always yields status 0; see #8605, #14207
+                                                                       xhr.status,
+                                                                       xhr.statusText
+                                                               );
+                                                       } else {
+                                                               complete(
+                                                                       xhrSuccessStatus[ xhr.status ] || xhr.status,
+                                                                       xhr.statusText,
+                                                                       // Support: IE9
+                                                                       // Accessing binary-data responseText throws an exception
+                                                                       // (#11426)
+                                                                       typeof xhr.responseText === "string" ? {
+                                                                               text: xhr.responseText
+                                                                       } : undefined,
+                                                                       xhr.getAllResponseHeaders()
+                                                               );
+                                                       }
+                                               }
+                                       };
+                               };
+
+                               // Listen to events
+                               xhr.onload = callback();
+                               xhr.onerror = callback("error");
+
+                               // Create the abort callback
+                               callback = xhrCallbacks[ id ] = callback("abort");
+
+                               try {
+                                       // Do send the request (this may raise an exception)
+                                       xhr.send( options.hasContent && options.data || null );
+                               } catch ( e ) {
+                                       // #14683: Only rethrow if this hasn't been notified as an error yet
+                                       if ( callback ) {
+                                               throw e;
+                                       }
+                               }
+                       },
+
+                       abort: function() {
+                               if ( callback ) {
+                                       callback();
+                               }
+                       }
+               };
+       }
+});
+
+
+
+
+// Install script dataType
+jQuery.ajaxSetup({
+       accepts: {
+               script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+       },
+       contents: {
+               script: /(?:java|ecma)script/
+       },
+       converters: {
+               "text script": function( text ) {
+                       jQuery.globalEval( text );
+                       return text;
+               }
+       }
+});
+
+// Handle cache's special case and crossDomain
+jQuery.ajaxPrefilter( "script", function( s ) {
+       if ( s.cache === undefined ) {
+               s.cache = false;
+       }
+       if ( s.crossDomain ) {
+               s.type = "GET";
+       }
+});
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function( s ) {
+       // This transport only deals with cross domain requests
+       if ( s.crossDomain ) {
+               var script, callback;
+               return {
+                       send: function( _, complete ) {
+                               script = jQuery("<script>").prop({
+                                       async: true,
+                                       charset: s.scriptCharset,
+                                       src: s.url
+                               }).on(
+                                       "load error",
+                                       callback = function( evt ) {
+                                               script.remove();
+                                               callback = null;
+                                               if ( evt ) {
+                                                       complete( evt.type === "error" ? 404 : 200, evt.type );
+                                               }
+                                       }
+                               );
+                               document.head.appendChild( script[ 0 ] );
+                       },
+                       abort: function() {
+                               if ( callback ) {
+                                       callback();
+                               }
+                       }
+               };
+       }
+});
+
+
+
+
+var oldCallbacks = [],
+       rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+       jsonp: "callback",
+       jsonpCallback: function() {
+               var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
+               this[ callback ] = true;
+               return callback;
+       }
+});
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+       var callbackName, overwritten, responseContainer,
+               jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+                       "url" :
+                       typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
+               );
+
+       // Handle iff the expected data type is "jsonp" or we have a parameter to set
+       if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+               // Get callback name, remembering preexisting value associated with it
+               callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+                       s.jsonpCallback() :
+                       s.jsonpCallback;
+
+               // Insert callback into url or form data
+               if ( jsonProp ) {
+                       s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+               } else if ( s.jsonp !== false ) {
+                       s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+               }
+
+               // Use data converter to retrieve json after script execution
+               s.converters["script json"] = function() {
+                       if ( !responseContainer ) {
+                               jQuery.error( callbackName + " was not called" );
+                       }
+                       return responseContainer[ 0 ];
+               };
+
+               // force json dataType
+               s.dataTypes[ 0 ] = "json";
+
+               // Install callback
+               overwritten = window[ callbackName ];
+               window[ callbackName ] = function() {
+                       responseContainer = arguments;
+               };
+
+               // Clean-up function (fires after converters)
+               jqXHR.always(function() {
+                       // Restore preexisting value
+                       window[ callbackName ] = overwritten;
+
+                       // Save back as free
+                       if ( s[ callbackName ] ) {
+                               // make sure that re-using the options doesn't screw things around
+                               s.jsonpCallback = originalSettings.jsonpCallback;
+
+                               // save the callback name for future use
+                               oldCallbacks.push( callbackName );
+                       }
+
+                       // Call if it was a function and we have a response
+                       if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+                               overwritten( responseContainer[ 0 ] );
+                       }
+
+                       responseContainer = overwritten = undefined;
+               });
+
+               // Delegate to script
+               return "script";
+       }
+});
+
+
+
+
+// data: string of html
+// context (optional): If specified, the fragment will be created in this context, defaults to document
+// keepScripts (optional): If true, will include scripts passed in the html string
+jQuery.parseHTML = function( data, context, keepScripts ) {
+       if ( !data || typeof data !== "string" ) {
+               return null;
+       }
+       if ( typeof context === "boolean" ) {
+               keepScripts = context;
+               context = false;
+       }
+       context = context || document;
+
+       var parsed = rsingleTag.exec( data ),
+               scripts = !keepScripts && [];
+
+       // Single tag
+       if ( parsed ) {
+               return [ context.createElement( parsed[1] ) ];
+       }
+
+       parsed = jQuery.buildFragment( [ data ], context, scripts );
+
+       if ( scripts && scripts.length ) {
+               jQuery( scripts ).remove();
+       }
+
+       return jQuery.merge( [], parsed.childNodes );
+};
+
+
+// Keep a copy of the old load method
+var _load = jQuery.fn.load;
+
+/**
+ * Load a url into a page
+ */
+jQuery.fn.load = function( url, params, callback ) {
+       if ( typeof url !== "string" && _load ) {
+               return _load.apply( this, arguments );
+       }
+
+       var selector, type, response,
+               self = this,
+               off = url.indexOf(" ");
+
+       if ( off >= 0 ) {
+               selector = jQuery.trim( url.slice( off ) );
+               url = url.slice( 0, off );
+       }
+
+       // If it's a function
+       if ( jQuery.isFunction( params ) ) {
+
+               // We assume that it's the callback
+               callback = params;
+               params = undefined;
+
+       // Otherwise, build a param string
+       } else if ( params && typeof params === "object" ) {
+               type = "POST";
+       }
+
+       // If we have elements to modify, make the request
+       if ( self.length > 0 ) {
+               jQuery.ajax({
+                       url: url,
+
+                       // if "type" variable is undefined, then "GET" method will be used
+                       type: type,
+                       dataType: "html",
+                       data: params
+               }).done(function( responseText ) {
+
+                       // Save response for use in complete callback
+                       response = arguments;
+
+                       self.html( selector ?
+
+                               // If a selector was specified, locate the right elements in a dummy div
+                               // Exclude scripts to avoid IE 'Permission Denied' errors
+                               jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+                               // Otherwise use the full result
+                               responseText );
+
+               }).complete( callback && function( jqXHR, status ) {
+                       self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+               });
+       }
+
+       return this;
+};
+
+
+
+
+jQuery.expr.filters.animated = function( elem ) {
+       return jQuery.grep(jQuery.timers, function( fn ) {
+               return elem === fn.elem;
+       }).length;
+};
+
+
+
+
+var docElem = window.document.documentElement;
+
+/**
+ * Gets a window from an element
+ */
+function getWindow( elem ) {
+       return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
+}
+
+jQuery.offset = {
+       setOffset: function( elem, options, i ) {
+               var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
+                       position = jQuery.css( elem, "position" ),
+                       curElem = jQuery( elem ),
+                       props = {};
+
+               // Set position first, in-case top/left are set even on static elem
+               if ( position === "static" ) {
+                       elem.style.position = "relative";
+               }
+
+               curOffset = curElem.offset();
+               curCSSTop = jQuery.css( elem, "top" );
+               curCSSLeft = jQuery.css( elem, "left" );
+               calculatePosition = ( position === "absolute" || position === "fixed" ) &&
+                       ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
+
+               // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
+               if ( calculatePosition ) {
+                       curPosition = curElem.position();
+                       curTop = curPosition.top;
+                       curLeft = curPosition.left;
+
+               } else {
+                       curTop = parseFloat( curCSSTop ) || 0;
+                       curLeft = parseFloat( curCSSLeft ) || 0;
+               }
+
+               if ( jQuery.isFunction( options ) ) {
+                       options = options.call( elem, i, curOffset );
+               }
+
+               if ( options.top != null ) {
+                       props.top = ( options.top - curOffset.top ) + curTop;
+               }
+               if ( options.left != null ) {
+                       props.left = ( options.left - curOffset.left ) + curLeft;
+               }
+
+               if ( "using" in options ) {
+                       options.using.call( elem, props );
+
+               } else {
+                       curElem.css( props );
+               }
+       }
+};
+
+jQuery.fn.extend({
+       offset: function( options ) {
+               if ( arguments.length ) {
+                       return options === undefined ?
+                               this :
+                               this.each(function( i ) {
+                                       jQuery.offset.setOffset( this, options, i );
+                               });
+               }
+
+               var docElem, win,
+                       elem = this[ 0 ],
+                       box = { top: 0, left: 0 },
+                       doc = elem && elem.ownerDocument;
+
+               if ( !doc ) {
+                       return;
+               }
+
+               docElem = doc.documentElement;
+
+               // Make sure it's not a disconnected DOM node
+               if ( !jQuery.contains( docElem, elem ) ) {
+                       return box;
+               }
+
+               // If we don't have gBCR, just use 0,0 rather than error
+               // BlackBerry 5, iOS 3 (original iPhone)
+               if ( typeof elem.getBoundingClientRect !== strundefined ) {
+                       box = elem.getBoundingClientRect();
+               }
+               win = getWindow( doc );
+               return {
+                       top: box.top + win.pageYOffset - docElem.clientTop,
+                       left: box.left + win.pageXOffset - docElem.clientLeft
+               };
+       },
+
+       position: function() {
+               if ( !this[ 0 ] ) {
+                       return;
+               }
+
+               var offsetParent, offset,
+                       elem = this[ 0 ],
+                       parentOffset = { top: 0, left: 0 };
+
+               // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
+               if ( jQuery.css( elem, "position" ) === "fixed" ) {
+                       // We assume that getBoundingClientRect is available when computed position is fixed
+                       offset = elem.getBoundingClientRect();
+
+               } else {
+                       // Get *real* offsetParent
+                       offsetParent = this.offsetParent();
+
+                       // Get correct offsets
+                       offset = this.offset();
+                       if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+                               parentOffset = offsetParent.offset();
+                       }
+
+                       // Add offsetParent borders
+                       parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+                       parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+               }
+
+               // Subtract parent offsets and element margins
+               return {
+                       top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+                       left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
+               };
+       },
+
+       offsetParent: function() {
+               return this.map(function() {
+                       var offsetParent = this.offsetParent || docElem;
+
+                       while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
+                               offsetParent = offsetParent.offsetParent;
+                       }
+
+                       return offsetParent || docElem;
+               });
+       }
+});
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
+       var top = "pageYOffset" === prop;
+
+       jQuery.fn[ method ] = function( val ) {
+               return access( this, function( elem, method, val ) {
+                       var win = getWindow( elem );
+
+                       if ( val === undefined ) {
+                               return win ? win[ prop ] : elem[ method ];
+                       }
+
+                       if ( win ) {
+                               win.scrollTo(
+                                       !top ? val : window.pageXOffset,
+                                       top ? val : window.pageYOffset
+                               );
+
+                       } else {
+                               elem[ method ] = val;
+                       }
+               }, method, val, arguments.length, null );
+       };
+});
+
+// Add the top/left cssHooks using jQuery.fn.position
+// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+// getComputedStyle returns percent when specified for top/left/bottom/right
+// rather than make the css module depend on the offset module, we just check for it here
+jQuery.each( [ "top", "left" ], function( i, prop ) {
+       jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
+               function( elem, computed ) {
+                       if ( computed ) {
+                               computed = curCSS( elem, prop );
+                               // if curCSS returns percentage, fallback to offset
+                               return rnumnonpx.test( computed ) ?
+                                       jQuery( elem ).position()[ prop ] + "px" :
+                                       computed;
+                       }
+               }
+       );
+});
+
+
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+       jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
+               // margin is only for outerHeight, outerWidth
+               jQuery.fn[ funcName ] = function( margin, value ) {
+                       var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+                               extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
+
+                       return access( this, function( elem, type, value ) {
+                               var doc;
+
+                               if ( jQuery.isWindow( elem ) ) {
+                                       // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
+                                       // isn't a whole lot we can do. See pull request at this URL for discussion:
+                                       // https://github.com/jquery/jquery/pull/764
+                                       return elem.document.documentElement[ "client" + name ];
+                               }
+
+                               // Get document width or height
+                               if ( elem.nodeType === 9 ) {
+                                       doc = elem.documentElement;
+
+                                       // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
+                                       // whichever is greatest
+                                       return Math.max(
+                                               elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+                                               elem.body[ "offset" + name ], doc[ "offset" + name ],
+                                               doc[ "client" + name ]
+                                       );
+                               }
+
+                               return value === undefined ?
+                                       // Get width or height on the element, requesting but not forcing parseFloat
+                                       jQuery.css( elem, type, extra ) :
+
+                                       // Set width or height on the element
+                                       jQuery.style( elem, type, value, extra );
+                       }, type, chainable ? margin : undefined, chainable, null );
+               };
+       });
+});
+
+
+// The number of elements contained in the matched element set
+jQuery.fn.size = function() {
+       return this.length;
+};
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+
+
+
+// Register as a named AMD module, since jQuery can be concatenated with other
+// files that may use define, but not via a proper concatenation script that
+// understands anonymous AMD modules. A named AMD is safest and most robust
+// way to register. Lowercase jquery is used because AMD module names are
+// derived from file names, and jQuery is normally delivered in a lowercase
+// file name. Do this after creating the global so that if an AMD module wants
+// to call noConflict to hide this version of jQuery, it will work.
+
+// Note that for maximum portability, libraries that are not jQuery should
+// declare themselves as anonymous modules, and avoid setting a global if an
+// AMD loader is present. jQuery is a special case. For more information, see
+// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+if ( typeof define === "function" && define.amd ) {
+       define( "jquery", [], function() {
+               return jQuery;
+       });
+}
+
+
+
+
+var
+       // Map over jQuery in case of overwrite
+       _jQuery = window.jQuery,
+
+       // Map over the $ in case of overwrite
+       _$ = window.$;
+
+jQuery.noConflict = function( deep ) {
+       if ( window.$ === jQuery ) {
+               window.$ = _$;
+       }
+
+       if ( deep && window.jQuery === jQuery ) {
+               window.jQuery = _jQuery;
+       }
+
+       return jQuery;
+};
+
+// Expose jQuery and $ identifiers, even in
+// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+// and CommonJS for browser emulators (#13566)
+if ( typeof noGlobal === strundefined ) {
+       window.jQuery = window.$ = jQuery;
+}
+
+
+
+
+return jQuery;
+
+}));
diff --git a/d2d_app/client/lib/tau/mobile/js/jquery.min.js b/d2d_app/client/lib/tau/mobile/js/jquery.min.js
new file mode 100644 (file)
index 0000000..e5ace11
--- /dev/null
@@ -0,0 +1,4 @@
+/*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.1",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(f=_.exec(a))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="<div class='a'></div><div class='a i'></div>",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML="<select msallowclip=''><option selected=''></option></select>",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fb.selectors={cacheLength:50,createPseudo:hb,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=lb(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=mb(b);function pb(){}pb.prototype=d.filters=d.pseudos,d.setFilters=new pb,g=fb.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fb.error(a):z(a,i).slice(0)};function qb(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function rb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function sb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+Math.random()}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)
+},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ab=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ib={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qb[0].contentDocument,b.write(),b.close(),c=sb(a,b),qb.detach()),rb[a]=c),c}var ub=/^margin/,vb=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)};function xb(a,b,c){var d,e,f,g,h=a.style;return c=c||wb(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),vb.test(g)&&ub.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function yb(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var zb=/^(none|table(?!-c[ea]).+)/,Ab=new RegExp("^("+Q+")(.*)$","i"),Bb=new RegExp("^([+-])=("+Q+")","i"),Cb={position:"absolute",visibility:"hidden",display:"block"},Db={letterSpacing:"0",fontWeight:"400"},Eb=["Webkit","O","Moz","ms"];function Fb(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Eb.length;while(e--)if(b=Eb[e]+c,b in a)return b;return d}function Gb(a,b,c){var d=Ab.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Hb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ib(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wb(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xb(a,b,f),(0>e||null==e)&&(e=a.style[b]),vb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Hb(a,b,c||(g?"border":"content"),d,f)+"px"}function Jb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",tb(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Bb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xb(a,b,d)),"normal"===e&&b in Db&&(e=Db[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?zb.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Cb,function(){return Ib(a,b,d)}):Ib(a,b,d):void 0},set:function(a,c,d){var e=d&&wb(a);return Gb(a,c,d?Hb(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=yb(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xb,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ub.test(a)||(n.cssHooks[a+b].set=Gb)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wb(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Jb(this,!0)},hide:function(){return Jb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Kb(a,b,c,d,e){return new Kb.prototype.init(a,b,c,d,e)}n.Tween=Kb,Kb.prototype={constructor:Kb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Kb.propHooks[this.prop];return a&&a.get?a.get(this):Kb.propHooks._default.get(this)},run:function(a){var b,c=Kb.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Kb.propHooks._default.set(this),this}},Kb.prototype.init.prototype=Kb.prototype,Kb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Kb.propHooks.scrollTop=Kb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Kb.prototype.init,n.fx.step={};var Lb,Mb,Nb=/^(?:toggle|show|hide)$/,Ob=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pb=/queueHooks$/,Qb=[Vb],Rb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Ob.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Ob.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sb(){return setTimeout(function(){Lb=void 0}),Lb=n.now()}function Tb(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ub(a,b,c){for(var d,e=(Rb[b]||[]).concat(Rb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Vb(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||tb(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Nb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?tb(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ub(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xb(a,b,c){var d,e,f=0,g=Qb.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Lb||Sb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:Lb||Sb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wb(k,j.opts.specialEasing);g>f;f++)if(d=Qb[f].call(j,a,k,j.opts))return d;return n.map(k,Ub,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xb,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Rb[c]=Rb[c]||[],Rb[c].unshift(b)},prefilter:function(a,b){b?Qb.unshift(a):Qb.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xb(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Tb(b,!0),a,d,e)}}),n.each({slideDown:Tb("show"),slideUp:Tb("hide"),slideToggle:Tb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Lb=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Lb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Mb||(Mb=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Mb),Mb=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Yb,Zb,$b=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Zb:Yb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))
+},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Zb={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$b[b]||n.find.attr;$b[b]=function(a,b,d){var e,f;return d||(f=$b[b],$b[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$b[b]=f),e}});var _b=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_b.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ac=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ac," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ac," ").indexOf(b)>=0)return!0;return!1}});var bc=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cc=n.now(),dc=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var ec,fc,gc=/#.*$/,hc=/([?&])_=[^&]*/,ic=/^(.*?):[ \t]*([^\r\n]*)$/gm,jc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,kc=/^(?:GET|HEAD)$/,lc=/^\/\//,mc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,nc={},oc={},pc="*/".concat("*");try{fc=location.href}catch(qc){fc=l.createElement("a"),fc.href="",fc=fc.href}ec=mc.exec(fc.toLowerCase())||[];function rc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function sc(a,b,c,d){var e={},f=a===oc;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function tc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function uc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function vc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:fc,type:"GET",isLocal:jc.test(ec[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":pc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?tc(tc(a,n.ajaxSettings),b):tc(n.ajaxSettings,a)},ajaxPrefilter:rc(nc),ajaxTransport:rc(oc),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=ic.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||fc)+"").replace(gc,"").replace(lc,ec[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=mc.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===ec[1]&&h[2]===ec[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(ec[3]||("http:"===ec[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),sc(nc,k,b,v),2===t)return v;i=k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!kc.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(dc.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=hc.test(d)?d.replace(hc,"$1_="+cc++):d+(dc.test(d)?"&":"?")+"_="+cc++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+pc+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=sc(oc,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=uc(k,v,f)),u=vc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var wc=/%20/g,xc=/\[\]$/,yc=/\r?\n/g,zc=/^(?:submit|button|image|reset|file)$/i,Ac=/^(?:input|select|textarea|keygen)/i;function Bc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||xc.test(a)?d(a,e):Bc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Bc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Bc(c,a[c],b,e);return d.join("&").replace(wc,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Ac.test(this.nodeName)&&!zc.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(yc,"\r\n")}}):{name:b.name,value:c.replace(yc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Cc=0,Dc={},Ec={0:200,1223:204},Fc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Dc)Dc[a]()}),k.cors=!!Fc&&"withCredentials"in Fc,k.ajax=Fc=!!Fc,n.ajaxTransport(function(a){var b;return k.cors||Fc&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Cc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Dc[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Ec[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Dc[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Gc=[],Hc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Gc.pop()||n.expando+"_"+cc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Hc.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Hc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Hc,"$1"+e):b.jsonp!==!1&&(b.url+=(dc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Gc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Ic=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Ic)return Ic.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Jc=a.document.documentElement;function Kc(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Kc(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Jc;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Jc})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Kc(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=yb(k.pixelPosition,function(a,c){return c?(c=xb(a,b),vb.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Lc=a.jQuery,Mc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Mc),b&&a.jQuery===n&&(a.jQuery=Lc),n},typeof b===U&&(a.jQuery=a.$=n),n});
diff --git a/d2d_app/client/lib/tau/mobile/js/tau.js b/d2d_app/client/lib/tau/mobile/js/tau.js
new file mode 100644 (file)
index 0000000..8252473
--- /dev/null
@@ -0,0 +1,61260 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+(function(window, document, undefined) {
+'use strict';
+var ns = window.tau = window.tau || {},
+nsConfig = window.tauConfig = window.tauConfig || {};
+nsConfig.rootNamespace = 'tau';
+nsConfig.fileName = 'tau';
+ns.version = '1.2.7';
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* global window, define */
+/* eslint-disable no-console */
+/**
+ * #Core namespace
+ * Object contains main framework methods.
+ * @class ns
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function (document, console) {
+       "use strict";
+                       var idNumberCounter = 0,
+                       currentDate = +new Date(),
+                       slice = [].slice,
+                       rootNamespace = "",
+                       fileName = "",
+                       infoForLog = function (args) {
+                               var dateNow = new Date();
+
+                               args.unshift("[" + rootNamespace + "][" + dateNow.toLocaleString() + "]");
+                       },
+                       ns = window.ns || window.tau || {},
+                       nsConfig = window.nsConfig || window.tauConfig || {},
+                       TAUException = function (message) {
+                               this.message = message;
+                       };
+
+               ns.info = ns.info || {
+                       profile: "custom"
+               };
+               ns.tauPerf = ns.tauPerf || {};
+
+               window.ns = ns;
+               window.nsConfig = nsConfig;
+
+               window.tau = ns;
+               window.tauConfig = nsConfig;
+
+               rootNamespace = nsConfig.rootNamespace;
+               fileName = nsConfig.fileName;
+
+               TAUException.prototype.toString = function () {
+                       return this.message;
+               };
+
+               /**
+                * Return unique id
+                * @method getUniqueId
+                * @static
+                * @return {string}
+                * @member ns
+                */
+               ns.getUniqueId = function () {
+                       return rootNamespace + "-" + ns.getNumberUniqueId() + "-" + currentDate;
+               };
+
+               /**
+                * Return unique id
+                * @method getNumberUniqueId
+                * @static
+                * @return {number}
+                * @member ns
+                */
+               ns.getNumberUniqueId = function () {
+                       return idNumberCounter++;
+               };
+
+               /**
+                * logs supplied messages/arguments
+                * @method log
+                * @static
+                * @member ns
+                */
+               ns.log = function () {
+                       var args = slice.call(arguments);
+
+                       infoForLog(args);
+                       if (console) {
+                               console.log.apply(console, args);
+                       }
+               };
+
+               /**
+                * logs supplied messages/arguments ad marks it as warning
+                * @method warn
+                * @static
+                * @member ns
+                */
+               ns.warn = function () {
+                       var args = slice.call(arguments);
+
+                       infoForLog(args);
+                       if (console) {
+                               console.warn.apply(console, args);
+                       }
+               };
+
+               /**
+                * logs supplied messages/arguments and marks it as error
+                * @method error
+                * @static
+                * @member ns
+                */
+               ns.error = function () {
+                       var args = slice.call(arguments);
+
+                       infoForLog(args);
+                       if (console) {
+                               console.error.apply(console, args);
+                       }
+               };
+
+               /**
+                * get from nsConfig
+                * @method getConfig
+                * @param {string} key
+                * @param {*} [defaultValue] value returned when config is not set
+                * @return {*}
+                * @static
+                * @member ns
+                */
+               ns.getConfig = function (key, defaultValue) {
+                       return nsConfig[key] === undefined ? defaultValue : nsConfig[key];
+               };
+
+               /**
+                * set in nsConfig
+                * @method setConfig
+                * @param {string} key
+                * @param {*} value
+                * @param {boolean} [asDefault=false] value should be treated as default (doesn't overwrites
+                * the config[key] if it already exists)
+                * @static
+                * @member ns
+                */
+               ns.setConfig = function (key, value, asDefault) {
+                       if (!asDefault || nsConfig[key] === undefined) {
+                               nsConfig[key] = value;
+                       }
+               };
+
+               /**
+                * Return path for framework script file.
+                * @method getFrameworkPath
+                * @return {?string}
+                * @member ns
+                */
+               ns.getFrameworkPath = function () {
+                       var scripts = document.getElementsByTagName("script"),
+                               countScripts = scripts.length,
+                               i,
+                               url,
+                               arrayUrl,
+                               count;
+
+                       for (i = 0; i < countScripts; i++) {
+                               url = scripts[i].src;
+                               arrayUrl = url.split("/");
+                               count = arrayUrl.length;
+                               if (arrayUrl[count - 1] === fileName + ".js" ||
+                                       arrayUrl[count - 1] === fileName + ".min.js") {
+                                       return arrayUrl.slice(0, count - 1).join("/");
+                               }
+                       }
+                       return null;
+               };
+
+               ns._TAUException = TAUException;
+
+               /**
+                * Method throws TAU exception with given message
+                * @param {string} message
+                * @method throws
+                * @member ns
+                */
+               ns.throws = function (message) {
+                       if (typeof message !== "string") {
+                               ns.throws("Wrong parameter type. Message must be a string!");
+                       }
+                       throw new ns._TAUException(message);
+               };
+
+               }(window.document, window.console));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, ns, define*/
+/*
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function () {
+       "use strict";
+       
+                       // Default configuration properties for mobile
+                       ns.setConfig("autoBuildOnPageChange", true, true);
+                       ns.setConfig("loader", false, true);
+                       ns.setConfig("pageContainerBody", true, true);
+                       ns.setConfig("popupTransition", "slideup", true);
+                       ns.setConfig("pageTransition", "none", true);
+                       ns.setConfig("enablePageScroll", false, true);
+                       }());
+
+/*global window, define, ns*/
+/*jslint bitwise: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function () {
+       "use strict";
+       
+                       // Default configuration properties
+                       ns.setConfig("rootDir", ns.getFrameworkPath(), true);
+                       ns.setConfig("version", "", true);
+                       ns.setConfig("allowCrossDomainPages", false, true);
+                       ns.setConfig("domCache", false, true);
+                       // .. other possible options
+                       ns.setConfig("autoBuildOnPageChange", true, true);
+                       ns.setConfig("autoInitializePage", true, true);
+                       ns.setConfig("dynamicBaseEnabled", true, true);
+                       ns.setConfig("pageTransition", "none", true);
+                       ns.setConfig("popupTransition", "none", true);
+                       ns.setConfig("popupFullSize", false, true);
+                       ns.setConfig("scrollEndEffectArea", "content", true);
+                       ns.setConfig("enablePopupScroll", false, true);
+                       // ns.setConfig('container', document.body); // for defining application container
+                       // same as above, but for wearable version
+                       ns.setConfig("pageContainer", document.body, true);
+                       ns.setConfig("findProfileFile", false, true);
+                       ns.setConfig("keyboardSupport", false);
+
+                       }());
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * #Defaults settings object
+ *
+ * This module is deprecated, please use tau.setConfig and tau.getConfig functions or tauConfig
+ * object.
+ *
+ * @author Hyunkook Cho <hk0713.cho@samsung.com>
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ * @author junhyeonLee <juneh.lee@samsung.com>
+ * @author heeju Joo <heeju.joo@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author hagun.kim <hagun.kim@samsung.com>
+ * @class ns.defaults
+ * @since 2.0
+ * @deprecated 3.0
+ */
+(function () {
+       "use strict";
+                               var defaults = {};
+
+                       /**
+                        * Helper function to define property on object defaults
+                        * @param {string} name Property name to define
+                        */
+                       function defineProperty(name) {
+                               Object.defineProperty(ns.defaults, name, {
+                                       get: function () {
+                                               ns.warn("tau.defaults are deprecated from Tizen 3.0, please use tau.getConfig.");
+                                               return ns.getConfig(name);
+                                       },
+                                       set: function (value) {
+                                               ns.warn("tau.defaults are deprecated from Tizen 3.0, please use tau.setConfig.");
+                                               return ns.setConfig(name, value);
+                                       }
+                               });
+                       }
+
+                       ns.defaults = defaults;
+
+                       /**
+                        * @property {boolean} autoInitializePage=true
+                        * @member ns.defaults
+                        * @static
+                        */
+                       defineProperty("autoInitializePage");
+                       /**
+                        * @property {boolean} dynamicBaseEnabled=true
+                        * @member ns.defaults
+                        * @static
+                        */
+                       defineProperty("dynamicBaseEnabled");
+                       /**
+                        * @property {string} pageTransition="none"
+                        * @member ns.defaults
+                        * @static
+                        */
+                       defineProperty("pageTransition");
+                       /**
+                        * @property {string} popupTransition="none"
+                        * @member ns.defaults
+                        * @static
+                        */
+                       defineProperty("popupTransition");
+                       /**
+                        * @property {boolean} popupFullSize=false
+                        * @member ns.defaults
+                        * @static
+                        */
+                       defineProperty("popupFullSize");
+                       /**
+                        * @property {boolean} enablePageScroll=false
+                        * @member ns.defaults
+                        * @static
+                        */
+                       defineProperty("enablePageScroll");
+                       /**
+                        * @property {boolean} goToTopButton=false
+                        * @member ns.defaults
+                        * @static
+                        */
+                       defineProperty("goToTopButton");
+                       /**
+                        * @property {string} scrollEndEffectArea="content
+                        * @member ns.defaults
+                        * @static
+                        */
+                       defineProperty("scrollEndEffectArea");
+                       /**
+                        * @property {boolean} enablePopupScroll=false
+                        * @member ns.defaults
+                        * @static
+                        */
+                       defineProperty("enablePopupScroll");
+
+                       }());
+
+/*global window, ns, define*/
+/*jslint bitwise: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Support
+ * Namespace with helpers function connected with browser properties
+ * @class ns.support
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function (window, document) {
+       "use strict";
+       
+                       /* $.mobile.media method: pass a CSS media type or query and get a bool return
+                        note: this feature relies on actual media query support for media queries, though types will
+                         work most anywhere
+                        examples:
+                        $.mobile.media('screen') // tests for screen media type
+                        $.mobile.media('screen and (min-width: 480px)') // tests for screen media type with window
+                         width > 480px
+                        $.mobile.media('\@media screen and (-webkit-min-device-pixel-ratio: 2)') // tests for webkit
+                         2x pixel ratio (iPhone 4)
+                        */
+                       // TODO: use window.matchMedia once at least one UA implements it
+                       var cacheMedia = {},
+                               testDiv = document.createElement("div"),
+                               fakeBody = document.createElement("body"),
+                               fakeBodyStyle = fakeBody.style,
+                               html = document.getElementsByTagName("html")[0],
+                               style,
+                               vendors = ["Webkit", "Moz", "O"],
+                               webos = window.palmGetResource, //only used to rule out scrollTop
+                               opera = window.opera,
+                               operamini = window.operamini && ({}).toString.call(window.operamini) === "[object OperaMini]",
+                               blackBerry,
+                               testDivStyle = testDiv.style,
+                               ieVersion;
+
+                       testDiv.id = "jquery-mediatest";
+                       fakeBody.appendChild(testDiv);
+
+                       /**
+                        * Method checks \@media "query" support
+                        * @method media
+                        * @param {string} query
+                        * @return {boolean}
+                        * @static
+                        * @member ns.support
+                        */
+                       function media(query) {
+                               var styleBlock = document.createElement("style"),
+                                       cssrule = "@media " + query + " { #jquery-mediatest { position:absolute; } }";
+
+                               if (query.cacheMedia === undefined) {
+                                       //must set type for IE!
+                                       styleBlock.type = "text/css";
+
+                                       if (styleBlock.styleSheet) {
+                                               styleBlock.styleSheet.cssText = cssrule;
+                                       } else {
+                                               styleBlock.appendChild(document.createTextNode(cssrule));
+                                       }
+
+                                       if (html.firstChild) {
+                                               html.insertBefore(fakeBody, html.firstChild);
+                                       } else {
+                                               html.appendChild(fakeBody);
+                                       }
+                                       html.insertBefore(styleBlock, fakeBody);
+                                       style = window.getComputedStyle(testDiv);
+                                       cacheMedia[query] = (style.position === "absolute");
+                                       styleBlock.parentNode.removeChild(styleBlock);
+                                       fakeBody.parentNode.removeChild(fakeBody);
+                               }
+                               return cacheMedia[query];
+                       }
+
+                       function validStyle(prop, value, checkVend) {
+                               var div = document.createElement("div"),
+                                       uc = function (txt) {
+                                               return txt.charAt(0).toUpperCase() + txt.substr(1);
+                                       },
+                                       vendPref = function (vend) {
+                                               return "-" + vend.charAt(0).toLowerCase() + vend.substr(1) + "-";
+                                       },
+                                       returnValue,
+                                       checkStyle = function (vend) {
+                                               var vendProp = vendPref(vend) + prop + ": " + value + ";",
+                                                       ucVend = uc(vend),
+                                                       propStyle = ucVend + uc(prop);
+
+                                               div.setAttribute("style", vendProp);
+
+                                               if (div.style[propStyle]) {
+                                                       returnValue = true;
+                                               }
+                                       },
+                                       checkVendors = checkVend ? [checkVend] : vendors,
+                                       checkVendorsLength = checkVendors.length,
+                                       i;
+
+                               for (i = 0; i < checkVendorsLength; i++) {
+                                       checkStyle(checkVendors[i]);
+                               }
+                               return !!returnValue;
+                       }
+
+                       /**
+                        *
+                        * @param {string} prop
+                        * @return {boolean}
+                        */
+                       function propExists(prop) {
+                               var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
+                                       props = (prop + " " + vendors.join(ucProp + " ") + ucProp).split(" "),
+                                       key;
+
+                               for (key = 0; key < props.length; key++) {
+                                       if (props.hasOwnProperty(key) && fakeBodyStyle[props[key]] !== undefined) {
+                                               return true;
+                                       }
+                               }
+                               return false;
+                       }
+
+                       function transform3dTest() {
+                               var prop = "transform-3d";
+
+                               return validStyle("perspective", "10px", "moz") || media("(-" + vendors.join("-" + prop + "),(-") + "-" + prop + "),(" + prop + ")");
+                       }
+
+                       blackBerry = window.blackberry && !propExists("-webkit-transform");
+
+                       function baseTagTest() {
+                               var fauxBase = location.protocol + "//" + location.host + location.pathname + "ui-dir/",
+                                       head = document.head,
+                                       base = head.querySelector("base"),
+                                       fauxEle = null,
+                                       hadBase = false,
+                                       href = "",
+                                       link,
+                                       rebase;
+
+                               if (base) {
+                                       href = base.getAttribute("href");
+                                       base.setAttribute("href", fauxBase);
+                                       hadBase = true;
+                               } else {
+                                       base = fauxEle = document.createElement("base");
+                                       base.setAttribute("href", fauxBase);
+                                       head.appendChild(base);
+                               }
+
+                               link = document.createElement("a");
+                               link.href = "testurl";
+                               if (fakeBody.firstChild) {
+                                       fakeBody.insertBefore(link, fakeBody.firstChild);
+                               } else {
+                                       fakeBody.appendChild(link);
+                               }
+                               rebase = link.href;
+                               base.href = href || location.pathname;
+
+                               if (fauxEle) {
+                                       head.removeChild(fauxEle);
+                               }
+
+                               // Restore previous base href if base had existed
+                               if (hadBase) {
+                                       base.setAttribute("href", href);
+                               }
+
+                               // Tell jQuery not to append <base> in build mode
+                               if (location.hash === "#build") {
+                                       return false;
+                               }
+
+                               return rebase.indexOf(fauxBase) === 0;
+                       }
+
+                       function cssPointerEventsTest() {
+                               var element = document.createElement("x"),
+                                       documentElement = document.documentElement,
+                                       getComputedStyle = window.getComputedStyle,
+                                       supports,
+                                       elementStyle = element.style;
+
+                               if (elementStyle.pointerEvents === undefined) {
+                                       return false;
+                               }
+
+                               elementStyle.pointerEvents = "x";
+                               documentElement.appendChild(element);
+                               supports = getComputedStyle && getComputedStyle(element, "").pointerEvents === "auto";
+                               documentElement.removeChild(element);
+                               return !!supports;
+                       }
+
+                       function boundingRect() {
+                               var div = document.createElement("div");
+
+                               return div.getBoundingClientRect !== undefined;
+                       }
+
+                       ieVersion = (function () {
+                               var v = 3,
+                                       div = document.createElement("div"),
+                                       a = div.all || [];
+
+                               do {
+                                       div.innerHTML = "<!--[if gt IE " + (++v) + "]><br><![endif]-->";
+                               } while (a[0]);
+                               return v;
+                       })();
+
+                       ns.support = {
+                               media: media,
+                               /**
+                                * Informs browser support transition
+                                * @property {boolean} cssTransitions
+                                * @member ns.support
+                                * @static
+                                */
+                               cssTransitions: (window.WebKitTransitionEvent !== undefined || validStyle("transition", "height 100ms linear")) && !opera,
+                               /**
+                                * Informs browser support history.pushStare method
+                                * @property {boolean} pushState
+                                * @member ns.support
+                                * @static
+                                */
+                               pushState: window.history.pushState && window.history.replaceState && true,
+                               /**
+                                * Informs browser support media query "only all"
+                                * @property {boolean} mediaquery
+                                * @member ns.support
+                                * @static
+                                */
+                               mediaquery: media("only all"),
+                               /**
+                                * Informs browser support content property on element
+                                * @property {boolean} cssPseudoElement
+                                * @member ns.support
+                                * @static
+                                */
+                               cssPseudoElement: !!propExists("content"),
+                               /**
+                                * Informs browser support overflowScrolling property on element
+                                * @property {boolean} touchOverflow
+                                * @member ns.support
+                                * @static
+                                */
+                               touchOverflow: !!propExists("overflowScrolling"),
+                               /**
+                                * Informs browser support CSS 3D transitions
+                                * @property {boolean} cssTransform3d
+                                * @member ns.support
+                                * @static
+                                */
+                               cssTransform3d: transform3dTest(),
+                               /**
+                                * Informs browser support boxShadow property on element
+                                * @property {boolean} boxShadow
+                                * @member ns.support
+                                * @static
+                                */
+                               boxShadow: !!propExists("boxShadow") && !blackBerry,
+                               /**
+                                * Informs browser support scrollTop property
+                                * @property {boolean} scrollTop
+                                * @member ns.support
+                                * @static
+                                */
+                               scrollTop: ((window.pageXOffset || document.documentElement.scrollTop || fakeBody.scrollTop) !== undefined && !webos && !operamini) ? true : false,
+                               /**
+                                * Informs browser support dynamic change base tag
+                                * @property {boolean} dynamicBaseTag
+                                * @member ns.support
+                                * @static
+                                */
+                               dynamicBaseTag: baseTagTest(),
+                               /**
+                                * Informs browser support CSS pointer events
+                                * @property {boolean} cssPointerEvents
+                                * @member ns.support
+                                * @static
+                                */
+                               cssPointerEvents: cssPointerEventsTest(),
+                               /**
+                                * Prefix for animations
+                                * @property ("-webkit-"|"-moz-"|"-o-"|""} cssAnimationPrefix
+                                * @member ns.support
+                                * @static
+                                */
+                               cssAnimationPrefix: testDivStyle.hasOwnProperty("webkitAnimation") ? "-webkit-" :
+                                       testDivStyle.hasOwnProperty("mozAnimation") ? "-moz-" :
+                                               testDivStyle.hasOwnProperty("oAnimation") ? "-o-" : "",
+                               /**
+                                * Informs browser support getBoundingClientRect
+                                * @property {boolean} boundingRect
+                                * @member ns.support
+                                * @static
+                                */
+                               boundingRect: boundingRect(),
+                               /**
+                                * Object with browser information
+                                * @property (Object} browser
+                                * @property {boolean} browser.ie detects Internet Explorer
+                                * @member ns.support
+                                * @static
+                                */
+                               browser: {
+                                       ie: ieVersion > 4
+                               },
+                               /**
+                                * Informs that browser pass all tests for run framework
+                                * @method gradeA
+                                * @member ns.support
+                                * @static
+                                * @return {boolean}
+                                */
+                               gradeA: function () {
+                                       return ((this.mediaquery || (this.browser.ie && ieVersion >= 7)) &&
+                                       (this.boundingRect || ((window.jQuery && window.jQuery.fn && window.jQuery.fn.jquery.match(/1\.[0-7+]\.[0-9+]?/)) !== null)));
+                               },
+                               /**
+                                * Informs browser support touch events
+                                * @property {boolean} touch
+                                * @member ns.support
+                                * @static
+                                */
+                               touch: document.ontouchend !== undefined,
+                               /**
+                                * Informs browser support orientation property
+                                * @property {boolean} orientation
+                                * @member ns.support
+                                * @static
+                                */
+                               orientation: window.orientation !== undefined && window.onorientationchange !== undefined
+                       };
+                       testDiv = null;
+                       fakeBody = null;
+                       }(window, window.document));
+
+/*global ns, define */
+/*jslint nomen: true, browser: true, plusplus: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Utilities
+ *
+ * The Tizen Advanced UI (TAU) framework provides utilities for easy-developing
+ * and fully replaceable with jQuery method. When user using these DOM and
+ * selector methods, it provide more light logic and it proves performance
+ * of web app. The following table displays the utilities provided by the
+ * TAU framework.
+ *
+ * @class ns.util
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var currentFrame = null,
+                               util = ns.util || {},
+                               // frames callbacks which should be run in next request animation frame
+                               waitingFrames = [],
+                               slice = [].slice,
+                               // inform that loop was added to request animation frame callback
+                               loopWork = false;
+
+                       /**
+                        * Function which is use as workaround when any type of request animation frame not exists
+                        * @param {Function} callback
+                        * @method _requestAnimationFrameOnSetTimeout
+                        * @static
+                        * @member ns.util
+                        * @protected
+                        */
+                       util._requestAnimationFrameOnSetTimeout = function (callback) {
+                               if (typeof callback !== "function") {
+                                       ns.throws("Parameter is not a function!");
+                               }
+                               currentFrame = window.setTimeout(callback.bind(callback, +new Date()), 1000 / 60);
+                       };
+
+                       /**
+                        * Function which support every request animation frame.
+                        * @method _loop
+                        * @protected
+                        * @static
+                        * @member ns.util
+                        */
+                       util._loop = function () {
+                               var loopWaitingFrames = slice.call(waitingFrames),
+                                       currentFrameFunction = loopWaitingFrames.shift(),
+                                       loopTime = performance.now();
+
+                               waitingFrames = [];
+
+                               while (currentFrameFunction) {
+                                       currentFrameFunction(loopTime);
+                                       if (performance.now() - loopTime < 15) {
+                                               currentFrameFunction = loopWaitingFrames.shift();
+                                       } else {
+                                               currentFrameFunction = null;
+                                       }
+                               }
+                               if (loopWaitingFrames.length || waitingFrames.length) {
+                                       waitingFrames.unshift.apply(waitingFrames, loopWaitingFrames);
+                                       util.windowRequestAnimationFrame(util._loop);
+                               } else {
+                                       loopWork = false;
+                               }
+                       };
+
+                       /**
+                        * Find browser prefixed request animation frame function.
+                        * @method _getRequestAnimationFrame
+                        * @protected
+                        * @static
+                        * @member ns.util
+                        */
+                       util._getRequestAnimationFrame = function () {
+                               return (window.requestAnimationFrame ||
+                                       window.webkitRequestAnimationFrame ||
+                                       window.mozRequestAnimationFrame ||
+                                       window.oRequestAnimationFrame ||
+                                       window.msRequestAnimationFrame ||
+                                       util._requestAnimationFrameOnSetTimeout).bind(window);
+                       };
+
+                       /**
+                        * Original requestAnimationFrame from object window.
+                        * @method windowRequestAnimationFrame
+                        * @static
+                        * @member ns.util
+                        */
+                       util.windowRequestAnimationFrame = util._getRequestAnimationFrame();
+
+                       /**
+                        * Special requestAnimationFrame function which add functions to queue of callbacks
+                        * @method requestAnimationFrame
+                        * @static
+                        * @member ns.util
+                        */
+                       util.requestAnimationFrame = function (callback) {
+                               waitingFrames.push(callback);
+                               if (!loopWork) {
+                                       util.windowRequestAnimationFrame(util._loop);
+                                       loopWork = true;
+                               }
+                       };
+
+                       util._cancelAnimationFrameOnSetTimeout = function () {
+                               // probably wont work if there is any more than 1
+                               // active animationFrame but we are trying anyway
+                               window.clearTimeout(currentFrame);
+                       };
+
+                       /**
+                        * Remove animation callbacks added by requestAnimationFrame
+                        * @method cancelAnimationFrames
+                        * @static
+                        * @member ns.util
+                        * @param {*} animationId value for identify animation in queue
+                        */
+                       util.cancelAnimationFrames = function (animationId) {
+                               var found = 0,
+                                       len = waitingFrames.length,
+                                       i = 0;
+
+                               if (animationId) {
+                                       // remove selected requests
+                                       while (len > 0 && found > -1) {
+                                               found = -1;
+                                               for (; i < len; i++) {
+                                                       if (waitingFrames[i].animationId === animationId) {
+                                                               found = i;
+                                                               break;
+                                                       }
+                                               }
+
+                                               if (found > -1) {
+                                                       waitingFrames.splice(found, 1);
+                                                       len--;
+                                               }
+                                       }
+                               } else {
+                                       ns.warn("cancelAnimationFrames() require one parameter for request identify");
+                               }
+                       };
+
+                       util._getCancelAnimationFrame = function () {
+                               return (window.cancelAnimationFrame ||
+                                       window.webkitCancelAnimationFrame ||
+                                       window.mozCancelAnimationFrame ||
+                                       window.oCancelAnimationFrame ||
+                                       window.msCancelAnimationFrame ||
+                                       util._cancelAnimationFrameOnSetTimeout).bind(window);
+                       };
+
+                       util.cancelAnimationFrame = util._getCancelAnimationFrame();
+
+                       /**
+                        * fetchSync retrieves a text document synchronously, returns null on error
+                        * @param {string} url
+                        * @param {=string} [mime=""] Mime type of the resource
+                        * @return {string|null}
+                        * @static
+                        * @member ns.util
+                        */
+                       function fetchSync(url, mime) {
+                               var xhr = new XMLHttpRequest(),
+                                       status;
+
+                               xhr.open("get", url, false);
+                               if (mime) {
+                                       xhr.overrideMimeType(mime);
+                               }
+                               xhr.send();
+                               if (xhr.readyState === 4) {
+                                       status = xhr.status;
+                                       if (status === 200 || (status === 0 && xhr.responseText)) {
+                                               return xhr.responseText;
+                                       }
+                               }
+
+                               return null;
+                       }
+
+                       util.fetchSync = fetchSync;
+
+                       /**
+                        * Removes all script tags with src attribute from document and returns them
+                        * @param {HTMLElement} container
+                        * @return {Array.<HTMLElement>}
+                        * @protected
+                        * @static
+                        * @member ns.util
+                        */
+                       function removeExternalScripts(container) {
+                               var scripts = slice.call(container.querySelectorAll("script[src]")),
+                                       i = scripts.length,
+                                       script;
+
+                               while (--i >= 0) {
+                                       script = scripts[i];
+                                       script.parentNode.removeChild(script);
+                               }
+
+                               return scripts;
+                       }
+
+                       util._removeExternalScripts = removeExternalScripts;
+
+                       /**
+                        * Evaluates code, reason for a function is for an atomic call to evaluate code
+                        * since most browsers fail to optimize functions with try-catch blocks, so this
+                        * minimizes the effect, returns the function to run
+                        * @param {string} code
+                        * @return {Function}
+                        * @static
+                        * @member ns.util
+                        */
+                       function safeEvalWrap(code) {
+                               return function () {
+                                       try {
+                                               window.eval(code);
+                                       } catch (e) {
+                                               if (e.stack) {
+                                                       ns.error(e.stack);
+                                               } else if (e.name && e.message) {
+                                                       ns.error(e.name, e.message);
+                                               } else {
+                                                       ns.error(e);
+                                               }
+                                       }
+                               };
+                       }
+
+                       util.safeEvalWrap = safeEvalWrap;
+
+                       /**
+                        * Calls functions in supplied queue (array)
+                        * @param {Array.<Function>} functionQueue
+                        * @static
+                        * @member ns.util
+                        */
+                       function batchCall(functionQueue) {
+                               var i,
+                                       length = functionQueue.length;
+
+                               for (i = 0; i < length; ++i) {
+                                       functionQueue[i]();
+                               }
+                       }
+
+                       util.batchCall = batchCall;
+
+                       /**
+                        * Creates new script elements for scripts gathered from a different document
+                        * instance, blocks asynchronous evaluation (by renaming src attribute) and
+                        * returns an array of functions to run to evaluate those scripts
+                        * @param {Array.<HTMLElement>} scripts
+                        * @param {HTMLElement} container
+                        * @return {Array.<Function>}
+                        * @protected
+                        * @static
+                        * @member ns.util
+                        */
+                       function createScriptsSync(scripts, container) {
+                               var scriptElement,
+                                       scriptBody,
+                                       i,
+                                       length,
+                                       queue = [];
+
+                               // proper order of execution
+                               for (i = 0, length = scripts.length; i < length; ++i) {
+                                       scriptBody = util.fetchSync(scripts[i].src, "text/plain");
+                                       if (scriptBody) {
+                                               scriptElement = document.adoptNode(scripts[i]);
+                                               scriptElement.setAttribute("data-src", scripts[i].src);
+                                               scriptElement.removeAttribute("src"); // block evaluation
+                                               queue.push(util.safeEvalWrap(scriptBody));
+                                               if (container) {
+                                                       container.appendChild(scriptElement);
+                                               }
+                                       }
+                               }
+
+                               return queue;
+                       }
+
+                       util._createScriptsSync = createScriptsSync;
+
+                       function removeInlineScripts(element) {
+                               var result = [],
+                                       script;
+
+                               slice.call(element.querySelectorAll(
+                                       "script:not([data-src]):not([type]):not([id]):not([src])"
+                                       )).forEach(function (item) {
+                                               script = document.createElement("script");
+                                               script.innerText = item.textContent;
+                                               // move attributes from original script element
+                                               slice.call(item.attributes).forEach(function (attribute) {
+                                                       script.setAttribute(attribute.name, item.getAttribute(attribute.name));
+                                               });
+                                               item.parentNode.removeChild(item);
+                                               result.push(script);
+                                       });
+
+                               return result;
+                       }
+
+                       util._removeInlineScripts = removeInlineScripts;
+
+                       /**
+                        * Method make asynchronous call of function
+                        * @method async
+                        * @inheritdoc #requestAnimationFrame
+                        * @member ns.util
+                        * @static
+                        */
+                       util.async = util.requestAnimationFrame;
+
+                       /**
+                        * Appends element from different document instance to current document in the
+                        * container element and evaluates scripts (synchronously)
+                        * @param {HTMLElement} element
+                        * @param {HTMLElement} container
+                        * @return {HTMLElement}
+                        * @method importEvaluateAndAppendElement
+                        * @member ns.util
+                        * @static
+                        */
+                       util.importEvaluateAndAppendElement = function (element, container) {
+                               var externalScriptsQueue =
+                                               util._createScriptsSync(util._removeExternalScripts(element), element),
+                                       inlineScripts = util._removeInlineScripts(element),
+                                       newNode = document.importNode(element, true)
+
+                               container.appendChild(newNode); // append and eval inline
+                               inlineScripts.forEach(function (script) {
+                                       container.appendChild(script);
+                               });
+                               util.batchCall(externalScriptsQueue);
+
+                               return newNode;
+                       };
+
+                       /**
+                        * Checks if specified string is a number or not
+                        * @method isNumber
+                        * @param {string} query
+                        * @return {boolean}
+                        * @member ns.util
+                        * @static
+                        */
+                       util.isNumber = function (query) {
+                               var parsed = parseFloat(query);
+
+                               return !isNaN(parsed) && isFinite(parsed);
+                       };
+
+                       /**
+                        * Reappear script tags to DOM structure to correct run script
+                        * @method runScript
+                        * @param {string} baseUrl
+                        * @param {HTMLScriptElement} script
+                        * @member ns.util
+                        * @deprecated 2.3
+                        */
+                       util.runScript = function (baseUrl, script) {
+                               var newScript = document.createElement("script"),
+                                       scriptData,
+                                       i,
+                                       scriptAttributes = slice.call(script.attributes),
+                                       src = script.getAttribute("src"),
+                                       attribute,
+                                       status;
+
+                               // 'src' may become null when none src attribute is set
+                               if (src !== null) {
+                                       src = util.path.makeUrlAbsolute(src, baseUrl);
+                               }
+
+                               //Copy script tag attributes
+                               i = scriptAttributes.length;
+                               while (--i >= 0) {
+                                       attribute = scriptAttributes[i];
+                                       if (attribute.name !== "src") {
+                                               newScript.setAttribute(attribute.name, attribute.value);
+                                       } else {
+                                               newScript.setAttribute("data-src", attribute.value);
+                                       }
+                               }
+
+                               if (src) {
+                                       scriptData = util.fetchSync(src, "text/plain");
+                                                                       } else {
+                                       scriptData = script.textContent;
+                               }
+
+                               if (scriptData) {
+                                       // add the returned content to a newly created script tag
+                                       newScript.src = window.URL.createObjectURL(new Blob([scriptData], {type: "text/javascript"}));
+                                       newScript.textContent = scriptData; // for compatibility with some libs ex. template systems
+                               }
+                               script.parentNode.replaceChild(newScript, script);
+                       };
+
+                       ns.util = util;
+                       }(window, window.document, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, ns, define */
+/**
+ * #Array Utility
+ *
+ * Utility helps work with arrays.
+ *
+ * @class ns.util.array
+ */
+(function (ns) {
+       "use strict";
+       
+                       /**
+                        * Convert values to common type and return information about type string or not.
+                        * @param {number|string} low
+                        * @param {number|string} high
+                        * @return {{inival: *, endval: *, chars: boolean}}
+                        */
+                       function convertTypes(low, high) {
+                               var inival,
+                                       endval,
+                                       chars = false;
+
+                               if (isNaN(low) && isNaN(high)) {
+                                       chars = true;
+                                       inival = low.charCodeAt(0);
+                                       endval = high.charCodeAt(0);
+                               } else {
+                                       inival = (isNaN(low) ? 0 : low);
+                                       endval = (isNaN(high) ? 0 : high);
+                               }
+                               return {
+                                       inival: inival,
+                                       endval: endval,
+                                       chars: chars
+                               };
+                       }
+
+                       /**
+                        * Create an array containing the range of integers or characters
+                        * from low to high (inclusive)
+                        * @method range
+                        * @param {number|string} low
+                        * @param {number|string} high
+                        * @param {number} step
+                        * @static
+                        * @return {Array} array containing continuos elements
+                        * @member ns.util.array
+                        */
+                       function range(low, high, step) {
+                               // Create an array containing the range of integers or characters
+                               // from low to high (inclusive)
+                               //
+                               // version: 1107.2516
+                               // discuss at: http://phpjs.org/functions/range
+                               // +   original by: Waldo Malqui Silva
+                               // *    example 1: range ( 0, 12 );
+                               // *    returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+                               // *    example 2: range( 0, 100, 10 );
+                               // *    returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
+                               // *    example 3: range( 'a', 'i' );
+                               // *    returns 3: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
+                               // *    example 4: range( 'c', 'a' );
+                               // *    returns 4: ['c', 'b', 'a']
+                               var matrix = [],
+                                       inival,
+                                       endval,
+                                       plus,
+                                       walker = step || 1,
+                                       chars,
+                                       typeData;
+
+                               typeData = convertTypes(low, high);
+                               inival = typeData.inival;
+                               endval = typeData.endval;
+                               chars = typeData.chars;
+
+                               plus = inival <= endval;
+                               if (plus) {
+                                       while (inival <= endval) {
+                                               matrix.push((chars ? String.fromCharCode(inival) : inival));
+                                               inival += walker;
+                                       }
+                               } else {
+                                       while (inival >= endval) {
+                                               matrix.push((chars ? String.fromCharCode(inival) : inival));
+                                               inival -= walker;
+                                       }
+                               }
+
+                               return matrix;
+                       }
+
+                       function isCorrectType(object) {
+                               return Array.isArray(object) || object instanceof NodeList || typeof object === "function";
+                       }
+
+                       function hasCorrectLength(object) {
+                               var length = object.length;
+
+                               return (length === 0 || typeof length === "number" && length > 0 && (length - 1) in object);
+                       }
+
+                       /**
+                        * Check object is array-like (array-like include array and
+                        * collection)
+                        * @method isArrayLike
+                        * @param {Object} object
+                        * @return {boolean} Whether array-like object or not
+                        * @member ns.util.array
+                        * @static
+                        */
+                       function isArrayLike(object) {
+
+                               // if object exists and is different from window
+                               // window object has length property
+                               if (object && object !== object.window) {
+                                       // If length value is not number, object is not array and collection.
+                                       // Collection type is not array but has length value.
+                                       // e.g) Array.isArray(document.childNodes) ==> false
+                                       return isCorrectType(object) && hasCorrectLength(object);
+                               }
+                               return false;
+                       }
+
+                       /**
+                        * Faster version of standard forEach method in array
+                        * Confirmed that this method is 20 times faster then native
+                        * @method forEach
+                        * @param {Array} array
+                        * @param {Function} callback
+                        * @member ns.util.array
+                        * @static
+                        */
+                       function forEach(array, callback) {
+                               var i,
+                                       length,
+                                       convertedArray = array;
+
+                               if (!(array instanceof Array)) {
+                                       convertedArray = [].slice.call(array);
+                               }
+                               length = convertedArray.length;
+                               for (i = 0; i < length; i++) {
+                                       callback(convertedArray[i], i, convertedArray);
+                               }
+                       }
+
+
+                       /**
+                        * Faster version of standard filter method in array
+                        * @method filter
+                        * @param {Array} array
+                        * @param {Function} callback
+                        * @member ns.util.array
+                        * @static
+                        */
+                       function filter(array, callback) {
+                               var result = [],
+                                       i,
+                                       length,
+                                       value,
+                                       convertedArray = array;
+
+                               if (!(array instanceof Array)) {
+                                       convertedArray = [].slice.call(array);
+                               }
+                               length = convertedArray.length;
+                               for (i = 0; i < length; i++) {
+                                       value = convertedArray[i];
+                                       if (callback(value, i, convertedArray)) {
+                                               result.push(value);
+                                       }
+                               }
+                               return result;
+                       }
+
+                       /**
+                        * Faster version of standard map method in array
+                        * Confirmed that this method is 60% faster then native
+                        * @method map
+                        * @param {Array} array
+                        * @param {Function} callback
+                        * @member ns.util.array
+                        * @static
+                        */
+                       function map(array, callback) {
+                               var result = [],
+                                       i,
+                                       length,
+                                       convertedArray = array;
+
+                               if (!(array instanceof Array)) {
+                                       convertedArray = [].slice.call(array);
+                               }
+                               length = convertedArray.length;
+                               for (i = 0; i < length; i++) {
+                                       result.push(callback(convertedArray[i], i, convertedArray));
+                               }
+                               return result;
+                       }
+
+                       /**
+                        * Faster version of standard reduce method in array
+                        * Confirmed that this method is 60% faster then native
+                        * @method reduce
+                        * @param {Array} array
+                        * @param {Function} callback
+                        * @param {*} [initialValue]
+                        * @member ns.util.array
+                        * @return {*}
+                        * @static
+                        */
+                       function reduce(array, callback, initialValue) {
+                               var i,
+                                       length,
+                                       value,
+                                       result = initialValue,
+                                       convertedArray = array;
+
+                               if (!(array instanceof Array)) {
+                                       convertedArray = [].slice.call(array);
+                               }
+                               length = convertedArray.length;
+                               for (i = 0; i < length; i++) {
+                                       value = convertedArray[i];
+                                       if (result === undefined && i === 0) {
+                                               result = value;
+                                       } else {
+                                               result = callback(result, value, i, convertedArray);
+                                       }
+                               }
+                               return result;
+                       }
+
+                       ns.util.array = {
+                               range: range,
+                               isArrayLike: isArrayLike,
+                               forEach: forEach,
+                               filter: filter,
+                               map: map,
+                               reduce: reduce
+                       };
+
+                       }(ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/* global ns, define, CustomEvent */
+/**
+ * #Events
+ *
+ * The Tizen Advanced UI (TAU) framework provides events optimized for the Tizen
+ * Web application. The following table displays the events provided by the TAU
+ * framework.
+ * @class ns.event
+ */
+(function (window, ns) {
+       "use strict";
+                               /**
+                        * Checks if specified variable is a array or not
+                        * @method isArray
+                        * @return {boolean}
+                        * @member ns.event
+                        * @private
+                        * @static
+                        */
+                       var instances = [],
+                               isArray = Array.isArray,
+                               isArrayLike = ns.util.array.isArrayLike,
+                               /**
+                                * @property {RegExp} SPLIT_BY_SPACES_REGEXP
+                                */
+                               SPLIT_BY_SPACES_REGEXP = /\s+/g,
+
+                               /**
+                                * Returns trimmed value
+                                * @method trim
+                                * @param {string} value
+                                * @return {string} trimmed string
+                                * @static
+                                * @private
+                                * @member ns.event
+                                */
+                               trim = function (value) {
+                                       return value.trim();
+                               },
+
+                               /**
+                                * Split string to array
+                                * @method getEventsListeners
+                                * @param {string|Array|Object} names string with one name of event, many names of events
+                                * divided by spaces, array with names of widgets or object in which keys are names of
+                                * events and values are callbacks
+                                * @param {Function} globalListener
+                                * @return {Array}
+                                * @static
+                                * @private
+                                * @member ns.event
+                                */
+                               getEventsListeners = function (names, globalListener) {
+                                       var name,
+                                               result = [],
+                                               i;
+
+                                       if (typeof names === "string") {
+                                               names = names.split(SPLIT_BY_SPACES_REGEXP).map(trim);
+                                       }
+
+                                       if (isArray(names)) {
+                                               for (i = 0; i < names.length; i++) {
+                                                       result.push({type: names[i], callback: globalListener});
+                                               }
+                                       } else {
+                                               for (name in names) {
+                                                       if (names.hasOwnProperty(name)) {
+                                                               result.push({type: name, callback: names[name]});
+                                                       }
+                                               }
+                                       }
+                                       return result;
+                               };
+
+                       /**
+                        * Find instance by element
+                        * @method findInstance
+                        * @param {HTMLElement} element
+                        * @return {ns.event.gesture.Instance}
+                        * @member ns.event
+                        * @static
+                        * @private
+                        */
+                       function findInstance(element) {
+                               var instance;
+
+                               instances.forEach(function (item) {
+                                       if (item.element === element) {
+                                               instance = item.instance;
+                                       }
+                               });
+                               return instance;
+                       }
+
+                       /**
+                        * Remove instance from instances by element
+                        * @method removeInstance
+                        * @param {HTMLElement} element
+                        * @member ns.event
+                        * @static
+                        * @private
+                        */
+                       function removeInstance(element) {
+                               instances.forEach(function (item, key) {
+                                       if (item.element === element) {
+                                               instances.splice(key, 1);
+                                       }
+                               });
+                       }
+
+
+                       ns.event = {
+
+                               /**
+                                * Triggers custom event fastOn element
+                                * The return value is false, if at least one of the event
+                                * handlers which handled this event, called preventDefault.
+                                * Otherwise it returns true.
+                                * @method trigger
+                                * @param {HTMLElement|HTMLDocument} element
+                                * @param {string} type
+                                * @param {?*} [data=null]
+                                * @param {boolean=} [bubbles=true]
+                                * @param {boolean=} [cancelable=true]
+                                * @return {boolean}
+                                * @member ns.event
+                                * @static
+                                */
+                               trigger: function (element, type, data, bubbles, cancelable) {
+                                       var evt = new CustomEvent(type, {
+                                               "detail": data,
+                                               //allow event to bubble up, required if we want to allow to listen fastOn document etc
+                                               bubbles: typeof bubbles === "boolean" ? bubbles : true,
+                                               cancelable: typeof cancelable === "boolean" ? cancelable : true
+                                       });
+                                                                               return element.dispatchEvent(evt);
+                               },
+
+                               /**
+                                * Prevent default on original event
+                                * @method preventDefault
+                                * @param {Event} event
+                                * @member ns.event
+                                * @static
+                                */
+                               preventDefault: function (event) {
+                                       var originalEvent = event._originalEvent;
+                                       // @todo this.isPropagationStopped = returnTrue;
+
+                                       if (originalEvent && originalEvent.preventDefault) {
+                                               originalEvent.preventDefault();
+                                       }
+                                       event.preventDefault();
+                               },
+
+                               /**
+                                * Stop event propagation
+                                * @method stopPropagation
+                                * @param {Event} event
+                                * @member ns.event
+                                * @static
+                                */
+                               stopPropagation: function (event) {
+                                       var originalEvent = event._originalEvent;
+                                       // @todo this.isPropagationStopped = returnTrue;
+
+                                       if (originalEvent && originalEvent.stopPropagation) {
+                                               originalEvent.stopPropagation();
+                                       }
+                                       event.stopPropagation();
+                               },
+
+                               /**
+                                * Stop event propagation immediately
+                                * @method stopImmediatePropagation
+                                * @param {Event} event
+                                * @member ns.event
+                                * @static
+                                */
+                               stopImmediatePropagation: function (event) {
+                                       var originalEvent = event._originalEvent;
+                                       // @todo this.isPropagationStopped = returnTrue;
+
+                                       if (originalEvent && originalEvent.stopImmediatePropagation) {
+                                               originalEvent.stopImmediatePropagation();
+                                       }
+                                       event.stopImmediatePropagation();
+                               },
+
+                               /**
+                                * Return document relative cords for event
+                                * @method documentRelativeCoordsFromEvent
+                                * @param {Event} event
+                                * @return {Object}
+                                * @return {number} return.x
+                                * @return {number} return.y
+                                * @member ns.event
+                                * @static
+                                */
+                               documentRelativeCoordsFromEvent: function (event) {
+                                       var _event = event ? event : window.event,
+                                               client = {
+                                                       x: _event.clientX,
+                                                       y: _event.clientY
+                                               },
+                                               page = {
+                                                       x: _event.pageX,
+                                                       y: _event.pageY
+                                               },
+                                               posX = 0,
+                                               posY = 0,
+                                               touch0,
+                                               body = document.body,
+                                               documentElement = document.documentElement;
+
+                                       if (event.type.match(/^touch/)) {
+                                               touch0 = _event.targetTouches[0] || _event.originalEvent.targetTouches[0];
+                                               page = {
+                                                       x: touch0.pageX,
+                                                       y: touch0.pageY
+                                               };
+                                               client = {
+                                                       x: touch0.clientX,
+                                                       y: touch0.clientY
+                                               };
+                                       }
+
+                                       if (page.x || page.y) {
+                                               posX = page.x;
+                                               posY = page.y;
+                                       } else if (client.x || client.y) {
+                                               posX = client.x + body.scrollLeft + documentElement.scrollLeft;
+                                               posY = client.y + body.scrollTop + documentElement.scrollTop;
+                                       }
+
+                                       return {x: posX, y: posY};
+                               },
+
+                               /**
+                                * Return target relative cords for event
+                                * @method targetRelativeCoordsFromEvent
+                                * @param {Event} event
+                                * @return {Object}
+                                * @return {number} return.x
+                                * @return {number} return.y
+                                * @member ns.event
+                                * @static
+                                */
+                               targetRelativeCoordsFromEvent: function (event) {
+                                       var target = event.target,
+                                               cords = {
+                                                       x: event.offsetX,
+                                                       y: event.offsetY
+                                               };
+
+                                       if (cords.x === undefined || isNaN(cords.x) ||
+                                               cords.y === undefined || isNaN(cords.y)) {
+                                               cords = ns.event.documentRelativeCoordsFromEvent(event);
+                                               cords.x -= target.offsetLeft;
+                                               cords.y -= target.offsetTop;
+                                       }
+
+                                       return cords;
+                               },
+
+                               /**
+                                * Add event listener to element
+                                * @method fastOn
+                                * @param {HTMLElement} element
+                                * @param {string} type
+                                * @param {Function} listener
+                                * @param {boolean} [useCapture=false]
+                                * @member ns.event
+                                * @static
+                                */
+                               fastOn: function (element, type, listener, useCapture) {
+                                       element.addEventListener(type, listener, useCapture || false);
+                               },
+
+                               /**
+                                * Remove event listener to element
+                                * @method fastOff
+                                * @param {HTMLElement} element
+                                * @param {string} type
+                                * @param {Function} listener
+                                * @param {boolean} [useCapture=false]
+                                * @member ns.event
+                                * @static
+                                */
+                               fastOff: function (element, type, listener, useCapture) {
+                                       element.removeEventListener(type, listener, useCapture || false);
+                               },
+
+                               /**
+                                * Add event listener to element with prefixes for all browsers
+                                *
+                                *      @example
+                                *              tau.event.prefixedFastOn(document, "animationEnd", function() {
+                                *                      console.log("animation ended");
+                                *              });
+                                *              // write "animation ended" on console on event "animationEnd", "webkitAnimationEnd", "mozAnimationEnd", "msAnimationEnd", "oAnimationEnd"
+                                *
+                                * @method fastPrefixedOn
+                                * @param {HTMLElement} element
+                                * @param {string} type
+                                * @param {Function} listener
+                                * @param {boolean} [useCapture=false]
+                                * @member ns.event
+                                * @static
+                                */
+                               prefixedFastOn: function (element, type, listener, useCapture) {
+                                       var nameForPrefix = type.charAt(0).toLocaleUpperCase() + type.substring(1);
+
+                                       element.addEventListener(type.toLowerCase(), listener, useCapture || false);
+                                       element.addEventListener("webkit" + nameForPrefix, listener, useCapture || false);
+                                       element.addEventListener("moz" + nameForPrefix, listener, useCapture || false);
+                                       element.addEventListener("ms" + nameForPrefix, listener, useCapture || false);
+                                       element.addEventListener("o" + nameForPrefix.toLowerCase(), listener, useCapture || false);
+                               },
+
+                               /**
+                                * Remove event listener to element with prefixes for all browsers
+                                *
+                                *      @example
+                                *              tau.event.prefixedFastOff(document, "animationEnd", functionName);
+                                *              // remove listeners functionName on events "animationEnd", "webkitAnimationEnd", "mozAnimationEnd", "msAnimationEnd", "oAnimationEnd"
+                                *
+                                * @method fastPrefixedOff
+                                * @param {HTMLElement} element
+                                * @param {string} type
+                                * @param {Function} listener
+                                * @param {boolean} [useCapture=false]
+                                * @member ns.event
+                                * @static
+                                */
+                               prefixedFastOff: function (element, type, listener, useCapture) {
+                                       var nameForPrefix = type.charAt(0).toLocaleUpperCase() + type.substring(1);
+
+                                       element.removeEventListener(type.toLowerCase(), listener, useCapture || false);
+                                       element.removeEventListener("webkit" + nameForPrefix, listener, useCapture || false);
+                                       element.removeEventListener("moz" + nameForPrefix, listener, useCapture || false);
+                                       element.removeEventListener("ms" + nameForPrefix, listener, useCapture || false);
+                                       element.removeEventListener("o" + nameForPrefix.toLowerCase(), listener, useCapture || false);
+                               },
+
+                               /**
+                                * Add event listener to element that can be added addEventListener
+                                * @method on
+                                * @param {HTMLElement|HTMLDocument|Window} element
+                                * @param {string|Array|Object} type
+                                * @param {Function} listener
+                                * @param {boolean} [useCapture=false]
+                                * @member ns.event
+                                * @static
+                                */
+                               on: function (element, type, listener, useCapture) {
+                                       var i,
+                                               j,
+                                               elementsLength,
+                                               typesLength,
+                                               elements,
+                                               listeners;
+
+                                       if (isArrayLike(element)) {
+                                               elements = element;
+                                       } else {
+                                               elements = [element];
+                                       }
+                                       elementsLength = elements.length;
+                                       listeners = getEventsListeners(type, listener);
+                                       typesLength = listeners.length;
+                                       for (i = 0; i < elementsLength; i++) {
+                                               if (typeof elements[i].addEventListener === "function") {
+                                                       for (j = 0; j < typesLength; j++) {
+                                                               ns.event.fastOn(elements[i], listeners[j].type, listeners[j].callback, useCapture);
+                                                       }
+                                               }
+                                       }
+                               },
+
+                               /**
+                                * Remove event listener to element
+                                * @method off
+                                * @param {HTMLElement|HTMLDocument|Window} element
+                                * @param {string|Array|Object} type
+                                * @param {Function} listener
+                                * @param {boolean} [useCapture=false]
+                                * @member ns.event
+                                * @static
+                                */
+                               off: function (element, type, listener, useCapture) {
+                                       var i,
+                                               j,
+                                               elementsLength,
+                                               typesLength,
+                                               elements,
+                                               listeners;
+
+                                       if (isArrayLike(element)) {
+                                               elements = element;
+                                       } else {
+                                               elements = [element];
+                                       }
+                                       elementsLength = elements.length;
+                                       listeners = getEventsListeners(type, listener);
+                                       typesLength = listeners.length;
+                                       for (i = 0; i < elementsLength; i++) {
+                                               if (typeof elements[i].addEventListener === "function") {
+                                                       for (j = 0; j < typesLength; j++) {
+                                                               ns.event.fastOff(elements[i], listeners[j].type, listeners[j].callback, useCapture);
+                                                       }
+                                               }
+                                       }
+                               },
+
+                               /**
+                                * Add event listener to element only for one trigger
+                                * @method one
+                                * @param {HTMLElement|HTMLDocument|window} element
+                                * @param {string|Array|Object} type
+                                * @param {Function} listener
+                                * @param {boolean} [useCapture=false]
+                                * @member ns.event
+                                * @static
+                                */
+                               one: function (element, type, listener, useCapture) {
+                                       var arraySlice = [].slice,
+                                               i,
+                                               j,
+                                               elementsLength,
+                                               typesLength,
+                                               elements,
+                                               listeners,
+                                               callbacks = [];
+
+                                       if (isArrayLike(element)) {
+                                               elements = arraySlice.call(element);
+                                       } else {
+                                               elements = [element];
+                                       }
+                                       elementsLength = elements.length;
+                                       // pair type with listener
+                                       listeners = getEventsListeners(type, listener);
+                                       typesLength = listeners.length;
+                                       // on each element
+                                       for (i = 0; i < elementsLength; i++) {
+                                               // if element has possibility of add listener
+                                               if (typeof elements[i].addEventListener === "function") {
+                                                       callbacks[i] = [];
+                                                       // for each event type
+                                                       for (j = 0; j < typesLength; j++) {
+                                                               callbacks[i][j] = (function (i, j) {
+                                                                       var args = arraySlice.call(arguments);
+
+                                                                       ns.event.fastOff(elements[i], listeners[j].type, callbacks[i][j], useCapture);
+                                                                       // remove the first argument of binding function
+                                                                       args.shift();
+                                                                       // remove the second argument of binding function
+                                                                       args.shift();
+                                                                       listeners[j].callback.apply(this, args);
+                                                               }).bind(null, i, j);
+                                                               ns.event.fastOn(elements[i], listeners[j].type, callbacks[i][j], useCapture);
+                                                       }
+                                               }
+                                       }
+                               },
+
+                               // disable is required because method has changing arguments
+                               /* eslint-disable jsdoc/check-param-names */
+
+                               /**
+                                * Enable gesture handling on given HTML element or object
+                                * @method enableGesture
+                                * @param {HTMLElement} element
+                                * @param {...Object} [gesture] Gesture object {@link ns.event.gesture}
+                                * @member ns.event
+                                */
+                               enableGesture: function (element) {
+                                       var gestureInstance = findInstance(element),
+                                               length = arguments.length,
+                                               i = 1;
+
+                                       if (!gestureInstance) {
+                                               gestureInstance = new ns.event.gesture.Instance(element);
+                                               instances.push({element: element, instance: gestureInstance});
+                                       }
+
+                                       for (; i < length; i++) {
+                                               gestureInstance.addDetector(arguments[i]);
+                                       }
+                               },
+
+                               /**
+                                * Disable gesture handling from given HTML element or object
+                                * @method disableGesture
+                                * @param {HTMLElement} element
+                                * @param {...Object} [gesture] Gesture object {@link ns.event.gesture}
+                                * @member ns.event
+                                */
+                               disableGesture: function (element) {
+                                       var gestureInstance = findInstance(element),
+                                               length = arguments.length,
+                                               i = 1;
+
+                                       if (!gestureInstance) {
+                                               return;
+                                       }
+
+                                       if (length > 1) {
+                                               gestureInstance.removeDetector(arguments[i]);
+                                       } else {
+                                               gestureInstance.destroy();
+                                               removeInstance(element);
+                                       }
+                               }
+
+                               /* eslint-disable jsdoc/check-param-names */
+                       };
+
+                       }(window, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Info
+ *
+ * Various TAU information
+ * @class ns.info
+ */
+(function (window, document) {
+       "use strict";
+                               /**
+                        * @property {Object} info
+                        * @property {string} [info.profile="default"] Current runtime profile
+                        * @property {string} [info.theme="default"] Current runtime theme
+                        * @property {string} info.version Current runtime version
+                        * @member ns.info
+                        * @static
+                        */
+                       var eventUtils = ns.event,
+                               info = {
+                                       profile: "default",
+                                       theme: "default",
+                                       version: ns.version,
+
+                                       /**
+                                        * Refreshes information about runtime
+                                        * @method refreshTheme
+                                        * @param {Function} done Callback run when the theme is discovered
+                                        * @member ns.info
+                                        * @return {null|String}
+                                        * @static
+                                        */
+                                       refreshTheme: function (done) {
+                                               var el = document.createElement("span"),
+                                                       parent = document.body,
+                                                       themeName;
+
+                                               if (document.readyState !== "interactive" && document.readyState !== "complete") {
+                                                       eventUtils.fastOn(document, "DOMContentLoaded", this.refreshTheme.bind(this, done));
+                                                       return null;
+                                               }
+                                               el.classList.add("tau-info-theme");
+
+                                               parent.appendChild(el);
+                                               themeName = window.getComputedStyle(el, ":after").content;
+                                               if (themeName) {
+                                                       themeName = themeName.replace(/\"/g, "");
+                                               }
+                                               parent.removeChild(el);
+
+                                               if (themeName && themeName.length > 0) {
+                                                       this.theme = themeName;
+                                               }
+
+                                               themeName = themeName || null;
+
+                                               if (done) {
+                                                       done(themeName);
+                                               }
+
+                                               return themeName;
+                                       }
+                               };
+
+                       info.refreshTheme();
+
+                       ns.info = info;
+                       }(window, window.document));
+
+/*global define: false, window: false, ns: false */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Selectors Utility
+ * Object contains functions to get HTML elements by different selectors.
+ * @class ns.util.selectors
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@partner.samsung.com>
+ * @author Damian Osipiuk <d.osipiuk@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               /**
+                        * @method slice Alias for array slice method
+                        * @member ns.util.selectors
+                        * @private
+                        * @static
+                        */
+                       var slice = [].slice,
+                               /**
+                                * @method matchesSelectorType
+                                * @return {string|boolean}
+                                * @member ns.util.selectors
+                                * @private
+                                * @static
+                                */
+                               matchesSelectorType = (function () {
+                                       var el = document.createElement("div");
+
+                                       if (typeof el.webkitMatchesSelector === "function") {
+                                               return "webkitMatchesSelector";
+                                       }
+
+                                       if (typeof el.mozMatchesSelector === "function") {
+                                               return "mozMatchesSelector";
+                                       }
+
+                                       if (typeof el.msMatchesSelector === "function") {
+                                               return "msMatchesSelector";
+                                       }
+
+                                       if (typeof el.matchesSelector === "function") {
+                                               return "matchesSelector";
+                                       }
+
+                                       if (typeof el.matches === "function") {
+                                               return "matches";
+                                       }
+
+                                       return "";
+                               }());
+
+                       /**
+                        * Prefix selector with 'data-' and namespace if present
+                        * @method getDataSelector
+                        * @param {string} selector
+                        * @return {string}
+                        * @member ns.util.selectors
+                        * @private
+                        * @static
+                        */
+                       function getDataSelector(selector) {
+                               var namespace = ns.getConfig("namespace");
+
+                               return "[data-" + (namespace ? namespace + "-" : "") + selector + "]";
+                       }
+
+                       /**
+                        * Runs matches implementation of matchesSelector
+                        * method on specified element
+                        * @method matchesSelector
+                        * @param {HTMLElement} element
+                        * @param {string} selector
+                        * @return {boolean}
+                        * @static
+                        * @member ns.util.selectors
+                        */
+                       function matchesSelector(element, selector) {
+                               if (matchesSelectorType && element[matchesSelectorType]) {
+                                       return element[matchesSelectorType](selector);
+                               }
+                               return false;
+                       }
+
+                       /**
+                        * Return array with all parents of element.
+                        * @method parents
+                        * @param {HTMLElement} element
+                        * @return {Array}
+                        * @member ns.util.selectors
+                        * @private
+                        * @static
+                        */
+                       function parents(element) {
+                               var items = [],
+                                       current = element.parentNode;
+
+                               while (current && current !== document) {
+                                       items.push(current);
+                                       current = current.parentNode;
+                               }
+                               return items;
+                       }
+
+                       /**
+                        * Checks if given element and its ancestors matches given function
+                        * @method closest
+                        * @param {HTMLElement} element
+                        * @param {Function} testFunction
+                        * @return {?HTMLElement}
+                        * @member ns.util.selectors
+                        * @static
+                        * @private
+                        */
+                       function closest(element, testFunction) {
+                               var current = element;
+
+                               while (current && current !== document) {
+                                       if (testFunction(current)) {
+                                               return current;
+                                       }
+                                       current = current.parentNode;
+                               }
+                               return null;
+                       }
+
+                       /**
+                        * @method testSelector
+                        * @param {string} selector
+                        * @param {HTMLElement} node
+                        * @return {boolean}
+                        * @member ns.util.selectors
+                        * @static
+                        * @private
+                        */
+                       function testSelector(selector, node) {
+                               return matchesSelector(node, selector);
+                       }
+
+                       /**
+                        * @method testClass
+                        * @param {string} className
+                        * @param {HTMLElement} node
+                        * @return {boolean}
+                        * @member ns.util.selectors
+                        * @static
+                        * @private
+                        */
+                       function testClass(className, node) {
+                               return node && node.classList && node.classList.contains(className);
+                       }
+
+                       /**
+                        * @method testTag
+                        * @param {string} tagName
+                        * @param {HTMLElement} node
+                        * @return {boolean}
+                        * @member ns.util.selectors
+                        * @static
+                        * @private
+                        */
+                       function testTag(tagName, node) {
+                               return node.tagName.toLowerCase() === tagName;
+                       }
+
+                       /**
+                        * @class ns.util.selectors
+                        */
+                       ns.util.selectors = {
+                               matchesSelector: matchesSelector,
+
+                               /**
+                                * Return array with children pass by given selector.
+                                * @method getChildrenBySelector
+                                * @param {HTMLElement} context
+                                * @param {string} selector
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getChildrenBySelector: function (context, selector) {
+                                       return slice.call(context.children).filter(testSelector.bind(null, selector));
+                               },
+
+                               /**
+                                * Return array with children pass by given data-namespace-selector.
+                                * @method getChildrenByDataNS
+                                * @param {HTMLElement} context
+                                * @param {string} dataSelector
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getChildrenByDataNS: function (context, dataSelector) {
+                                       return slice.call(context.children).filter(testSelector.bind(null,
+                                               getDataSelector(dataSelector)));
+                               },
+
+                               /**
+                                * Return array with children with given class name.
+                                * @method getChildrenByClass
+                                * @param {HTMLElement} context
+                                * @param {string} className
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getChildrenByClass: function (context, className) {
+                                       return slice.call(context.children).filter(testClass.bind(null, className));
+                               },
+
+                               /**
+                                * Return array with children with given tag name.
+                                * @method getChildrenByTag
+                                * @param {HTMLElement} context
+                                * @param {string} tagName
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getChildrenByTag: function (context, tagName) {
+                                       return slice.call(context.children).filter(testTag.bind(null, tagName));
+                               },
+
+                               /**
+                                * Return array with all parents of element.
+                                * @method getParents
+                                * @param {HTMLElement} context
+                                * @param {string} selector
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getParents: parents,
+
+                               /**
+                                * Return array with all parents of element pass by given selector.
+                                * @method getParentsBySelector
+                                * @param {HTMLElement} context
+                                * @param {string} selector
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getParentsBySelector: function (context, selector) {
+                                       return parents(context).filter(testSelector.bind(null, selector));
+                               },
+
+                               /**
+                                * Return array with all parents of element pass by given selector with namespace.
+                                * @method getParentsBySelectorNS
+                                * @param {HTMLElement} context
+                                * @param {string} selector
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getParentsBySelectorNS: function (context, selector) {
+                                       return parents(context).filter(testSelector.bind(null, getDataSelector(selector)));
+                               },
+
+                               /**
+                                * Return array with all parents of element with given class name.
+                                * @method getParentsByClass
+                                * @param {HTMLElement} context
+                                * @param {string} className
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getParentsByClass: function (context, className) {
+                                       return parents(context).filter(testClass.bind(null, className));
+                               },
+
+                               /**
+                                * Return array with all parents of element with given tag name.
+                                * @method getParentsByTag
+                                * @param {HTMLElement} context
+                                * @param {string} tagName
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getParentsByTag: function (context, tagName) {
+                                       return parents(context).filter(testTag.bind(null, tagName));
+                               },
+
+                               /**
+                                * Return first element from parents of element pass by selector.
+                                * @method getClosestBySelector
+                                * @param {HTMLElement} context
+                                * @param {string} selector
+                                * @return {HTMLElement}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getClosestBySelector: function (context, selector) {
+                                       return closest(context, testSelector.bind(null, selector));
+                               },
+
+                               /**
+                                * Return first element from parents of element pass by selector with namespace.
+                                * @method getClosestBySelectorNS
+                                * @param {HTMLElement} context
+                                * @param {string} selector
+                                * @return {HTMLElement}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getClosestBySelectorNS: function (context, selector) {
+                                       return closest(context, testSelector.bind(null, getDataSelector(selector)));
+                               },
+
+                               /**
+                                * Return first element from parents of element with given class name.
+                                * @method getClosestByClass
+                                * @param {HTMLElement} context
+                                * @param {string} selector
+                                * @return {HTMLElement}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getClosestByClass: function (context, selector) {
+                                       return closest(context, testClass.bind(null, selector));
+                               },
+
+                               /**
+                                * Return first element from parents of element with given tag name.
+                                * @method getClosestByTag
+                                * @param {HTMLElement} context
+                                * @param {string} selector
+                                * @return {HTMLElement}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getClosestByTag: function (context, selector) {
+                                       return closest(context, testTag.bind(null, selector));
+                               },
+
+                               /**
+                                * Return array of elements from context with given data-selector
+                                * @method getAllByDataNS
+                                * @param {HTMLElement} context
+                                * @param {string} dataSelector
+                                * @return {Array}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getAllByDataNS: function (context, dataSelector) {
+                                       return slice.call(context.querySelectorAll(getDataSelector(dataSelector)));
+                               },
+
+                               /**
+                                * Get scrollable parent element
+                                * @method getScrollableParent
+                                * @param {HTMLElement} element
+                                * @return {HTMLElement}
+                                * @static
+                                * @member ns.util.selectors
+                                */
+                               getScrollableParent: function (element) {
+                                       var overflow,
+                                               style;
+
+                                       while (element && element !== document.body) {
+                                               style = window.getComputedStyle(element);
+
+                                               if (style) {
+                                                       overflow = style.getPropertyValue("overflow-y");
+                                                       if (overflow === "scroll" || (overflow === "auto" &&
+                                                               element.scrollHeight > element.clientHeight)) {
+                                                               return element;
+                                                       }
+                                               }
+                                               element = element.parentNode;
+                                       }
+                                       return null;
+                               }
+                       };
+                       }(window.document, ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (c) 2010 - 2014 Samsung Electronics Co., Ltd.
+ * License : MIT License V2
+ */
+/**
+ * #Object Utility
+ * Object contains functions help work with objects.
+ * @class ns.util.object
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function () {
+       "use strict";
+       
+                       var object = {
+                               /**
+                                * Copy object to new object
+                                * @method copy
+                                * @param {Object} orgObject
+                                * @return {Object}
+                                * @static
+                                * @member ns.util.object
+                                */
+                               copy: function (orgObject) {
+                                       return object.merge({}, orgObject);
+                               },
+
+                               /**
+                                * Attach fields from second object to first object.
+                                * @method fastMerge
+                                * @param {Object} newObject
+                                * @param {Object} orgObject
+                                * @return {Object}
+                                * @static
+                                * @member ns.util.object
+                                */
+                               fastMerge: function (newObject, orgObject) {
+                                       var key,
+                                               propertyDescriptor;
+
+                                       for (key in orgObject) {
+                                               if (orgObject.hasOwnProperty(key)) {
+                                                       propertyDescriptor = Object.getOwnPropertyDescriptor(newObject, key);
+                                                       if (!propertyDescriptor || propertyDescriptor.writable === true || propertyDescriptor.set != undefined) {
+                                                               newObject[key] = orgObject[key];
+                                                       } else {
+                                                               console.warn("Attempt to override object readonly property (" + key + ") during merge.")
+                                                       }
+                                               }
+                                       }
+                                       return newObject;
+                               },
+
+                               /**
+                                * Attach fields from second and next object to first object.
+                                * @method merge
+                                * @return {Object}
+                                * @static
+                                * @member ns.util.object
+                                */
+                               merge: function (/* newObject, orgObject, override */) {
+                                       var newObject,
+                                               orgObject,
+                                               override,
+                                               key,
+                                               args = [].slice.call(arguments),
+                                               argsLength = args.length,
+                                               i,
+                                               propertyDescriptor;
+
+                                       newObject = args.shift();
+                                       override = true;
+                                       if (typeof arguments[argsLength - 1] === "boolean") {
+                                               override = arguments[argsLength - 1];
+                                               argsLength--;
+                                       }
+                                       for (i = 0; i < argsLength; i++) {
+                                               orgObject = args.shift();
+                                               if (orgObject !== null) {
+                                                       for (key in orgObject) {
+                                                               if (orgObject.hasOwnProperty(key)) {
+                                                                       propertyDescriptor = Object.getOwnPropertyDescriptor(newObject, key);
+                                                                       if (!propertyDescriptor ||
+                                                                               (override && (propertyDescriptor.writable === true || propertyDescriptor.set != undefined))) {
+                                                                               newObject[key] = orgObject[key];
+                                                                       } else if (override) {
+                                                                               console.warn("Attempt to override object readonly property (" + key + ") during merge.")
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       return newObject;
+                               },
+
+                               /**
+                                * Function add to Constructor prototype Base object and add to prototype properties and methods from
+                                * prototype object.
+                                * @method inherit
+                                * @param {Function} Constructor
+                                * @param {Function} Base
+                                * @param {Object} prototype
+                                * @static
+                                * @member ns.util.object
+                                */
+                               /* jshint -W083 */
+                               inherit: function (Constructor, Base, prototype) {
+                                       var basePrototype = new Base(),
+                                               property,
+                                               value;
+
+                                       for (property in prototype) {
+                                               if (prototype.hasOwnProperty(property)) {
+                                                       value = prototype[property];
+                                                       if (typeof value === "function") {
+                                                               basePrototype[property] = (function (Base, property, value) {
+                                                                       var _super = function () {
+                                                                               var superFunction = Base.prototype[property];
+
+                                                                               if (superFunction) {
+                                                                                       return superFunction.apply(this, arguments);
+                                                                               }
+                                                                               return null;
+                                                                       };
+
+                                                                       return function () {
+                                                                               var __super = this._super,
+                                                                                       returnValue;
+
+                                                                               this._super = _super;
+                                                                               returnValue = value.apply(this, arguments);
+                                                                               this._super = __super;
+                                                                               return returnValue;
+                                                                       };
+                                                               }(Base, property, value));
+                                                       } else {
+                                                               basePrototype[property] = value;
+                                                       }
+                                               }
+                                       }
+
+                                       Constructor.prototype = basePrototype;
+                                       Constructor.prototype.constructor = Constructor;
+                               },
+
+                               /**
+                                * Returns true if every property value corresponds value from 'value' argument
+                                * @method hasPropertiesOfValue
+                                * @param {Object} obj
+                                * @param {*} [value=undefined]
+                                * @return {boolean}
+                                */
+                               hasPropertiesOfValue: function (obj, value) {
+                                       var keys = Object.keys(obj),
+                                               i = keys.length;
+
+                                       // Empty array should return false
+                                       if (i === 0) {
+                                               return false;
+                                       }
+
+                                       while (--i >= 0) {
+                                               if (obj[keys[i]] !== value) {
+                                                       return false;
+                                               }
+                                       }
+
+                                       return true;
+                               },
+
+                               /**
+                                * Remove properties from object.
+                                * @method removeProperties
+                                * @param {Object} object
+                                * @param {Array} propertiesToRemove
+                                * @return {Object}
+                                */
+                               removeProperties: function (object, propertiesToRemove) {
+                                       var length = propertiesToRemove.length,
+                                               property,
+                                               i;
+
+                                       for (i = 0; i < length; i++) {
+                                               property = propertiesToRemove[i];
+                                               if (object.hasOwnProperty(property)) {
+                                                       delete object[property];
+                                               }
+                                       }
+                                       return object;
+                               }
+                       };
+
+                       ns.util.object = object;
+                       }());
+
+/*global window, define, ns, Node */
+/*jslint nomen: true, plusplus: true, bitwise: false */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (c) 2010 - 2014 Samsung Electronics Co., Ltd.
+ * License : MIT License V2
+ */
+/**
+ * #Engine
+ * Main class with engine of library which control communication
+ * between parts of framework.
+ * @class ns.engine
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Michal Szepielak <m.szepielak@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@partner.samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ * @author Przemyslaw Ciezkowski <p.ciezkowski@samsung.com>
+ * @author Hyunkook, Cho <hk0713.cho@samsung.com>
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ * @author Piotr Ostalski <p.ostalski@samsung.com>
+ */
+(function (window, document) {
+       "use strict";
+                               var slice = [].slice,
+                               /**
+                                * @property {Object} eventUtils {@link ns.event}
+                                * @private
+                                * @static
+                                * @member ns.engine
+                                */
+                               eventUtils = ns.event,
+                               util = ns.util,
+                               objectUtils = util.object,
+                               selectors = util.selectors,
+                               arrayUtils = ns.util.array,
+                               /**
+                                * @property {Object} widgetDefinitions Object with widgets definitions
+                                * @private
+                                * @static
+                                * @member ns.engine
+                                */
+                               widgetDefinitions = {},
+                               /**
+                                * @property {Object} widgetBindingMap Object with widgets bindings
+                                * @private
+                                * @static
+                                * @member ns.engine
+                                */
+                               widgetBindingMap = {},
+                               location = window.location,
+                               /**
+                                * engine mode, if true then engine only builds widgets
+                                * @property {boolean} justBuild
+                                * @private
+                                * @static
+                                * @member ns.engine
+                                */
+                               justBuild = location.hash === "#build",
+                               /**
+                                * @property {string} [TYPE_STRING="string"] local cache of string type name
+                                * @private
+                                * @static
+                                * @readonly
+                                * @member ns.engine
+                                */
+                               TYPE_STRING = "string",
+                               /**
+                                * @property {string} [TYPE_FUNCTION="function"] local cache of function type name
+                                * @private
+                                * @static
+                                * @readonly
+                                * @member ns.engine
+                                */
+                               TYPE_FUNCTION = "function",
+                               /**
+                                * @property {string} [DATA_BUILT="data-tau-built"] attribute informs that widget id build
+                                * @private
+                                * @static
+                                * @readonly
+                                * @member ns.engine
+                                */
+                               DATA_BUILT = "data-tau-built",
+                               /**
+                                * @property {string} [DATA_NAME="data-tau-name"] attribute contains widget name
+                                * @private
+                                * @static
+                                * @readonly
+                                * @member ns.engine
+                                */
+                               DATA_NAME = "data-tau-name",
+                               /**
+                                * @property {string} [DATA_BOUND="data-tau-bound"] attribute informs that widget id bound
+                                * @private
+                                * @static
+                                * @readonly
+                                * @member ns.engine
+                                */
+                               DATA_BOUND = "data-tau-bound",
+                               /**
+                                * @property {string} [DATA_WIDGET_WRAPPER="data-tau-wrapper"] attribute informs that widget has wrapper
+                                * @private
+                                * @static
+                                * @readonly
+                                * @member ns.engine
+                                */
+                               DATA_WIDGET_WRAPPER = "data-tau-wrapper",
+                               /**
+                                * @property {string} NAMES_SEPARATOR
+                                * @private
+                                * @static
+                                * @readonly
+                                */
+                               NAMES_SEPARATOR = ",",
+                               /**
+                                * @property {string} [querySelectorWidgets="*[data-tau-built][data-tau-name]:not([data-tau-bound])"] query selector for all widgets which are built but not bound
+                                * @private
+                                * @static
+                                * @member ns.engine
+                                */
+                               querySelectorWidgets = "*[" + DATA_BUILT + "][" + DATA_NAME + "]:not([" + DATA_BOUND + "])",
+                               /**
+                                * @method excludeBuildAndBound
+                                * @private
+                                * @static
+                                * @param {string} widgetType
+                                * @member ns.engine
+                                * @return {string} :not([data-tau-built*='widgetName']):not([data-tau-bound*='widgetName'])
+                                */
+                               excludeBuiltAndBound = function (widgetType) {
+                                       return ":not([" + DATA_BUILT + "*='" + widgetType + "']):not([" + DATA_BOUND + "*='" + widgetType + "'])";
+                               },
+
+                               /**
+                                * Engine event types
+                                * @property {Object} eventType
+                                * @property {string} eventType.INIT="tauinit" INIT of framework init event
+                                * @property {string} eventType.WIDGET_BOUND="widgetbound" WIDGET_BOUND of widget bound event
+                                * @property {string} eventType.WIDGET_DEFINED="widgetdefined" WIDGET_DEFINED of widget built event
+                                * @property {string} eventType.WIDGET_BUILT="widgetbuilt" WIDGET_BUILT of widget built event
+                                * @property {string} eventType.BOUND="bound" BOUND of bound event
+                                * @static
+                                * @readonly
+                                * @member ns.engine
+                                */
+                               eventType = {
+                                       INIT: "tauinit",
+                                       READY: "tauready",
+                                       WIDGET_BOUND: "widgetbound",
+                                       WIDGET_DEFINED: "widgetdefined",
+                                       WIDGET_BUILT: "widgetbuilt",
+                                       DESTROY: "taudestroy",
+                                       BOUND: "bound",
+                                       WIDGET_INIT: "init",
+                                       STOP_ROUTING: "tauroutingstop"
+                               },
+                               engine;
+
+                       /**
+                        * This function prepares selector for widget' definition
+                        * @method selectorChange
+                        * @param {string} selectorName
+                        * @return {string} new selector
+                        * @member ns.engine
+                        * @static
+                        */
+                       function selectorChange(selectorName) {
+                               if (selectorName.match(/\[data-role=/) && !selectorName.match(/:not\(\[data-role=/)) {
+                                       return selectorName.trim();
+                               }
+                               return selectorName.trim() + ":not([data-role='none'])";
+                       }
+
+                       /**
+                        * Function to define widget
+                        * @method defineWidget
+                        * @param {string} name
+                        * @param {string} selector
+                        * @param {Array} methods
+                        * @param {Object} widgetClass
+                        * @param {string} [namespace]
+                        * @param {boolean} [redefine]
+                        * @param {boolean} [widgetNameToLowercase=true]
+                        * @return {boolean}
+                        * @member ns.engine
+                        * @static
+                        */
+                       function defineWidget(name, selector, methods, widgetClass, namespace, redefine, widgetNameToLowercase, BaseElement, buildOptions) {
+                               var definition;
+                               // Widget name is absolutely required
+
+                               buildOptions = buildOptions || {};
+                               if (name) {
+                                       if (!widgetDefinitions[name] || redefine) {
+                                                                                               methods = methods || [];
+                                               methods.push("destroy", "disable", "enable", "option", "refresh", "value");
+                                               definition = {
+                                                       name: name,
+                                                       methods: methods,
+                                                       selector: selector || "",
+                                                       selectors: selector ? selector.split(",").map(selectorChange) : [],
+                                                       widgetClass: widgetClass || null,
+                                                       namespace: namespace || "",
+                                                       widgetNameToLowercase: widgetNameToLowercase === undefined ? true : !!widgetNameToLowercase,
+                                                       BaseElement: BaseElement,
+                                                       buildOptions: buildOptions
+                                               };
+
+                                               widgetDefinitions[name] = definition;
+                                               if (namespace) {
+                                                       widgetDefinitions[namespace + "." + name] = definition;
+                                               }
+                                               eventUtils.trigger(document, "widgetdefined", definition, false);
+                                               return true;
+                                       }
+                                                                       } else {
+                                       ns.error("Widget with selector [" + selector + "] defined without a name, aborting!");
+                               }
+                               return false;
+                       }
+
+
+                       /**
+                        * Get widget instance from binding for given element and type
+                        * @method getInstanceByElement
+                        * @static
+                        * @param {Object} binding
+                        * @param {HTMLElement} element
+                        * @param {string} [type] widget name, if is empty then return first built widget
+                        * @return {?Object}
+                        * @member ns.engine
+                        */
+                       function getInstanceByElement(binding, element, type) {
+                               var widgetInstance,
+                                       bindingElement,
+                                       storedWidgetNames,
+                                       names = type ? type.split(".") : [],
+                                       name = names.pop(),
+                                       namespace = names.pop();
+
+                               // If name is defined it's possible to fetch it instantly
+                               if (name) {
+                                       widgetInstance = binding.instances[name];
+                               } else {
+                                       storedWidgetNames = Object.keys(binding.instances);
+                                       widgetInstance = binding.instances[storedWidgetNames[0]];
+                               }
+
+                               if (namespace && widgetInstance && widgetInstance.namespace !== namespace) {
+                                       widgetInstance = null;
+                               }
+
+                               // Return only it instance of the proper widget exists
+                               if (widgetInstance) {
+                                       
+                                       // Check if widget instance has that same object referenced
+                                       if (widgetInstance.element === element) {
+                                               return widgetInstance;
+                                       }
+                               }
+
+                               return null;
+                       }
+
+                       /**
+                        * Filter children with DATA_BUILT attribute
+                        * @param {HTMLElement} child
+                        * @private
+                        */
+                       function filterBuiltWidget(child) {
+                               return child.hasAttribute(DATA_BUILT);
+                       }
+
+                       /**
+                        * Get binding for element
+                        * @method getBinding
+                        * @static
+                        * @param {HTMLElement|string} element
+                        * @param {string} [type] widget name
+                        * @return {?Object}
+                        * @member ns.engine
+                        */
+                       function getBinding(element, type) {
+                               var id = !element || typeof element === TYPE_STRING ? element : element.id,
+                                       binding,
+                                       baseElement;
+
+                               if (typeof element === TYPE_STRING) {
+                                       element = document.getElementById(id);
+                               }
+
+                               if (element) {
+                                       // Fetch group of widget defined for this element
+                                       binding = widgetBindingMap[id];
+
+                                       if (binding && typeof binding === "object") {
+                                               return getInstanceByElement(binding, element, type);
+                                       } else {
+                                               // Check if widget has wrapper and find base element
+                                               if (typeof element.hasAttribute === TYPE_FUNCTION &&
+                                                               element.hasAttribute(DATA_WIDGET_WRAPPER)) {
+                                                       baseElement = slice.call(element.children).filter(filterBuiltWidget)[0];
+                                                       if (baseElement) {
+                                                               return getBinding(baseElement, type);
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               return null;
+                       }
+
+                       /**
+                        * Set binding of widget
+                        * @method setBinding
+                        * @param {ns.widget.BaseWidget} widgetInstance
+                        * @static
+                        * @member ns.engine
+                        */
+                       function setBinding(widgetInstance) {
+                               var id = widgetInstance.element.id,
+                                       type = widgetInstance.name,
+                                       widgetBinding = widgetBindingMap[id];
+
+                               
+                               // If the HTMLElement never had a widget declared create an empty object
+                               if (!widgetBinding) {
+                                       widgetBinding = {
+                                               elementId: id,
+                                               element: widgetInstance.element,
+                                               instances: {}
+                                       };
+                               }
+
+                               widgetBinding.instances[type] = widgetInstance;
+                               widgetBindingMap[id] = widgetBinding;
+                       }
+
+                       /**
+                        * Returns all bindings for element or id gives as parameter
+                        * @method getAllBindings
+                        * @param {HTMLElement|string} element
+                        * @return {?Object}
+                        * @static
+                        * @member ns.engine
+                        */
+                       function getAllBindings(element) {
+                               var id = !element || typeof element === TYPE_STRING ? element : element.id;
+
+                               return (widgetBindingMap[id] && widgetBindingMap[id].instances) || null;
+                       }
+
+                       /**
+                        * Removes given name from attributeValue string.
+                        * Names should be separated with a NAMES_SEPARATOR
+                        * @param {string} name
+                        * @param {string} attributeValue
+                        * @private
+                        * @static
+                        * @return {string}
+                        */
+                       function _removeWidgetNameFromAttribute(name, attributeValue) {
+                               var widgetNames,
+                                       searchResultIndex;
+
+                               // Split attribute value by separator
+                               widgetNames = attributeValue.split(NAMES_SEPARATOR);
+                               searchResultIndex = widgetNames.indexOf(name);
+
+                               if (searchResultIndex > -1) {
+                                       widgetNames.splice(searchResultIndex, 1);
+                                       attributeValue = widgetNames.join(NAMES_SEPARATOR);
+                               }
+
+                               return attributeValue;
+                       }
+
+                       function _removeAllBindingAttributes(element) {
+                               element.removeAttribute(DATA_BUILT);
+                               element.removeAttribute(DATA_BOUND);
+                               element.removeAttribute(DATA_NAME);
+                       }
+
+                       /**
+                        * Remove binding data attributes for element.
+                        * @method _removeBindingAttributes
+                        * @param {HTMLElement} element
+                        * @param {string} type widget type (name)
+                        * @private
+                        * @static
+                        * @member ns.engine
+                        */
+                       function _removeWidgetFromAttributes(element, type) {
+                               var dataBuilt,
+                                       dataBound,
+                                       dataName;
+
+                               // Most often case is that name is not defined
+                               if (!type) {
+                                       _removeAllBindingAttributes(element);
+                               } else {
+                                       dataBuilt = _removeWidgetNameFromAttribute(type, element.getAttribute(DATA_BUILT) || "");
+                                       dataBound = _removeWidgetNameFromAttribute(type, element.getAttribute(DATA_BOUND) || "");
+                                       dataName = _removeWidgetNameFromAttribute(type, element.getAttribute(DATA_NAME) || "");
+
+                                       // Check if all attributes have at least one widget
+                                       if (dataBuilt && dataBound && dataName) {
+                                               element.setAttribute(DATA_BUILT, dataBuilt);
+                                               element.setAttribute(DATA_BOUND, dataBound);
+                                               element.setAttribute(DATA_NAME, dataName);
+                                       } else {
+                                               // If something is missing remove everything
+                                               _removeAllBindingAttributes(element);
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Method removes binding for single widget.
+                        * @method _removeSingleBinding
+                        * @param {Object} bindingGroup
+                        * @param {string} type
+                        * @return {boolean}
+                        * @private
+                        * @static
+                        */
+                       function _removeSingleBinding(bindingGroup, type) {
+                               var widgetInstance = bindingGroup[type];
+
+                               if (widgetInstance) {
+                                       if (widgetInstance.element && typeof widgetInstance.element.setAttribute === TYPE_FUNCTION) {
+                                               _removeWidgetFromAttributes(widgetInstance.element, type);
+                                       }
+
+                                       delete bindingGroup[type];
+
+                                       return true;
+                               }
+
+                               return false;
+                       }
+
+                       /**
+                        * Remove group of bindings for all types of widgets based on the same element
+                        * @method removeGroupBindingAllTypes
+                        * @param {Object} bindingGroup
+                        * @param {string} id widget element id
+                        * @return {boolean}
+                        * @static
+                        * @member ns.engine
+                        */
+                       function removeGroupBindingAllTypes(bindingGroup, id) {
+                               var singleSuccess,
+                                       widgetName,
+                                       fullSuccess = true;
+
+                               // Iterate over group of created widgets
+                               for (widgetName in bindingGroup) {
+                                       if (bindingGroup.hasOwnProperty(widgetName)) {
+                                               singleSuccess = _removeSingleBinding(bindingGroup, widgetName);
+                                               
+                                               // As we iterate over keys we are sure we want to remove this element
+                                               // NOTE: Removing property by delete is slower than assigning null value
+                                               bindingGroup[widgetName] = null;
+
+                                               fullSuccess = (fullSuccess && singleSuccess);
+                                       }
+                               }
+
+                               // If the object bindingGroup is empty or every key has a null value
+                               if (objectUtils.hasPropertiesOfValue(bindingGroup, null)) {
+                                       // NOTE: Removing property by delete is slower than assigning null value
+                                       widgetBindingMap[id] = null;
+                               }
+
+                               return fullSuccess;
+                       }
+
+                       /**
+                        * Remove group of bindings for widgets based on the same element
+                        * @method removeGroupBinding
+                        * @param {Object} bindingGroup
+                        * @param {string} type object name
+                        * @param {string} id widget element id
+                        * @return {boolean}
+                        * @static
+                        * @member ns.engine
+                        */
+                       function removeGroupBinding(bindingGroup, type, id) {
+                               var success;
+
+                               if (!type) {
+                                       success = removeGroupBindingAllTypes(bindingGroup, id);
+                               } else {
+                                       success = _removeSingleBinding(bindingGroup, type);
+                                       if (objectUtils.hasPropertiesOfValue(bindingGroup, null)) {
+                                               widgetBindingMap[id] = null;
+                                       }
+                               }
+                               return success;
+                       }
+
+                       /**
+                        * Remove binding for widget based on element.
+                        * @method removeBinding
+                        * @param {HTMLElement|string} element
+                        * @param {?string} [type=null] widget name
+                        * @return {boolean}
+                        * @static
+                        * @member ns.engine
+                        */
+                       function removeBinding(element, type) {
+                               var id = (typeof element === TYPE_STRING) ? element : element.id,
+                                       binding = widgetBindingMap[id],
+                                       bindingGroup;
+
+                               // [NOTICE] Due to backward compatibility calling removeBinding
+                               // with one parameter should remove all bindings
+
+                               if (binding) {
+                                       if (typeof element === TYPE_STRING) {
+                                               // Search based on current document may return bad results,
+                                               // use previously defined element if it exists
+                                               element = binding.element;
+                                       }
+
+                                       if (element) {
+                                               _removeWidgetFromAttributes(element, type);
+                                       }
+
+                                       bindingGroup = widgetBindingMap[id] && widgetBindingMap[id].instances;
+                                       if (bindingGroup) {
+                                               return removeGroupBinding(bindingGroup, type, id);
+                                       }
+
+                                       if (widgetBindingMap[id].instances && (Object.keys(widgetBindingMap[id].instances).length === 0)) {
+                                               widgetBindingMap[id] = null;
+                                       }
+                               }
+
+                               return false;
+                       }
+
+                       /**
+                        * Removes all bindings of widgets.
+                        * @method removeAllBindings
+                        * @param {HTMLElement|string} element
+                        * @return {boolean}
+                        * @static
+                        * @member ns.engine
+                        */
+                       function removeAllBindings(element) {
+                               // @TODO this should be coded in the other way around, removeAll should loop through all bindings and inside call removeBinding
+                               // but due to backward compatibility that code should be more readable
+                               return removeBinding(element);
+                       }
+
+                       /**
+                        * If element not exist create base element for widget.
+                        * @method ensureElement
+                        * @param {HTMLElement} element
+                        * @param {ns.widget.BaseWidget} Widget
+                        * @return {HTMLElement}
+                        * @static
+                        * @private
+                        * @member ns.engine
+                        */
+                       function ensureElement(element, Widget) {
+                               if (!element || !(element instanceof HTMLElement)) {
+                                       if (typeof Widget.createEmptyElement === TYPE_FUNCTION) {
+                                               element = Widget.createEmptyElement();
+                                       } else {
+                                               element = document.createElement("div");
+                                       }
+                               }
+                               return element;
+                       }
+
+                       /**
+                        * Process core widget method
+                        * - configure
+                        * - build
+                        * - init
+                        * - bindEvents
+                        * @method processWidget
+                        * @param {HTMLElement} element base element of widget
+                        * @param {Object} widgetInstance instance of widget
+                        * @param {Object} definition definition of widget
+                        * @param {ns.widget.BaseWidget} definition.widgetClass
+                        * @param {string} definition.name
+                        * @param {Object} [options] options for widget
+                        * @private
+                        * @static
+                        * @member ns.engine
+                        */
+                       function coreProcessWidget(element, widgetInstance, definition, options) {
+                               var widgetOptions = options || {},
+                                       createFunction = widgetOptions.create,
+                                       buildAttribute;
+
+                               
+                               element = widgetInstance.configure(definition, element, options);
+
+                               // Run .create method from widget options when a [widgetName]create event is triggered
+                               if (typeof createFunction === TYPE_FUNCTION) {
+                                       eventUtils.one(element, definition.name.toLowerCase() + "create", createFunction);
+                               }
+
+                               if (element.id) {
+                                       widgetInstance.id = element.id;
+                               }
+
+                               // Check if this type of widget was build for this element before
+                               buildAttribute = element.getAttribute(DATA_BUILT);
+                               if (!buildAttribute ||
+                                       buildAttribute.split(NAMES_SEPARATOR).indexOf(widgetInstance.name) === -1) {
+                                       element = widgetInstance.build(element);
+                               }
+
+                               if (element) {
+                                       widgetInstance.element = element;
+
+                                       setBinding(widgetInstance);
+
+                                       widgetInstance.trigger(eventType.WIDGET_BUILT, widgetInstance, false);
+
+                                       if (!justBuild) {
+                                               widgetInstance.init(element);
+                                       }
+
+                                       widgetInstance.bindEvents(element, justBuild);
+
+                                       widgetInstance.trigger(widgetInstance.widgetEventPrefix + eventType.WIDGET_INIT);
+                                       widgetInstance.trigger(eventType.WIDGET_BOUND, widgetInstance, false);
+                                       eventUtils.trigger(document, eventType.WIDGET_BOUND, widgetInstance);
+                               } else {
+                                                                       }
+                       }
+
+                       /**
+                        * Load widget
+                        * @method processWidget
+                        * @param {HTMLElement} element base element of widget
+                        * @param {Object} definition definition of widget
+                        * @param {ns.widget.BaseWidget} definition.widgetClass
+                        * @param {string} definition.name
+                        * @param {Object} [options] options for widget
+                        * @return {?HTMLElement}
+                        * @private
+                        * @static
+                        * @member ns.engine
+                        */
+                       function processWidget(element, definition, options) {
+                               var Widget = definition.widgetClass,
+                                       /**
+                                        * @type {ns.widget.BaseWidget} widgetInstance
+                                        */
+                                       widgetInstance,
+                                       parentEnhance,
+                                       existingBinding;
+
+                               element = ensureElement(element, Widget);
+                               widgetInstance = Widget ? new Widget(element, options) : false;
+
+                               // if any parent has attribute data-enhance=false then stop building widgets
+                               parentEnhance = selectors.getParentsBySelectorNS(element, "enhance=false");
+
+                               // While processing widgets queue other widget may built this one before
+                               // it reaches it's turn
+                               existingBinding = getBinding(element, definition.name);
+                               if (existingBinding && existingBinding.element === element) {
+                                       return element;
+                               }
+
+                               if (widgetInstance) {
+                                       if (!parentEnhance.length) {
+                                               coreProcessWidget(element, widgetInstance, definition, options);
+                                       }
+                                       return widgetInstance.element;
+                               }
+
+                               return null;
+                       }
+
+                       /**
+                        * Destroys widget of given 'type' for given HTMLElement.
+                        * [NOTICE] This method won't destroy any children widgets.
+                        * @method destroyWidget
+                        * @param {HTMLElement|string} element
+                        * @param {string} type
+                        * @static
+                        * @member ns.engine
+                        */
+                       function destroyWidget(element, type) {
+                               var widgetInstance;
+
+                               if (typeof element === TYPE_STRING) {
+                                       element = document.getElementById(element);
+                               }
+
+                               // If type is not defined all widgets should be removed
+                               // this is for backward compatibility
+                               widgetInstance = getBinding(element, type);
+
+                               if (widgetInstance) {
+                                       //Destroy widget
+                                       widgetInstance.destroy();
+                                       widgetInstance.trigger("widgetdestroyed");
+
+                                       removeBinding(element, type);
+                               }
+                       }
+
+                       /**
+                        * Calls destroy on group of widgets connected with given HTMLElement
+                        * @method destroyGroupWidgets
+                        * @param {HTMLElement|string} element
+                        * @static
+                        * @private
+                        * @member ns.engine
+                        */
+                       function destroyGroupWidgets(element) {
+                               var widgetName,
+                                       widgetInstance,
+                                       widgetGroup;
+
+                               widgetGroup = getAllBindings(element);
+                               for (widgetName in widgetGroup) {
+                                       if (widgetGroup.hasOwnProperty(widgetName)) {
+                                               widgetInstance = widgetGroup[widgetName];
+
+                                               //Destroy widget
+                                               if (widgetInstance) {
+                                                       widgetInstance.destroy();
+                                                       widgetInstance.trigger("widgetdestroyed");
+                                               }
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Calls destroy on widget (or widgets) connected with given HTMLElement
+                        * Removes child widgets as well.
+                        * @method destroyAllWidgets
+                        * @param {HTMLElement|string} element
+                        * @param {boolean} [childOnly=false] destroy only widgets on children elements
+                        * @static
+                        * @member ns.engine
+                        */
+                       function destroyAllWidgets(element, childOnly) {
+                               var childWidgets,
+                                       i;
+
+                               if (typeof element === TYPE_STRING) {
+                                       element = document.getElementById(element);
+                               }
+
+                               if (!childOnly) {
+                                       // If type is not defined all widgets should be removed
+                                       // this is for backward compatibility
+                                       destroyGroupWidgets(element);
+                               }
+
+                               //Destroy child widgets, if something left.
+                               childWidgets = slice.call(element.querySelectorAll("[" + DATA_BOUND + "]"));
+                               for (i = childWidgets.length - 1; i >= 0; i -= 1) {
+                                       if (childWidgets[i]) {
+                                               destroyAllWidgets(childWidgets[i], false);
+                                       }
+                               }
+
+                               removeAllBindings(element);
+                       }
+
+                       /**
+                        * Load widgets from data-* definition
+                        * @method processHollowWidget
+                        * @param {HTMLElement} element base element of widget
+                        * @param {Object} definition widget definition
+                        * @param {Object} [options] options for create widget
+                        * @return {HTMLElement} base element of widget
+                        * @private
+                        * @static
+                        * @member ns.engine
+                        */
+                       function processHollowWidget(element, definition, options) {
+                               var name = (element && element.getAttribute(DATA_NAME)) ||
+                                       (definition && definition.name);
+                                                               definition = definition || (name && widgetDefinitions[name]) || {
+                                       "name": name
+                               };
+                               return processWidget(element, definition, options);
+                       }
+
+                       /**
+                        * Compare function for nodes on build queue
+                        * @param {Object} nodeA
+                        * @param {Object} nodeB
+                        * @return {number}
+                        * @private
+                        * @static
+                        */
+                       function compareByDepth(nodeA, nodeB) {
+                               /*jshint -W016 */
+                               var mask = Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_PRECEDING;
+
+                               if (nodeA.element === nodeB.element) {
+                                       return 0;
+                               }
+
+                               if (nodeA.element.compareDocumentPosition(nodeB.element) & mask) {
+                                       return 1;
+                               }
+                               /*jshint +W016 */
+                               return -1;
+                       }
+
+                       /**
+                        * Processes one build queue item. Runs processHollowWidget
+                        * underneath
+                        * @method processBuildQueueItem
+                        * @param {Object|HTMLElement} queueItem
+                        * @private
+                        * @static
+                        */
+                       function processBuildQueueItem(queueItem) {
+                               // HTMLElement doesn't have .element property
+                               // widgetDefinitions will return undefined when called widgetDefinitions[undefined]
+                               processHollowWidget(queueItem.element || queueItem, widgetDefinitions[queueItem.widgetName]);
+                       }
+
+                       function boundPerfListener() {
+                               document.removeEventListener(eventType.BOUND, boundPerfListener);
+                               window.tauPerf.get("engine/createWidgets", "event: " + eventType.BOUND);
+                       }
+
+                       function builtPerfListener() {
+                               document.removeEventListener("built", builtPerfListener);
+                               window.tauPerf.get("engine/createWidgets", "event: built");
+                       }
+
+                       /**
+                        * Build widgets on all children of context element
+                        * @method createWidgets
+                        * @static
+                        * @param {HTMLElement} context base html for create children
+                        * @member ns.engine
+                        */
+                       function createWidgets(context) {
+                               // find widget which are built
+                               var builtWidgetElements = slice.call(context.querySelectorAll(querySelectorWidgets)),
+                                       normal,
+                                       buildQueue = [],
+                                       selectorKeys = Object.keys(widgetDefinitions),
+                                       excludeSelector,
+                                       i,
+                                       j,
+                                       len = selectorKeys.length,
+                                       definition,
+                                       widgetName,
+                                       definitionSelectors;
+
+                               
+                               
+                               // process built widgets
+                               builtWidgetElements.forEach(processBuildQueueItem);
+
+                               // process widgets didn't build
+                               for (i = 0; i < len; ++i) {
+                                       widgetName = selectorKeys[i];
+                                       if (widgetName.indexOf(".") === -1) {
+                                               definition = widgetDefinitions[widgetName];
+                                               definitionSelectors = definition.selectors;
+                                               if (definitionSelectors.length) {
+                                                       excludeSelector = excludeBuiltAndBound(widgetName);
+
+                                                       normal = slice.call(context.querySelectorAll(definitionSelectors.join(excludeSelector + ",") +
+                                                       excludeSelector));
+                                                       j = normal.length;
+
+                                                       while (--j >= 0) {
+                                                               buildQueue.push({
+                                                                       element: normal[j],
+                                                                       widgetName: widgetName
+                                                               });
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // Sort queue by depth, on every DOM branch outer most element go first
+                               buildQueue.sort(compareByDepth);
+
+                               // Build all widgets from queue
+                               buildQueue.forEach(processBuildQueueItem);
+
+                               
+                               eventUtils.trigger(document, "built");
+                               eventUtils.trigger(document, eventType.BOUND);
+                                                       }
+
+                       /**
+                        * Handler for event create
+                        * @method createEventHandler
+                        * @param {Event} event
+                        * @static
+                        * @member ns.engine
+                        */
+                       function createEventHandler(event) {
+                               createWidgets(event.target);
+                       }
+
+                       function setViewport() {
+                               /**
+                                * Sets viewport tag if not exists
+                                */
+                               var documentHead = document.head,
+                                       metaTagListLength,
+                                       metaTagList,
+                                       metaTag,
+                                       i;
+
+                               metaTagList = documentHead.querySelectorAll("[name=\"viewport\"]");
+                               metaTagListLength = metaTagList.length;
+
+                               if (metaTagListLength > 0) {
+                                       // Leave the last viewport tag
+                                       --metaTagListLength;
+
+                                       // Remove duplicated tags
+                                       for (i = 0; i < metaTagListLength; ++i) {
+                                               // Remove meta tag from DOM
+                                               documentHead.removeChild(metaTagList[i]);
+                                       }
+                               } else {
+                                       // Create new HTML Element
+                                       metaTag = document.createElement("meta");
+
+                                       // Set required attributes
+                                       metaTag.setAttribute("name", "viewport");
+                                       metaTag.setAttribute("content", "width=device-width, user-scalable=no");
+
+                                       // Force that viewport tag will be first child of head
+                                       if (documentHead.firstChild) {
+                                               documentHead.insertBefore(metaTag, documentHead.firstChild);
+                                       } else {
+                                               documentHead.appendChild(metaTag);
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Build first page
+                        * @method build
+                        * @static
+                        * @member ns.engine
+                        */
+                       function build() {
+                               eventUtils.trigger(document, eventType.READY);
+                               setViewport();
+                       }
+
+                       /**
+                        * Method to remove all listeners bound in run
+                        * @method stop
+                        * @static
+                        * @member ns.engine
+                        */
+                       function stop() {
+                               eventUtils.trigger(document, eventType.STOP_ROUTING);
+                       }
+
+                       /**
+                        * Method to remove all listeners bound in run
+                        * @method destroy
+                        * @static
+                        * @member ns.engine
+                        */
+                       function destroy() {
+                               stop();
+                               eventUtils.fastOff(document, "create", createEventHandler);
+                               destroyAllWidgets(document, true);
+                               eventUtils.trigger(document, eventType.DESTROY);
+                       }
+
+                       /**
+                        * Add to object value at index equal to type of arg.
+                        * @method getType
+                        * @param {Object} result
+                        * @param {*} arg
+                        * @return {Object}
+                        * @static
+                        * @private
+                        * @member ns.engine
+                        */
+                       function getType(result, arg) {
+                               var type = arg instanceof HTMLElement ? "HTMLElement" : typeof arg;
+
+                               result[type] = arg;
+                               return result;
+                       }
+
+                       /**
+                        * Convert args array to object with keys being types and arguments mapped by values
+                        * @method getArgumentsTypes
+                        * @param {Arguments[]} args
+                        * @return {Object}
+                        * @static
+                        * @private
+                        * @member ns.engine
+                        */
+                       function getArgumentsTypes(args) {
+                               return arrayUtils.reduce(args, getType, {});
+                       }
+
+                       ns.widgetDefinitions = {};
+                       engine = {
+                               justBuild: location.hash === "#build",
+                               /**
+                                * object with names of engine attributes
+                                * @property {Object} dataTau
+                                * @property {string} [dataTau.built="data-tau-built"] attribute inform that widget id build
+                                * @property {string} [dataTau.name="data-tau-name"] attribute contains widget name
+                                * @property {string} [dataTau.bound="data-tau-bound"] attribute inform that widget id bound
+                                * @property {string} [dataTau.separator=","] separation string for widget names
+                                * @static
+                                * @member ns.engine
+                                */
+                               dataTau: {
+                                       built: DATA_BUILT,
+                                       name: DATA_NAME,
+                                       bound: DATA_BOUND,
+                                       separator: NAMES_SEPARATOR,
+                                       widgetWrapper: DATA_WIDGET_WRAPPER
+                               },
+                               destroyWidget: destroyWidget,
+                               destroyAllWidgets: destroyAllWidgets,
+                               createWidgets: createWidgets,
+
+                               /**
+                                * Method to get all definitions of widgets
+                                * @method getDefinitions
+                                * @return {Object}
+                                * @static
+                                * @member ns.engine
+                                */
+                               getDefinitions: function () {
+                                       return widgetDefinitions;
+                               },
+                               /**
+                                * Returns definition of widget
+                                * @method getWidgetDefinition
+                                * @param {string} name
+                                * @static
+                                * @member ns.engine
+                                * @return {Object}
+                                */
+                               getWidgetDefinition: function (name) {
+                                       return widgetDefinitions[name];
+                               },
+                               defineWidget: defineWidget,
+                               getBinding: getBinding,
+                               getAllBindings: getAllBindings,
+                               setBinding: setBinding,
+                               removeBinding: removeBinding,
+                               removeAllBindings: removeAllBindings,
+
+                               /**
+                                * Clear bindings of widgets
+                                * @method _clearBindings
+                                * @static
+                                * @member ns.engine
+                                */
+                               _clearBindings: function () {
+                                       //clear and set references to the same object
+                                       widgetBindingMap = {};
+                               },
+
+                               build: build,
+
+                               /**
+                                * Run engine
+                                * @method run
+                                * @static
+                                * @member ns.engine
+                                */
+                               run: function () {
+                                                                               // stop the TAU process if exists before
+                                       stop();
+
+                                       eventUtils.fastOn(document, "create", createEventHandler);
+
+                                       eventUtils.trigger(document, eventType.INIT, {tau: ns});
+
+                                       switch (document.readyState) {
+                                               case "interactive":
+                                               case "complete":
+                                                       // build widgets and initiate router
+                                                       build();
+                                                       break;
+                                               default:
+                                                       // build widgets and initiate router
+                                                       eventUtils.one(document, "DOMContentLoaded", build.bind(engine));
+                                                       break;
+                                       }
+                               },
+
+                               /**
+                                * Build instance of widget and binding events
+                                * Returns error when empty element is passed
+                                * @method instanceWidget
+                                * @param {HTMLElement|string} [element]
+                                * @param {string} name
+                                * @param {Object} [options]
+                                * @return {?Object}
+                                * @static
+                                * @member ns.engine
+                                */
+                               instanceWidget: function (element, name, options) {
+                                       var binding,
+                                               definition,
+                                               argumentsTypes = getArgumentsTypes(arguments);
+
+                                       // Map arguments with specific types to correct variables
+                                       // Only name is required argument
+                                       element = argumentsTypes.HTMLElement;
+                                       name = argumentsTypes.string;
+                                       options = argumentsTypes.object;
+                                       // If element exists try to find existing binding
+                                       if (element) {
+                                               binding = getBinding(element, name);
+                                       }
+                                       // If didn't found binding build new widget
+                                       if (!binding && widgetDefinitions[name]) {
+                                               definition = widgetDefinitions[name];
+                                               if (definition.buildOptions.requireMatchSelector &&
+                                                       !ns.util.selectors.matchesSelector(element, definition.selector)) {
+                                                       return null;
+                                               }
+                                               element = processHollowWidget(element, definition, options);
+                                               binding = getBinding(element, name);
+                                       } else if (binding) {
+                                               // if widget was built early we should set options delivered to constructor
+                                               binding.option(options);
+                                       }
+                                       return binding;
+                               },
+
+                               stop: stop,
+
+                               destroy: destroy,
+
+                               /**
+                                * Method to change build mode
+                                * @method setJustBuild
+                                * @param {boolean} newJustBuild
+                                * @static
+                                * @member ns.engine
+                                */
+                               setJustBuild: function (newJustBuild) {
+                                       // Set location hash to have a consistent behavior
+                                       if (newJustBuild) {
+                                               location.hash = "build";
+                                       } else {
+                                               location.hash = "";
+                                       }
+
+                                       justBuild = newJustBuild;
+                               },
+
+                               /**
+                                * Method to get build mode
+                                * @method getJustBuild
+                                * @return {boolean}
+                                * @static
+                                * @member ns.engine
+                                */
+                               getJustBuild: function () {
+                                       return justBuild;
+                               },
+                               _createEventHandler: createEventHandler
+                       };
+
+                       engine.eventType = eventType;
+                       ns.engine = engine;
+                       }(window, window.document));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #jQuery Mobile mapping namespace
+ * Object maps all methods enabling jQuery Mobile API.
+ * @class ns.jqm
+ */
+(function (ns, window) {
+       "use strict";
+                               var eventType = ns.engine.eventType;
+
+                       ns.jqm = {
+                               /**
+                                * jQuery object
+                                * @property {Object} jQuery
+                                * @member ns.jqm
+                                */
+                               jQuery: ns.getConfig("jQuery") || window.jQuery
+                       };
+
+                       /**
+                        * Initialize framework in the same way as it is done in jQueryMobile
+                        */
+                       function init() {
+                               // Tell the world that JQM is ready to serve Tau
+                               ns.event.trigger(document, "mobileinit");
+                       }
+
+                       /**
+                        * Removes events listeners on framework destroy.
+                        */
+                       function destroy() {
+                               document.removeEventListener(eventType.INIT, init, false);
+                               document.removeEventListener(eventType.DESTROY, destroy, false);
+                       }
+
+                       document.addEventListener(eventType.INIT, init, false);
+                       document.addEventListener(eventType.DESTROY, destroy, false);
+
+                       }(ns, window));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, ns, define */
+/**
+ * #jQuery Mobile mapping defaults
+ * Object maps default values from TAU namespace to jQuery Mobile namespace.
+ * @class ns.jqm.defaults
+ */
+(function (window, document) {
+       "use strict";
+                               var engineEventsType = ns.engine.eventType,
+                               $ = ns.jqm.jQuery,
+                               eventType = {
+                                       INIT: engineEventsType.INIT,
+                                       DESTROY: engineEventsType.DESTROY
+                               },
+                               defaults = {
+                                       /**
+                                        * Proxy colors library from ns namespace to jQM namespace
+                                        * @method init
+                                        * @member ns.jqm.defaults
+                                        * @static
+                                        */
+                                       init: function () {
+                                               if ($) {
+
+                                                       $.mobile = $.mobile || {};
+                                                       // Version of the jQuery Mobile Framework
+                                                       //$.mobile.version: __version__;
+
+                                                       // Namespace used framework-wide for data-attrs. Default is no namespace
+                                                       $.mobile.ns = "";
+
+                                                       // Define the url parameter used for referencing widget-generated sub-pages.
+                                                       // Translates to to example.html&ui-page=subpageIdentifier
+                                                       // hash segment before &ui-page= is used to make Ajax request
+                                                       $.mobile.subPageUrlKey = "ui-page";
+
+                                                       // Class assigned to page currently in view; and during transitions
+                                                       $.mobile.activePageClass = "ui-page-active";
+
+                                                       // Class used for "active" button state; from CSS framework
+                                                       $.mobile.activeBtnClass = "ui-btn-active";
+
+                                                       // Class used for "focus" form element state; from CSS framework
+                                                       $.mobile.focusClass = "ui-focus";
+
+                                                       // Automatically handle clicks and form submissions through Ajax; when same-domain
+                                                       $.mobile.ajaxEnabled = true;
+
+                                                       // Automatically load and show pages based on location.hash
+                                                       $.mobile.hashListeningEnabled = true;
+
+                                                       // disable to prevent jquery from bothering with links
+                                                       $.mobile.linkBindingEnabled = true;
+
+                                                       // Set default page transition - 'none' for no transitions
+                                                       $.mobile.defaultPageTransition = "fade";
+
+                                                       // Set maximum window width for transitions to apply - 'false' for no limit
+                                                       $.mobile.maxTransitionWidth = false;
+
+                                                       // Minimum scroll distance that will be remembered when returning to a page
+                                                       $.mobile.minScrollBack = 250;
+
+                                                       // DEPRECATED = the following property is no longer in use; but defined until 2.0 to prevent conflicts
+                                                       $.mobile.touchOverflowEnabled = false;
+
+                                                       // Set default dialog transition - 'none' for no transitions
+                                                       $.mobile.defaultDialogTransition = "pop";
+
+                                                       // Error response message - appears when an Ajax page request fails
+                                                       $.mobile.pageLoadErrorMessage = "Error Loading Page";
+
+                                                       // replace calls to window.history.back with phonegaps navigation helper
+                                                       // where it is provided on the window object
+                                                       $.mobile.phonegapNavigationEnabled = false;
+
+                                                       //automatically initialize the DOM when it's ready
+                                                       $.mobile.autoInitializePage = true;
+
+                                                       $.mobile.pushStateEnabled = true;
+
+                                                       // allows users to opt in to ignoring content by marking a parent element as
+                                                       // data-ignored
+                                                       $.mobile.ignoreContentEnabled = false;
+
+                                                       // turn of binding to the native orientationchange due to android orientation behavior
+                                                       $.mobile.orientationChangeEnabled = true;
+
+                                                       $.mobile.tizen = $.mobile.tizen || {};
+                                                       $.mobile.tizen.enableHWKeyHandler = true;
+                                               }
+                                       },
+                                       destroy: function () {
+                                               document.removeEventListener(eventType.INIT, defaults.init, false);
+                                               document.removeEventListener(eventType.DESTROY, defaults.destroy, false);
+                                               $ = null;
+                                       }
+                               };
+
+                       // Listen when framework is ready
+                       document.addEventListener(eventType.INIT, defaults.init, false);
+                       document.addEventListener(eventType.DESTROY, defaults.destroy, false);
+
+                       }(window, window.document));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global define, ns */
+/**
+ * #String Utility
+ * Utility helps work with strings.
+ * @class ns.util.string
+ */
+(function () {
+       "use strict";
+                               var DASH_TO_UPPER_CASE_REGEXP = /-([a-z])/gi,
+                               UPPER_TO_DASH_CASE_REGEXP = /([A-Z])/g,
+                               arrayUtil = ns.util.array;
+
+                       /**
+                        * Callback method for regexp used in dashesToCamelCase method
+                        * @method toUpperCaseFn
+                        * @param {string} match
+                        * @param {string} value
+                        * @return {string}
+                        * @member ns.util.string
+                        * @static
+                        * @private
+                        */
+                       function toUpperCaseFn(match, value) {
+                               return value.toLocaleUpperCase();
+                       }
+
+                       /**
+                        * Callback method for regexp used in camelCaseToDashes method
+                        * @method toUpperCaseFn
+                        * @param {string} match
+                        * @param {string} value
+                        * @return {string}
+                        * @member ns.util.string
+                        * @static
+                        * @private
+                        */
+                       function toLowerCaseFn(match, value) {
+                               return "-" + value.toLowerCase();
+                       }
+
+                       /**
+                        * Changes dashes string to camel case string
+                        * @method firstToUpperCase
+                        * @param {string} str
+                        * @return {string}
+                        * @member ns.util.string
+                        * @static
+                        */
+                       function dashesToCamelCase(str) {
+                               return str.replace(DASH_TO_UPPER_CASE_REGEXP, toUpperCaseFn);
+                       }
+
+                       /**
+                        * Changes camel case string to dashes string
+                        * @method camelCaseToDashes
+                        * @param {string} str
+                        * @return {string}
+                        * @member ns.util.string
+                        * @static
+                        */
+                       function camelCaseToDashes(str) {
+                               return str.replace(UPPER_TO_DASH_CASE_REGEXP, toLowerCaseFn);
+                       }
+
+                       /**
+                        * Changes the first char in string to uppercase
+                        * @method firstToUpperCase
+                        * @param {string} str
+                        * @return {string}
+                        * @member ns.util.string
+                        * @static
+                        */
+                       function firstToUpperCase(str) {
+                               return str.charAt(0).toLocaleUpperCase() + str.substring(1);
+                       }
+
+                       /**
+                        * Map different types to number if is possible.
+                        * @param {string|*} x
+                        * @return {*}
+                        */
+                       function mapToNumber(x) {
+                               var parsed;
+
+                               if (x && (x + "").indexOf("%") === -1) {
+                                       parsed = parseInt(x, 10);
+                                       if (isNaN(parsed)) {
+                                               parsed = null;
+                                       }
+                                       return parsed;
+                               }
+                               return x;
+                       }
+
+                       /**
+                        * Parses comma separated string to array
+                        * @method parseProperty
+                        * @param {string} property
+                        * @return {Array} containing number or null
+                        * @member ns.util.string
+                        * @static
+                        */
+                       function parseProperty(property) {
+                               var arrayProperty;
+
+                               if (typeof property === "string") {
+                                       arrayProperty = property.split(",");
+                               } else {
+                                       arrayProperty = property || [];
+                               }
+
+                               return arrayUtil.map(arrayProperty, mapToNumber);
+                       }
+
+                       /* eslint-disable jsdoc/check-param-names */
+                       /**
+                        * Returns a string of tags that exist in the first param but do not exist
+                        * in rest of the params
+                        * @param {string} baseWithTags
+                        * @param {...string} compare
+                        * @return {string}
+                        */
+                       function removeExactTags(baseWithTags) {
+                               var tags = [];
+
+                               [].slice
+                                       .call(arguments)
+                                       .slice(1)
+                                       .forEach(function (arg) {
+                                               arg.split(" ")
+                                                       .forEach(function (tag) {
+                                                               tags.push(tag.trim());
+                                                       });
+                                       });
+
+                               return baseWithTags
+                                       .split(" ")
+                                       .filter(function (tag) {
+                                               return tags.indexOf(tag) === -1;
+                                       }).join(" ");
+                       }
+                       /* eslint-enable jsdoc/check-param-names */
+
+                       ns.util.string = {
+                               dashesToCamelCase: dashesToCamelCase,
+                               camelCaseToDashes: camelCaseToDashes,
+                               firstToUpperCase: firstToUpperCase,
+                               parseProperty: parseProperty,
+                               removeExactTags: removeExactTags
+                       };
+                       }());
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, define, ns */
+/**
+ * #Utility DOM
+ * Utility object with function to DOM manipulation, CSS properties support
+ * and DOM attributes support.
+ *
+ * # How to replace jQuery methods  by ns methods
+ * ## append vs appendNodes
+ *
+ * #### HTML code before manipulation
+ *
+ *     @example
+ *     <div>
+ *         <div id="first">Hello</div>
+ *         <div id="second">And</div>
+ *         <div id="third">Goodbye</div>
+ *     </div>
+ *
+ * #### jQuery manipulation
+ *
+ *     @example
+ *     $( "#second" ).append( "<span>Test</span>" );
+
+ * #### ns manipulation
+ *
+ *     @example
+ *     var context = document.getElementById("second"),
+ *         element = document.createElement("span");
+ *     element.innerHTML = "Test";
+ *     ns.util.DOM.appendNodes(context, element);
+ *
+ * #### HTML code after manipulation
+ *
+ *     @example
+ *     <div>
+ *         <div id="first">Hello</div>
+ *         <div id="second">And
+ *             <span>Test</span>
+ *         </div>
+ *        <div id="third">Goodbye</div>
+ *     </div>
+ *
+ * ## replaceWith vs replaceWithNodes
+ *
+ * #### HTML code before manipulation
+ *
+ *     @example
+ *     <div>
+ *         <div id="first">Hello</div>
+ *         <div id="second">And</div>
+ *         <div id="third">Goodbye</div>
+ *     </div>
+ *
+ * #### jQuery manipulation
+ *
+ *     @example
+ *     $('#second').replaceWith("<span>Test</span>");
+ *
+ * #### ns manipulation
+ *
+ *     @example
+ *     var context = document.getElementById("second"),
+ *         element = document.createElement("span");
+ *     element.innerHTML = "Test";
+ *     ns.util.DOM.replaceWithNodes(context, element);
+ *
+ * #### HTML code after manipulation
+ *
+ *     @example
+ *     <div>
+ *         <div id="first">Hello</div>
+ *         <span>Test</span>
+ *         <div id="third">Goodbye</div>
+ *     </div>
+ *
+ * ## before vs insertNodesBefore
+ *
+ * #### HTML code before manipulation
+ *
+ *     @example
+ *     <div>
+ *         <div id="first">Hello</div>
+ *         <div id="second">And</div>
+ *         <div id="third">Goodbye</div>
+ *     </div>
+ *
+ * #### jQuery manipulation
+ *
+ *     @example
+ *     $( "#second" ).before( "<span>Test</span>" );
+ *
+ * #### ns manipulation
+ *
+ *     @example
+ *     var context = document.getElementById("second"),
+ *         element = document.createElement("span");
+ *     element.innerHTML = "Test";
+ *     ns.util.DOM.insertNodesBefore(context, element);
+ *
+ * #### HTML code after manipulation
+ *
+ *     @example
+ *     <div>
+ *         <div id="first">Hello</div>
+ *         <span>Test</span>
+ *         <div id="second">And</div>
+ *         <div id="third">Goodbye</div>
+ *     </div>
+ *
+ * ## wrapInner vs wrapInHTML
+ *
+ * #### HTML code before manipulation
+ *
+ *     @example
+ *     <div>
+ *         <div id="first">Hello</div>
+ *         <div id="second">And</div>
+ *         <div id="third">Goodbye</div>
+ *     </div>
+ *
+ * #### jQuery manipulation
+ *
+ *     @example
+ *     $( "#second" ).wrapInner( "<span class="new"></span>" );
+ *
+ * #### ns manipulation
+ *
+ *     @example
+ *     var element = document.getElementById("second");
+ *     ns.util.DOM.wrapInHTML(element, "<span class="new"></span>");
+ *
+ * #### HTML code after manipulation
+ *
+ *     @example
+ *     <div>
+ *         <div id="first">Hello</div>
+ *         <div id="second">
+ *             <span class="new">And</span>
+ *         </div>
+ *         <div id="third">Goodbye</div>
+ *     </div>
+ *
+ * @class ns.util.DOM
+ * @author Jadwiga Sosnowska <j.sosnowska@partner.samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function () {
+       "use strict";
+                               ns.util.DOM = ns.util.DOM || {};
+                       }());
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, ns, define */
+/*
+ * @author Jadwiga Sosnowska <j.sosnowska@partner.samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function () {
+       "use strict";
+       
+
+                       var selectors = ns.util.selectors,
+                               DOM = ns.util.DOM,
+                               NAMESPACE = "namespace";
+
+                       /**
+                        * Returns given attribute from element or the closest parent,
+                        * which matches the selector.
+                        * @method inheritAttr
+                        * @member ns.util.DOM
+                        * @param {HTMLElement} element
+                        * @param {string} attr
+                        * @param {string} selector
+                        * @return {?string}
+                        * @static
+                        */
+                       DOM.inheritAttr = function (element, attr, selector) {
+                               var value = element.getAttribute(attr),
+                                       parent;
+
+                               if (!value) {
+                                       parent = selectors.getClosestBySelector(element, selector);
+                                       if (parent) {
+                                               return parent.getAttribute(attr);
+                                       }
+                               }
+                               return value;
+                       };
+
+                       /**
+                        * Returns Number from properties described in html tag
+                        * @method getNumberFromAttribute
+                        * @member ns.util.DOM
+                        * @param {HTMLElement} element
+                        * @param {string} attribute
+                        * @param {string=} [type] auto type casting
+                        * @param {number} [defaultValue] default returned value
+                        * @static
+                        * @return {number}
+                        */
+                       DOM.getNumberFromAttribute = function (element, attribute, type, defaultValue) {
+                               var value = element.getAttribute(attribute),
+                                       result = defaultValue;
+
+                               if (!isNaN(value)) {
+                                       if (type === "float") {
+                                               value = parseFloat(value);
+                                               if (!isNaN(value)) {
+                                                       result = value;
+                                               }
+                                       } else {
+                                               value = parseInt(value, 10);
+                                               if (!isNaN(value)) {
+                                                       result = value;
+                                               }
+                                       }
+                               }
+                               return result;
+                       };
+
+                       function getDataName(name, skipData) {
+                               var _namespace = ns.getConfig(NAMESPACE),
+                                       prefix = "";
+
+                               if (!skipData) {
+                                       prefix = "data-";
+                               }
+                               return prefix + (_namespace ? _namespace + "-" : "") + name;
+                       }
+
+                       /**
+                        * Special function to set attribute and property in the same time
+                        * @method setAttribute
+                        * @param {HTMLElement} element
+                        * @param {string} name
+                        * @param {Mixed} value
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function setAttribute(element, name, value) {
+                               element[name] = value;
+                               element.setAttribute(name, value);
+                       }
+
+                       /**
+                        * This function sets value of attribute data-{namespace}-{name} for element.
+                        * If the namespace is empty, the attribute data-{name} is used.
+                        * @method setNSData
+                        * @param {HTMLElement} element Base element
+                        * @param {string} name Name of attribute
+                        * @param {string|number|boolean} value New value
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       DOM.setNSData = function (element, name, value) {
+                               element.setAttribute(getDataName(name), value);
+                       };
+
+                       /**
+                        * This function returns value of attribute data-{namespace}-{name} for element.
+                        * If the namespace is empty, the attribute data-{name} is used.
+                        * Method may return boolean in case of 'true' or 'false' strings as attribute value.
+                        * @method getNSData
+                        * @param {HTMLElement} element Base element
+                        * @param {string} name Name of attribute
+                        * @param {boolean} skipData
+                        * @member ns.util.DOM
+                        * @return {?string|boolean}
+                        * @static
+                        */
+                       DOM.getNSData = function (element, name, skipData) {
+                               var value = element.getAttribute(getDataName(name, skipData));
+
+                               if (value === "true") {
+                                       return true;
+                               }
+
+                               if (value === "false") {
+                                       return false;
+                               }
+
+                               return value;
+                       };
+
+                       /**
+                        * This function returns true if attribute data-{namespace}-{name} for element is set
+                        * or false in another case. If the namespace is empty, attribute data-{name} is used.
+                        * @method hasNSData
+                        * @param {HTMLElement} element Base element
+                        * @param {string} name Name of attribute
+                        * @member ns.util.DOM
+                        * @return {boolean}
+                        * @static
+                        */
+                       DOM.hasNSData = function (element, name) {
+                               return element.hasAttribute(getDataName(name));
+                       };
+
+                       /**
+                        * Get or set value on data attribute.
+                        * @method nsData
+                        * @param {HTMLElement} element
+                        * @param {string} name
+                        * @param {?Mixed} [value]
+                        * @static
+                        * @member ns.util.DOM
+                        */
+                       DOM.nsData = function (element, name, value) {
+                               if (value === undefined) {
+                                       return DOM.getNSData(element, name);
+                               } else {
+                                       return DOM.setNSData(element, name, value);
+                               }
+                       };
+
+                       /**
+                        * This function removes attribute data-{namespace}-{name} from element.
+                        * If the namespace is empty, attribute data-{name} is used.
+                        * @method removeNSData
+                        * @param {HTMLElement} element Base element
+                        * @param {string} name Name of attribute
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       DOM.removeNSData = function (element, name) {
+                               element.removeAttribute(getDataName(name));
+                       };
+
+                       /**
+                        * Returns object with all data-* attributes of element
+                        * @method getData
+                        * @param {HTMLElement} element Base element
+                        * @member ns.util.DOM
+                        * @return {Object}
+                        * @static
+                        */
+                       DOM.getData = function (element) {
+                               var dataPrefix = "data-",
+                                       data = {},
+                                       attributes = element.attributes,
+                                       attribute,
+                                       nodeName,
+                                       value,
+                                       i,
+                                       length = attributes.length,
+                                       lowerCaseValue;
+
+                               for (i = 0; i < length; i++) {
+                                       attribute = attributes.item(i);
+                                       nodeName = attribute.nodeName;
+                                       if (nodeName.indexOf(dataPrefix) > -1) {
+                                               value = attribute.value;
+                                               lowerCaseValue = value.toLowerCase();
+                                               if (lowerCaseValue === "true") {
+                                                       value = true;
+                                               } else if (lowerCaseValue === "false") {
+                                                       value = false;
+                                               }
+                                               data[nodeName.replace(dataPrefix, "")] = value;
+                                       }
+                               }
+
+                               return data;
+                       };
+
+                       /**
+                        * Special function to remove attribute and property in the same time
+                        * @method removeAttribute
+                        * @param {HTMLElement} element
+                        * @param {string} name
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       DOM.removeAttribute = function (element, name) {
+                               element.removeAttribute(name);
+                               element[name] = false;
+                       };
+
+                       DOM.setAttribute = setAttribute;
+                       /**
+                        * Special function to set attributes and properties in the same time
+                        * @method setAttribute
+                        * @param {HTMLElement} element
+                        * @param {Object} values
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       DOM.setAttributes = function (element, values) {
+                               var i,
+                                       names = Object.keys(values),
+                                       name,
+                                       len;
+
+                               for (i = 0, len = names.length; i < len; i++) {
+                                       name = names[i];
+                                       setAttribute(element, name, values[name]);
+                               }
+                       };
+                       }());
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, ns, define */
+/*
+ * @author Jadwiga Sosnowska <j.sosnowska@partner.samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function (window, ns) {
+       "use strict";
+       
+                       var DOM = ns.util.DOM,
+                               stringUtil = ns.util.string,
+                               appStyleSheet;
+
+                       /**
+                        * Returns css property for element
+                        * @method getCSSProperty
+                        * @param {HTMLElement} element
+                        * @param {string} property
+                        * @param {string|number|null} [def=null] default returned value
+                        * @param {"integer"|"float"|null} [type=null] auto type casting
+                        * @return {string|number|null}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function getCSSProperty(element, property, def, type) {
+                               var style = window.getComputedStyle(element),
+                                       value,
+                                       result = def;
+
+                               if (style) {
+                                       value = style.getPropertyValue(property);
+                                       if (value) {
+                                               switch (type) {
+                                                       case "integer":
+                                                               value = parseInt(value, 10);
+                                                               if (!isNaN(value)) {
+                                                                       result = value;
+                                                               }
+                                                               break;
+                                                       case "float":
+                                                               value = parseFloat(value);
+                                                               if (!isNaN(value)) {
+                                                                       result = value;
+                                                               }
+                                                               break;
+                                                       default:
+                                                               result = value;
+                                                               break;
+                                               }
+                                       }
+                               }
+                               return result;
+                       }
+
+                       /**
+                        * Convert string to float or integer
+                        * @param {string} value
+                        * @return {number}
+                        */
+                       function convertToNumber(value) {
+                               if ((value + "").indexOf(".") > -1) {
+                                       return parseFloat(value);
+                               }
+                               return parseInt(value, 10);
+                       }
+
+                       /**
+                        * Extracts css properties from computed css for an element.
+                        * The properties values are applied to the specified
+                        * properties list (dictionary)
+                        * @method extractCSSProperties
+                        * @param {HTMLElement} element
+                        * @param {Object} properties
+                        * @param {?string} [pseudoSelector=null]
+                        * @param {boolean} [noConversion=false]
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function extractCSSProperties(element, properties, pseudoSelector, noConversion) {
+                               var style = window.getComputedStyle(element, pseudoSelector),
+                                       property,
+                                       value,
+                                       newValue;
+
+                               for (property in properties) {
+                                       if (properties.hasOwnProperty(property)) {
+                                               value = style.getPropertyValue(property);
+                                               newValue = convertToNumber(value);
+
+                                               if (!isNaN(newValue) || !noConversion) {
+                                                       value = newValue;
+                                               }
+
+                                               properties[property] = value;
+                                       }
+                               }
+                       }
+
+                       function getOffset(element, props, pseudoSelector, force, offsetProperty) {
+                               var originalDisplay,
+                                       originalVisibility,
+                                       originalPosition,
+                                       offsetValue,
+                                       style = element.style;
+
+                               if (style.display !== "none") {
+                                       extractCSSProperties(element, props, pseudoSelector, true);
+                                       offsetValue = element[offsetProperty];
+                               } else if (force) {
+                                       originalDisplay = style.display;
+                                       originalVisibility = style.visibility;
+                                       originalPosition = style.position;
+
+                                       style.display = "block";
+                                       style.visibility = "hidden";
+                                       style.position = "relative";
+
+                                       extractCSSProperties(element, props, pseudoSelector, true);
+                                       offsetValue = element[offsetProperty];
+
+                                       style.display = originalDisplay;
+                                       style.visibility = originalVisibility;
+                                       style.position = originalPosition;
+                               }
+                               return offsetValue;
+                       }
+
+                       /**
+                        * Returns elements height from computed style
+                        * @method getElementHeight
+                        * @param {HTMLElement} element
+                        * if null then the "inner" value is assigned
+                        * @param {"outer"|null} [type=null]
+                        * @param {boolean} [includeOffset=false]
+                        * @param {boolean} [includeMargin=false]
+                        * @param {?string} [pseudoSelector=null]
+                        * @param {boolean} [force=false] check even if element is hidden
+                        * @return {number}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function getElementHeight(element, type, includeOffset, includeMargin, pseudoSelector, force) {
+                               var height = 0,
+                                       outer = (type && type === "outer") || false,
+                                       offsetHeight,
+                                       property,
+                                       props = {
+                                               "height": 0,
+                                               "margin-top": 0,
+                                               "margin-bottom": 0,
+                                               "padding-top": 0,
+                                               "padding-bottom": 0,
+                                               "border-top-width": 0,
+                                               "border-bottom-width": 0,
+                                               "box-sizing": ""
+                                       };
+
+                               if (element) {
+                                       offsetHeight = getOffset(element, props, pseudoSelector, force, "offsetHeight");
+
+                                       for (property in props) {
+                                               if (props.hasOwnProperty(property) && property !== "box-sizing") {
+                                                       props[property] = convertToNumber(props[property]);
+                                               }
+                                       }
+
+                                       height += props["height"];
+
+                                       if (props["box-sizing"] !== "border-box") {
+                                               height += props["padding-top"] + props["padding-bottom"];
+                                       }
+
+                                       if (includeOffset) {
+                                               height = offsetHeight;
+                                       } else if (outer && props["box-sizing"] !== "border-box") {
+                                               height += props["border-top-width"] + props["border-bottom-width"];
+                                       }
+
+                                       if (includeMargin) {
+                                               height += Math.max(0, props["margin-top"]) + Math.max(0, props["margin-bottom"]);
+                                       }
+                               }
+                               return height;
+                       }
+
+                       /**
+                        * Returns elements width from computed style
+                        * @method getElementWidth
+                        * @param {HTMLElement} element
+                        * if null then the "inner" value is assigned
+                        * @param {"outer"|null} [type=null]
+                        * @param {boolean} [includeOffset=false]
+                        * @param {boolean} [includeMargin=false]
+                        * @param {?string} [pseudoSelector=null]
+                        * @param {boolean} [force=false] check even if element is hidden
+                        * @return {number}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function getElementWidth(element, type, includeOffset, includeMargin, pseudoSelector, force) {
+                               var width = 0,
+                                       value,
+                                       offsetWidth,
+                                       property,
+                                       outer = (type && type === "outer") || false,
+                                       props = {
+                                               "width": 0,
+                                               "margin-left": 0,
+                                               "margin-right": 0,
+                                               "padding-left": 0,
+                                               "padding-right": 0,
+                                               "border-left-width": 0,
+                                               "border-right-width": 0,
+                                               "box-sizing": ""
+                                       };
+
+                               if (element) {
+                                       offsetWidth = getOffset(element, props, pseudoSelector, force, "offsetWidth");
+
+                                       for (property in props) {
+                                               if (props.hasOwnProperty(property) && property !== "box-sizing") {
+                                                       value = parseFloat(props[property]);
+                                                       props[property] = value;
+                                               }
+                                       }
+
+                                       width += props["width"];
+                                       if (props["box-sizing"] !== "border-box") {
+                                               width += props["padding-left"] + props["padding-right"];
+                                       }
+
+                                       if (includeOffset) {
+                                               width = offsetWidth;
+                                       } else if (outer && props["box-sizing"] !== "border-box") {
+                                               width += props["border-left-width"] + props["border-right-width"];
+                                       }
+
+                                       if (includeMargin) {
+                                               width += Math.max(0, props["margin-left"]) + Math.max(0, props["margin-right"]);
+                                       }
+                               }
+                               return width;
+                       }
+
+                       /**
+                        * Returns offset of element
+                        * @method getElementOffset
+                        * @param {HTMLElement} element
+                        * @return {Object}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function getElementOffset(element) {
+                               var left = 0,
+                                       top = 0,
+                                       loopElement = element;
+
+                               do {
+                                       top += loopElement.offsetTop;
+                                       left += loopElement.offsetLeft;
+                                       loopElement = loopElement.offsetParent;
+                               } while (loopElement !== null);
+
+                               return {
+                                       top: top,
+                                       left: left
+                               };
+                       }
+
+                       /**
+                        * Check if element occupies place at view
+                        * @method isOccupiedPlace
+                        * @param {HTMLElement} element
+                        * @return {boolean}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function isOccupiedPlace(element) {
+                               return !(element.offsetWidth <= 0 && element.offsetHeight <= 0);
+                       }
+
+                       /**
+                        * Set values for element with prefixes for browsers
+                        * @method setPrefixedStyle
+                        * @param {HTMLElement | CSSStyleRule} elementOrRule
+                        * @param {string} property
+                        * @param {string|Object|null} value
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function setPrefixedStyle(elementOrRule, property, value) {
+                               var style = elementOrRule.style,
+                                       propertyForPrefix = property,
+                                       values = (typeof value !== "object") ? {
+                                               webkit: value,
+                                               moz: value,
+                                               o: value,
+                                               ms: value,
+                                               normal: value
+                                       } : value;
+
+                               style.setProperty(property, values.normal);
+                               style.setProperty("-webkit-" + propertyForPrefix, values.webkit);
+                               style.setProperty("-moz-" + propertyForPrefix, values.moz);
+                               style.setProperty("-o-" + propertyForPrefix, values.o);
+                               style.setProperty("-ms-" + propertyForPrefix, values.ms);
+                       }
+
+                       /**
+                        * Get value from element with prefixes for browsers
+                        * @method getCSSProperty
+                        * @param {string} value
+                        * @return {Object}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function getPrefixedValue(value) {
+                               return {
+                                       webkit: "-webkit-" + value,
+                                       moz: "-moz-" + value,
+                                       o: "-ms-" + value,
+                                       ms: "-o-" + value,
+                                       normal: value
+                               };
+                       }
+
+                       /**
+                        * Returns style value for css property with browsers prefixes
+                        * @method getPrefixedStyleValue
+                        * @param {HTMLStyle} styles
+                        * @param {string} property
+                        * @return {string|undefined}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function getPrefixedStyleValue(styles, property) {
+                               var prefixedProperties = getPrefixedValue(property),
+                                       value,
+                                       key;
+
+                               for (key in prefixedProperties) {
+                                       if (prefixedProperties.hasOwnProperty(key)) {
+                                               value = styles[prefixedProperties[key]];
+                                               if (value && value !== "none") {
+                                                       break;
+                                               }
+                                       }
+                               }
+                               return value;
+                       }
+
+                       /**
+                        * Returns size (width, height) as CSS string
+                        * @method toCSSSize
+                        * @param {string|Array} size has to be comma separated string (eg. "10,100") or array with 2
+                        * elements
+                        * @return {string} if not enough arguments the method returns empty string
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function toCSSSize(size) {
+                               var cssSize = "",
+                                       arraySize = stringUtil.parseProperty(size);
+
+                               if (arraySize && arraySize.length === 2) {
+                                       cssSize = "width: " + arraySize[0] + "px; " +
+                                       "height: " + arraySize[1] + "px;";
+                               }
+
+                               return cssSize;
+                       }
+
+                       /**
+                        * Set CSS styles for pseudo class selector.
+                        * @method setStylesForPseudoClass
+                        * @param {string} selector selector of elements
+                        * @param {string} pseudoClassName CSS pseudo class name to set, for example after, before
+                        * @param {Object} cssValues object with styles to set
+                        * @return {number?} return index of inserted rule
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function setStylesForPseudoClass(selector, pseudoClassName, cssValues) {
+                               var cssValuesArray = [],
+                                       headElement,
+                                       styleElement,
+                                       name;
+
+                               // create style element on first use
+                               if (!appStyleSheet) {
+                                       headElement = document.head || document.getElementsByTagName("head")[0];
+                                       styleElement = document.createElement("style");
+                                       styleElement.type = "text/css";
+                                       headElement.appendChild(styleElement);
+                                       appStyleSheet = styleElement.sheet;
+                               }
+
+                               for (name in cssValues) {
+                                       if (cssValues.hasOwnProperty(name)) {
+                                               cssValuesArray.push(name + ": " + cssValues[name]);
+                                       }
+                               }
+
+                               if (cssValuesArray.length) {
+                                       return appStyleSheet.addRule(selector + "::" + pseudoClassName, cssValuesArray.join("; "));
+                               }
+
+                               return null;
+                       }
+
+                       /**
+                        * Remove CSS rule from sheet.
+                        * @method removeCSSRule
+                        * @param {number} ruleIndex Index of rule to remove
+                        * @static
+                        */
+                       function removeCSSRule(ruleIndex) {
+
+                               // create style element on first use
+                               if (appStyleSheet) {
+                                       appStyleSheet.deleteRule(ruleIndex);
+                               }
+                       }
+
+                       // assign methods to namespace
+                       DOM.getCSSProperty = getCSSProperty;
+                       DOM.extractCSSProperties = extractCSSProperties;
+                       DOM.getElementHeight = getElementHeight;
+                       DOM.getElementWidth = getElementWidth;
+                       DOM.getElementOffset = getElementOffset;
+                       DOM.isOccupiedPlace = isOccupiedPlace;
+                       DOM.setPrefixedStyle = setPrefixedStyle;
+                       DOM.getPrefixedValue = getPrefixedValue;
+                       DOM.getPrefixedStyleValue = getPrefixedStyleValue;
+                       DOM.toCSSSize = toCSSSize;
+                       DOM.setStylesForPseudoClass = setStylesForPseudoClass;
+                       DOM.removeCSSRule = removeCSSRule;
+
+                       }(window, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, ns, define */
+/**
+ * #Set Utility
+ *
+ * Own implementation of ECMAScript Set.
+ *
+ * @class ns.util.Set
+ */
+(function (window, ns) {
+       "use strict";
+                               var set = function () {
+                               this._data = [];
+                       };
+
+                       set.prototype = {
+                               /**
+                                * Add one or many arguments to set
+                                * @method add
+                                * @member ns.util.Set
+                                */
+                               add: function () {
+                                       var data = this._data;
+
+                                       this._data = data.concat.apply(data, [].slice.call(arguments))
+                                               .filter(function (item, pos, array) {
+                                                       return array.indexOf(item) === pos;
+                                               });
+                               },
+                               /**
+                                * Remove all items from set
+                                * @method clear
+                                * @member ns.util.Set
+                                */
+                               clear: function () {
+                                       this._data = [];
+                               },
+                               /**
+                                * delete one item from set
+                                * @method delete
+                                * @param {*} item
+                                * @member ns.util.Set
+                                */
+                               delete: function (item) {
+                                       var data = this._data,
+                                               index = data.indexOf(item);
+
+                                       if (index > -1) {
+                                               data.splice(index, 1);
+                                       }
+                               },
+                               /**
+                                * Check that item exists in set
+                                * @method has
+                                * @param {Object} item
+                                * @member ns.util.Set
+                                * @return {boolean}
+                                */
+                               has: function (item) {
+                                       return this._data.indexOf(item) > -1;
+                               },
+                               /**
+                                * Iterate on each set elements
+                                * @method forEach
+                                * @param {Function} cb
+                                * @member ns.util.Set
+                                */
+                               forEach: function (cb) {
+                                       this._data.forEach(cb);
+                               }
+                       };
+
+                       // for tests
+                       ns.util._Set = set;
+                       ns.util.Set = window.Set || set;
+
+                       }(window, ns));
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (c) 2010 - 2014 Samsung Electronics Co., Ltd.
+ * License : MIT License V2
+ */
+/**
+ * #Namespace For Widgets
+ * Namespace For Widgets
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @class ns.widget
+ */
+(function (document) {
+       "use strict";
+                               var engine = ns.engine,
+                               eventType = engine.eventType,
+                               widget = {
+                                       /**
+                                        * Get bound widget for element
+                                        * @method getInstance
+                                        * @static
+                                        * @param {HTMLElement|string} element
+                                        * @param {string} type widget name
+                                        * @return {?Object}
+                                        * @member ns.widget
+                                        */
+                                       getInstance: engine.getBinding,
+                                       /**
+                                        * Returns Get all bound widget for element or id gives as parameter
+                                        * @method getAllInstances
+                                        * @param {HTMLElement|string} element
+                                        * @return {?Object}
+                                        * @static
+                                        * @member ns.widget
+                                        */
+                                       getAllInstances: engine.getAllBindings
+                               };
+
+                       function mapWidgetDefinition(name, element, options) {
+                               var widgetParams = {
+                                       name: name,
+                                       element: element,
+                                       options: options
+                               }
+
+                               return widgetParams;
+                       }
+
+                       function widgetConstructor(name, element, options) {
+                               var widgetParams = mapWidgetDefinition(name, element, options);
+
+                               return engine.instanceWidget(widgetParams.element, widgetParams.name, widgetParams.options);
+                       }
+
+                       /**
+                        * Register simple widget constructor in namespace
+                        * @param {Event} event
+                        */
+                       function defineWidget(event) {
+                               var definition = event.detail,
+                                       name = definition.name;
+
+                               ns.widget[name] = widgetConstructor.bind(null, name);
+                       }
+
+                       /**
+                        * Remove event listeners on framework destroy
+                        */
+                       function destroy() {
+                               document.removeEventListener(eventType.WIDGET_DEFINED, defineWidget, true);
+                               document.removeEventListener(eventType.DESTROY, destroy, false);
+                       }
+
+                       document.addEventListener(eventType.WIDGET_DEFINED, defineWidget, true);
+                       document.addEventListener(eventType.DESTROY, destroy, false);
+
+                       /** @namespace ns.widget */
+                       ns.widget = widget;
+                       }(window.document));
+
+/*global ns, define */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #BaseWidget
+ * Prototype class of widget
+ *
+ * ## How to invoke creation of widget from JavaScript
+ *
+ * To build and initialize widget in JavaScript you have to use method
+ * {@link ns.engine#instanceWidget}. First argument for method is HTMLElement, which specifies the
+ * element of widget. Second parameter is name of widget to create.
+ *
+ * If you load jQuery before initializing tau library, you can use standard jQuery UI Widget
+ * notation.
+ *
+ * ### Examples
+ * #### Build widget from JavaScript
+ *
+ *        @example
+ *        var element = document.getElementById("id"),
+ *            ns.engine.instanceWidget(element, "Button");
+ *
+ * #### Build widget from jQuery
+ *
+ *        @example
+ *        var element = $("#id").button();
+ *
+ * ## How to create new widget
+ *
+ *        @example
+ *        (function (ns) {
+ *                     "use strict";
+ *                      *                                      var BaseWidget = ns.widget.BaseWidget, // create alias to main objects
+ *                                             ...
+ *                                             arrayOfElements, // example of private property, common for all instances of widget
+ *                                             Button = function () { // create local object with widget
+ *                                                     ...
+ *                                             },
+ *                                             prototype = new BaseWidget(); // add ns.widget.BaseWidget as prototype to widget's
+ *                                             object, for better minification this should be assign to local variable and next
+ *                                             variable should be assign to prototype of object.
+ *
+ *                                     function closestEnabledButton(element) { // example of private method
+ *                                             ...
+ *                                     }
+ *                                     ...
+ *
+ *                                     prototype.options = { //add default options to be read from data- attributes
+ *                                             theme: "s",
+ *                                             ...
+ *                                     };
+ *
+ *                                     prototype._build = function (template, element) {
+ *                                             // method called when the widget is being built, should contain all HTML
+ *                                             // manipulation actions
+ *                                             ...
+ *                                             return element;
+ *                                     };
+ *
+ *                                     prototype._init = function (element) {
+ *                                             // method called during initialization of widget, should contain all actions
+ *                                             // necessary fastOn application start
+ *                                             ...
+ *                                             return element;
+ *                                     };
+ *
+ *                                     prototype._bindEvents = function (element) {
+ *                                             // method to bind all events, should contain all event bindings
+ *                                             ...
+ *                                     };
+ *
+ *                                     prototype._enable = function (element) {
+ *                                             // method called during invocation of enable() method
+ *                                             ...
+ *                                     };
+ *
+ *                                     prototype._disable = function (element) {
+ *                                             // method called during invocation of disable() method
+ *                                             ...
+ *                                     };
+ *
+ *                                     prototype.refresh = function (element) {
+ *                                             // example of public method
+ *                                             ...
+ *                                     };
+ *
+ *                                     prototype._refresh = function () {
+ *                                             // example of protected method
+ *                                             ...
+ *                                     };
+ *
+ *                                     Button.prototype = prototype;
+ *
+ *                                     engine.defineWidget( // define widget
+ *                                             "Button", //name of widget
+ *                                             "[data-role='button'],button,[type='button'],[type='submit'],[type='reset']",
+ *                                             //widget's selector
+ *                                             [ // public methods, here should be list all public method
+ *                                                     "enable",
+ *                                                     "disable",
+ *                                                     "refresh"
+ *                                             ],
+ *                                             Button, // widget's object
+ *                                             "mobile" // widget's namespace
+ *                                     );
+ *                                     ns.widget.Button = Button;
+ *                                      *              }(ns));
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ * @author Przemyslaw Ciezkowski <p.ciezkowski@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Michał Szepielak <m.szepielak@samsung.com>
+ * @class ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var slice = [].slice,
+                               /**
+                                * Alias to ns.engine
+                                * @property {ns.engine} engine
+                                * @member ns.widget.BaseWidget
+                                * @private
+                                * @static
+                                */
+                               engine = ns.engine,
+                               engineDataTau = engine.dataTau,
+                               util = ns.util,
+                               /**
+                                * Alias to {@link ns.event}
+                                * @property {Object} eventUtils
+                                * @member ns.widget.BaseWidget
+                                * @private
+                                * @static
+                                */
+                               eventUtils = ns.event,
+                               /**
+                                * Alias to {@link ns.util.DOM}
+                                * @property {Object} domUtils
+                                * @private
+                                * @static
+                                */
+                               domUtils = util.DOM,
+                               utilString = util.string,
+                               /**
+                                * Alias to {@link ns.util.object}
+                                * @property {Object} objectUtils
+                                * @private
+                                * @static
+                                */
+                               objectUtils = util.object,
+                               selectorUtils = util.selectors,
+                               setUtils = util.Set,
+                               BaseWidget = function () {
+                                       this.flowState = "created";
+                                       return this;
+                               },
+                               getNSData = domUtils.getNSData,
+                               prototype = {},
+                               /**
+                                * Property with string represent function type
+                                * (for better minification)
+                                * @property {string} [TYPE_FUNCTION="function"]
+                                * @private
+                                * @static
+                                * @readonly
+                                */
+                               TYPE_FUNCTION = "function",
+                               TYPE_STRING = "string",
+                               DEFAULT_STRING_DELIMITER = ",",
+                               disableClass = "ui-state-disabled",
+                               ariaDisabled = "aria-disabled",
+                               commonClasses = {
+                                       INLINE: "ui-inline"
+                               },
+                               __callbacks;
+
+                       BaseWidget.classes = {
+                               disable: disableClass
+                       };
+
+                       prototype._configureDefinition = function (definition) {
+                               var self = this,
+                                       definitionName,
+                                       definitionNamespace;
+
+                               if (definition) {
+                                       definitionName = definition.name;
+                                       definitionNamespace = definition.namespace;
+                                       /**
+                                        * Name of the widget
+                                        * @property {string} name
+                                        * @member ns.widget.BaseWidget
+                                        */
+                                       self.name = definitionName;
+
+                                       /**
+                                        * Name of the widget (in lower case)
+                                        * @property {string} widgetName
+                                        * @member ns.widget.BaseWidget
+                                        */
+                                       self.widgetName = definitionName;
+
+                                       /**
+                                        * Namespace of widget events
+                                        * @property {string} widgetEventPrefix
+                                        * @member ns.widget.BaseWidget
+                                        */
+                                       self.widgetEventPrefix = definitionName.toLowerCase();
+
+                                       /**
+                                        * Namespace of the widget
+                                        * @property {string} namespace
+                                        * @member ns.widget.BaseWidget
+                                        */
+                                       self.namespace = definitionNamespace;
+
+                                       /**
+                                        * Full name of the widget
+                                        * @property {string} widgetFullName
+                                        * @member ns.widget.BaseWidget
+                                        */
+                                       self.widgetFullName = ((definitionNamespace ? definitionNamespace + "-" : "") +
+                                               definitionName).toLowerCase();
+                                       /**
+                                        * Id of widget instance
+                                        * @property {string} id
+                                        * @member ns.widget.BaseWidget
+                                        */
+                                       self.id = ns.getUniqueId();
+
+                                       /**
+                                        * Widget's selector
+                                        * @property {string} selector
+                                        * @member ns.widget.BaseWidget
+                                        */
+                                       self.selector = definition.selector;
+                               }
+                       };
+
+                       /**
+                        * Protected method configuring the widget
+                        * @method _configure
+                        * @member ns.widget.BaseWidget
+                        * @protected
+                        * @template
+                        * @ignore
+                        */
+                       /**
+                        * Configures widget object from definition.
+                        *
+                        * It calls such methods as #\_getCreateOptions and #\_configure.
+                        * @method configure
+                        * @param {Object} definition
+                        * @param {string} definition.name Name of the widget
+                        * @param {string} definition.selector Selector of the widget
+                        * @param {HTMLElement} element Element of widget
+                        * @param {Object} options Configure options
+                        * @member ns.widget.BaseWidget
+                        * @return {ns.widget.BaseWidget}
+                        * @ignore
+                        */
+                       prototype.configure = function (definition, element, options) {
+                               var self = this;
+
+                               /**
+                                * Object with options for widget
+                                * @property {Object} [options={}]
+                                * @member ns.widget.BaseWidget
+                                */
+
+                               self.flowState = "configuring";
+
+                               self.options = self.options || {};
+                               /**
+                                * Base element of widget
+                                * @property {?HTMLElement} [element=null]
+                                * @member ns.widget.BaseWidget
+                                */
+                               self.element = self.element || null;
+
+                               self._configureDefinition(definition);
+
+                               if (typeof self._configure === TYPE_FUNCTION) {
+                                       element = self._configure(element) || element;
+                               }
+
+                               self.isCustomElement = !!element.createdCallback;
+
+                               self._getCreateOptions(element);
+
+                               objectUtils.fastMerge(self.options, options);
+
+                               // move style attribute to another attribute for recovery in init method
+                               // this feature is required in widgets with container
+                               if (element.style.cssText) {
+                                       element.dataset.originalStyle = element.style.cssText;
+                               }
+
+                               self.flowState = "configured";
+
+                               return element;
+                       };
+
+                       /**
+                        * Reads data-* attributes and save to options object.
+                        * @method _getCreateOptions
+                        * @param {HTMLElement} element Base element of the widget
+                        * @return {Object}
+                        * @member ns.widget.BaseWidget
+                        * @protected
+                        */
+                       prototype._getCreateOptions = function (element) {
+                               var self = this,
+                                       options = self.options,
+                                       tag = element.localName.toLowerCase(),
+                                       delimiter;
+
+                               if (options) {
+                                       Object.keys(options).forEach(function (option) {
+                                               var attributeName = utilString.camelCaseToDashes(option),
+                                                       baseValue = getNSData(element, attributeName, true),
+                                                       prefixedValue = getNSData(element, attributeName);
+
+                                               if (prefixedValue !== null) {
+                                                       if (typeof options[option] === "number") {
+                                                               prefixedValue = parseFloat(prefixedValue);
+                                                       } else if (typeof options[option] === "object" &&
+                                                                               typeof prefixedValue === "string" &&
+                                                                               Array.isArray(options[option])) {
+                                                               delimiter = element.dataset.delimiter || DEFAULT_STRING_DELIMITER;
+                                                               prefixedValue = prefixedValue.split(delimiter);
+                                                       }
+                                                       options[option] = prefixedValue;
+                                               } else {
+                                                       if (typeof options[option] === "boolean") {
+                                                               if (!self._readCommonOptionFromElementClassname(element, option)) {
+                                                                       if (!self._readPrefixedOptionFromElementClassname(element, option)) {
+                                                                               if (typeof self._readWidgetSpecyficOptionFromElementClassname !== TYPE_FUNCTION ||
+                                                                                       typeof self._readWidgetSpecyficOptionFromElementClassname === TYPE_FUNCTION &&
+                                                                                       !self._readWidgetSpecyficOptionFromElementClassname(element, option)) {
+                                                                                       if (typeof self._getDefaultOption === TYPE_FUNCTION) {
+                                                                                               options[option] = self._getDefaultOption(option);
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+
+                                               if (option === "type" && tag === "input" ||
+                                                       option === "style"
+                                               ) { // don't set conflicting props
+                                                       return;
+                                               }
+
+                                               if (baseValue !== null) {
+                                                       if (typeof options[option] === "number") {
+                                                               baseValue = parseFloat(baseValue);
+                                                       }
+                                                       options[option] = baseValue;
+                                               }
+                                       });
+                               }
+                               return options;
+                       };
+
+                       /**
+                        * Protected method building the widget
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} widget's element
+                        * @member ns.widget.BaseWidget
+                        * @protected
+                        * @template
+                        */
+                       /**
+                        * Builds widget.
+                        *
+                        * It calls method #\_build.
+                        *
+                        * Before starting building process, the event beforecreate with
+                        * proper prefix defined in variable widgetEventPrefix is triggered.
+                        * @method build
+                        * @param {HTMLElement} element Element of widget before building process
+                        * @return {HTMLElement} Element of widget after building process
+                        * @member ns.widget.BaseWidget
+                        * @ignore
+                        */
+                       prototype.build = function (element) {
+                               var self = this,
+                                       id,
+                                       node,
+                                       dataBuilt = element.getAttribute(engineDataTau.built),
+                                       dataName = element.getAttribute(engineDataTau.name);
+
+                               eventUtils.trigger(element, self.widgetEventPrefix + "beforecreate");
+
+                               self.flowState = "building";
+
+                               id = element.id;
+                               if (id) {
+                                       self.id = id;
+                               } else {
+                                       element.id = self.id;
+                               }
+
+                               if (typeof self._build === TYPE_FUNCTION) {
+                                       node = self._build(element);
+                               } else {
+                                       node = element;
+                               }
+
+                               self._setBooleanOptions(element);
+
+                               // Append current widget name to data-tau-built and data-tau-name attributes
+                               dataBuilt = !dataBuilt ? self.name : dataBuilt + engineDataTau.separator + self.name;
+                               dataName = !dataName ? self.name : dataName + engineDataTau.separator + self.name;
+
+                               element.setAttribute(engineDataTau.built, dataBuilt);
+                               element.setAttribute(engineDataTau.name, dataName);
+
+                               self.flowState = "built";
+                               return node;
+                       };
+
+                       /**
+                        * Protected method initializing the widget
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @member ns.widget.BaseWidget
+                        * @template
+                        * @protected
+                        */
+                       /**
+                        * Initializes widget.
+                        *
+                        * It calls method #\_init.
+                        * @method init
+                        * @param {HTMLElement} element Element of widget before initialization
+                        * @member ns.widget.BaseWidget
+                        * @return {ns.widget.BaseWidget}
+                        * @ignore
+                        */
+                       prototype.init = function (element) {
+                               var self = this,
+                                       container,
+                                       originalStyleText;
+
+                               self.id = element.id;
+
+                               self.flowState = "initiating";
+
+                               // Move style properties that was defined before building to container element
+                               if (element.dataset.originalStyle) {
+                                       container = self.getContainer();
+                                       if (container != element) {
+                                               originalStyleText = element.dataset.originalStyle;
+
+                                               originalStyleText.split(";").forEach(function (keyValue) {
+                                                       var key,
+                                                               value,
+                                                               keyValuePair;
+
+                                                       keyValuePair = keyValue.split(":");
+                                                       if (keyValuePair.length === 2) {
+                                                               key = keyValuePair[0].trim();
+                                                               value = keyValuePair[1].trim();
+
+                                                               container.style[key] = element.style[key];
+
+                                                               if (element.style[key] === value) {
+                                                                       element.style[key] = "";
+                                                               }
+                                                       }
+                                               });
+                                       }
+                               }
+
+                               if (typeof self._init === TYPE_FUNCTION) {
+                                       self._init(element);
+                               }
+
+                               if (element.hasAttribute("disabled") && element.getAttribute("disabled") !== "false" ||
+                                       self.options.disabled === true) {
+                                       self.disable();
+                               } else {
+                                       self.enable();
+                               }
+
+                               self.flowState = "initiated";
+                               return self;
+                       };
+
+                       /**
+                        * Returns base element widget
+                        * @member ns.widget.BaseWidget
+                        * @return {HTMLElement|null}
+                        * @instance
+                        */
+                       prototype.getContainer = function () {
+                               var self = this;
+
+                               if (typeof self._getContainer === TYPE_FUNCTION) {
+                                       return self._getContainer();
+                               }
+                               return self.element;
+                       };
+
+                       /**
+                        * Bind widget events attached in init mode
+                        * @method _bindEvents
+                        * @param {HTMLElement} element Base element of widget
+                        * @member ns.widget.BaseWidget
+                        * @template
+                        * @protected
+                        */
+                       /**
+                        * Binds widget events.
+                        *
+                        * It calls such methods as #\_buildBindEvents and #\_bindEvents.
+                        * At the end of binding process, the event "create" with proper
+                        * prefix defined in variable widgetEventPrefix is triggered.
+                        * @method bindEvents
+                        * @param {HTMLElement} element Base element of the widget
+                        * @param {boolean} onlyBuild Inform about the type of bindings: build/init
+                        * @member ns.widget.BaseWidget
+                        * @return {ns.widget.BaseWidget}
+                        * @ignore
+                        */
+                       prototype.bindEvents = function (element, onlyBuild) {
+                               var self = this,
+                                       dataBound = element.getAttribute(engineDataTau.bound);
+
+                               if (!onlyBuild) {
+                                       dataBound = !dataBound ? self.name : dataBound + engineDataTau.separator + self.name;
+                                       element.setAttribute(engineDataTau.bound, dataBound);
+                               }
+                               if (typeof self._buildBindEvents === TYPE_FUNCTION) {
+                                       self._buildBindEvents(element);
+                               }
+                               if (!onlyBuild && typeof self._bindEvents === TYPE_FUNCTION) {
+                                       self._bindEvents(element);
+                               }
+
+                               self.trigger(self.widgetEventPrefix + "create", self);
+
+                               return self;
+                       };
+
+                       /**
+                        * Event triggered when method focus is called
+                        * @event taufocus
+                        * @member ns.widget.BaseWidget
+                        */
+
+                       /**
+                        * Focus widget's element.
+                        *
+                        * This function calls function focus on element and if it is known
+                        * the direction of event, the proper css classes are added/removed.
+                        * @method focus
+                        * @param {Object} options The options of event.
+                        * @param {HTMLElement} options.previousElement Element to blur
+                        * @param {HTMLElement} options.element Element to focus
+                        * @member ns.widget.BaseWidget
+                        */
+                       prototype.focus = function (options) {
+                               var self = this,
+                                       element = self.element,
+                                       blurElement,
+                                       scrollview,
+                                       scrollviewElement,
+                                       blurWidget;
+
+                               options = options || {};
+
+                               blurElement = options.previousElement;
+                               // we try to blur element, which has focus previously
+                               if (blurElement) {
+                                       blurWidget = engine.getBinding(blurElement);
+                                       // call blur function on widget
+                                       if (blurWidget) {
+                                               options = objectUtils.merge({}, options, {element: blurElement});
+                                               blurWidget.blur(options);
+                                       } else {
+                                               // or on element, if widget does not exist
+                                               blurElement.blur();
+                                       }
+                               }
+
+                               options = objectUtils.merge({}, options, {element: element});
+                               scrollviewElement = selectorUtils.getClosestBySelector(element, "[data-tau-name='Scrollview']");
+                               if (scrollviewElement) {
+                                       scrollview = engine.getBinding(scrollviewElement);
+                               }
+
+                               // set focus on element
+                               eventUtils.trigger(document, "taufocus", options);
+                               if (typeof self._focus === TYPE_FUNCTION) {
+                                       if (options.event) {
+                                               scrollview && scrollview.ensureElementIsVisible(element);
+                                       }
+                                       self._focus(element);
+                               } else {
+                                       element.focus();
+                               }
+
+                               return true;
+                       };
+
+                       /**
+                        * Event triggered then method blur is called.
+                        * @event taublur
+                        * @member ns.widget.BaseWidget
+                        */
+
+                       /**
+                        * Blur widget's element.
+                        *
+                        * This function calls function blur on element and if it is known
+                        * the direction of event, the proper css classes are added/removed.
+                        * @method blur
+                        * @param {Object} options The options of event.
+                        * @param {HTMLElement} options.element Element to blur
+                        * @member ns.widget.BaseWidget
+                        */
+                       prototype.blur = function (options) {
+                               var self = this,
+                                       element = self.element;
+
+                               options = objectUtils.merge({}, options, {element: element});
+
+                               // blur element
+                               eventUtils.trigger(document, "taublur", options);
+                               if (typeof self._blur === TYPE_FUNCTION) {
+                                       self._blur(element);
+                               } else {
+                                       element.blur();
+                               }
+                               return true;
+                       };
+
+                       /**
+                        * Protected method destroying the widget
+                        * @method _destroy
+                        * @template
+                        * @protected
+                        * @member ns.widget.BaseWidget
+                        */
+                       /**
+                        * Destroys widget.
+                        *
+                        * It calls method #\_destroy.
+                        *
+                        * At the end of destroying process, the event "destroy" with proper
+                        * prefix defined in variable widgetEventPrefix is triggered and
+                        * the binding set in engine is removed.
+                        * @method destroy
+                        * @param {HTMLElement} element Base element of the widget
+                        * @member ns.widget.BaseWidget
+                        */
+                       prototype.destroy = function (element) {
+                               var self = this;
+
+                               element = element || self.element;
+
+                               // the widget is in during destroy process
+                               self.flowState = "destroying";
+
+                               if (typeof self._destroy === TYPE_FUNCTION) {
+                                       self._destroy(element);
+                               }
+                               if (self.element) {
+                                       self.trigger(self.widgetEventPrefix + "destroy");
+                                       if (self.element.dataset.originalStyle) {
+                                               self.element.style.cssText = self.element.dataset.originalStyle;
+                                               delete self.element.dataset.originalStyle;
+                                       }
+                               }
+                               if (element) {
+                                       engine.removeBinding(element, self.name);
+                               }
+                               // the widget was destroyed
+                               self.flowState = "destroyed";
+                       };
+
+                       /**
+                        * Protected method disabling the widget
+                        * @method _disable
+                        * @protected
+                        * @member ns.widget.BaseWidget
+                        * @template
+                        */
+                       /**
+                        * Disables widget.
+                        *
+                        * It calls method #\_disable.
+                        * @method disable
+                        * @member ns.widget.BaseWidget
+                        * @return {ns.widget.BaseWidget}
+                        */
+                       prototype.disable = function () {
+                               var self = this,
+                                       args = slice.call(arguments),
+                                       element = self.element;
+
+                               element.classList.add(disableClass);
+                               element.setAttribute(ariaDisabled, true);
+
+                               if (typeof self._disable === TYPE_FUNCTION) {
+                                       args.unshift(element);
+                                       self._disable.apply(self, args);
+                               }
+                               return this;
+                       };
+
+                       /**
+                        * Check if widget is disabled.
+                        * @method isDisabled
+                        * @member ns.widget.BaseWidget
+                        * @return {boolean} Returns true if widget is disabled
+                        */
+                       prototype.isDisabled = function () {
+                               var self = this;
+
+                               return self.element.getAttribute("disabled") || self.options.disabled === true;
+                       };
+
+                       /**
+                        * Protected method enabling the widget
+                        * @method _enable
+                        * @protected
+                        * @member ns.widget.BaseWidget
+                        * @template
+                        */
+                       /**
+                        * Enables widget.
+                        *
+                        * It calls method #\_enable.
+                        * @method enable
+                        * @member ns.widget.BaseWidget
+                        * @return {ns.widget.BaseWidget}
+                        */
+                       prototype.enable = function () {
+                               var self = this,
+                                       args = slice.call(arguments),
+                                       element = self.element;
+
+                               element.classList.remove(disableClass);
+                               element.setAttribute(ariaDisabled, false);
+
+                               if (typeof self._enable === TYPE_FUNCTION) {
+                                       args.unshift(element);
+                                       self._enable.apply(self, args);
+                               }
+                               return this;
+                       };
+
+                       /**
+                        * Protected method causing the widget to refresh
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.BaseWidget
+                        * @template
+                        */
+                       /**
+                        * Refreshes widget.
+                        *
+                        * It calls method #\_refresh.
+                        * @method refresh
+                        * @member ns.widget.BaseWidget
+                        * @return {ns.widget.BaseWidget}
+                        */
+                       prototype.refresh = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               self._getCreateOptions(element);
+
+                               if (typeof self._refresh === TYPE_FUNCTION) {
+                                       self._refresh.apply(self, arguments);
+                               }
+                               return self;
+                       };
+
+                       /**
+                        * Reads class based on name conversion option value, for all options which have boolean value
+                        * we can read option value by check that exists classname connected with option name. To
+                        * correct use this method is required define in widget property _classesPrefix. If this
+                        * condition is not met method returns false, otherwise returns true.
+                        *
+                        * For example for option middle in Button widget we will check existing of class
+                        * ui-btn-middle.
+                        *
+                        * @method _readPrefixedOptionFromElementClassname
+                        * @param {HTMLElement} element Main element of widget
+                        * @param {string} name Name of option which should be used
+                        * @return {boolean} If option value was successfully read
+                        * @member ns.widget.BaseWidget
+                        * @protected
+                        */
+                       prototype._readPrefixedOptionFromElementClassname = function (element, name) {
+                               var classesPrefix = this._classesPrefix,
+                                       className;
+
+                               if (classesPrefix) {
+                                       className = classesPrefix + utilString.camelCaseToDashes(name);
+                                       if (element.classList.contains(className)) {
+                                               this.options[name] = element.classList.contains(className);
+                                               // property exists in classname
+                                               return true;
+                                       }
+                               }
+
+                               return false;
+                       };
+
+                       /**
+                        * Reads class based on name conversion option value, for all options which have boolean value
+                        * we can read option value by check that exists classname connected with option name.
+                        * Method returns true if class name contains common option, otherwise returns false.
+                        *
+                        * For example for option inline in widget we will check existing of class
+                        * ui-inline.
+                        *
+                        * @method _readPrefixedOptionFromElementClassname
+                        * @param {HTMLElement} element Main element of widget
+                        * @param {string} name Name of option which should be used
+                        * @return {boolean} If option value was successfully read
+                        * @member ns.widget.BaseWidget
+                        * @protected
+                        */
+                       prototype._readCommonOptionFromElementClassname = function (element, name) {
+                               var options = this.options,
+                                       classList = element.classList;
+
+                               switch (name) {
+                                       case "inline" :
+                                               if (classList.contains(commonClasses.INLINE)) {
+                                                       options.inline = true;
+                                                       return true;
+                                               }
+                                               break;
+                               }
+                               return false;
+                       };
+
+                       /**
+                        * Sets or removes class based on name conversion option, for all options which have boolean
+                        * value we can just set classname which is converted from camel case to dash style.
+                        * To correct use this method is required define in widget property _classesPrefix.
+                        *
+                        * For example for option middle in Button widget we will set or remove class ui-btn-middle.
+                        *
+                        * @method _setBooleanOption
+                        * @param {HTMLElement} element Main element of widget
+                        * @param {string} name Name of option which should be used
+                        * @param {boolean} value New value of option to set
+                        * @member ns.widget.BaseWidget
+                        * @protected
+                        * @return {false} always return false to block refreshing
+                        */
+                       prototype._setBooleanOption = function (element, name, value) {
+                               var classesPrefix = this._classesPrefix,
+                                       className;
+
+                               if (classesPrefix) {
+                                       className = classesPrefix + utilString.camelCaseToDashes(name);
+                                       element.classList.toggle(className, value);
+                               }
+
+                               // we don't need refresh, always can return false
+                               return false;
+                       };
+
+                       /**
+                        * For each options which has boolean value set or remove connected class.
+                        *
+                        * @method _setBooleanOptions
+                        * @param {HTMLElement} element Base element of the widget
+                        * @return {Object}
+                        * @member ns.widget.BaseWidget
+                        * @protected
+                        */
+                       prototype._setBooleanOptions = function (element) {
+                               var self = this,
+                                       classesPrefix = self._classesPrefix,
+                                       options = self.options;
+
+                               if (classesPrefix && options !== undefined) {
+                                       Object.keys(options).forEach(function (option) {
+                                               if (typeof options[option] === "boolean") {
+                                                       options[option] = self._setBooleanOption(element, option, options[option]);
+                                               }
+                                       });
+                               }
+                               return options;
+                       };
+
+                       prototype._processOptionObject = function (firstArgument) {
+                               var self = this,
+                                       key,
+                                       partResult,
+                                       refresh = false;
+
+                               for (key in firstArgument) {
+                                       if (firstArgument.hasOwnProperty(key)) {
+                                               partResult = self._oneOption(key, firstArgument[key]);
+                                               if (key !== undefined && firstArgument[key] !== undefined) {
+                                                       refresh = refresh || partResult;
+                                               }
+                                       }
+                               }
+                               return refresh;
+                       };
+
+                       /**
+                        * Gets or sets options of the widget.
+                        *
+                        * This method can work in many context.
+                        *
+                        * If first argument is type of object them, method set values for options given in object.
+                        * Keys of object are names of options and values from object are values to set.
+                        *
+                        * If you give only one string argument then method return value for given option.
+                        *
+                        * If you give two arguments and first argument will be a string then second argument will be
+                        * intemperate as value to set.
+                        *
+                        * @method option
+                        * @param {string|Object} [name] name of option
+                        * @param {*} [value] value to set
+                        * @member ns.widget.BaseWidget
+                        * @return {*} return value of option or null if method is called in setter context
+                        */
+                       prototype.option = function (name, value) {
+                               var self = this,
+                                       firstArgument = name,
+                                       secondArgument = value,
+                                       result = null,
+                                       refresh = false;
+
+                               if (typeof firstArgument === "string") {
+                                       result = self._oneOption(firstArgument, secondArgument);
+                                       if (secondArgument !== undefined) {
+                                               refresh = result;
+                                               result = null;
+                                       }
+                               } else if (typeof firstArgument === "object") {
+                                       refresh = self._processOptionObject(firstArgument);
+                               }
+                               if (refresh) {
+                                       self.refresh();
+                               }
+                               return result;
+                       };
+
+                       /**
+                        * Gets or sets one option of the widget.
+                        *
+                        * @method _oneOption
+                        * @param {string} field
+                        * @param {*} value
+                        * @member ns.widget.BaseWidget
+                        * @return {*}
+                        * @protected
+                        */
+                       prototype._oneOption = function (field, value) {
+                               var self = this,
+                                       methodName,
+                                       refresh = false;
+
+                               if (value === undefined) {
+                                       methodName = "_get" + (field[0].toUpperCase() + field.slice(1));
+
+                                       if (typeof self[methodName] === TYPE_FUNCTION) {
+                                               return self[methodName]();
+                                       }
+
+                                       return self.options[field];
+                               }
+
+                               methodName = "_set" + (field[0].toUpperCase() + field.slice(1));
+                               if (typeof self[methodName] === TYPE_FUNCTION) {
+                                       refresh = self[methodName](self.element, value);
+                                       if (self.element && (typeof value !== "object" || Array.isArray(value))) {
+                                               self.element.setAttribute("data-" + (field.replace(/[A-Z]/g, function (c) {
+                                                       return "-" + c.toLowerCase();
+                                               })), value);
+                                       }
+                               } else if (typeof value === "boolean") {
+                                       refresh = self._setBooleanOption(self.element, field, value);
+                               } else {
+                                       self.options[field] = value;
+
+                                       if (self.element && (typeof value !== "object" || Array.isArray(value))) {
+                                               self.element.setAttribute("data-" + (field.replace(/[A-Z]/g, function (c) {
+                                                       return "-" + c.toLowerCase();
+                                               })), value);
+                                               refresh = true;
+                                       }
+                               }
+
+                               if (value === "" && self.element) {
+                                       self.element.removeAttribute("data-" + (field.replace(/[A-Z]/g, function (c) {
+                                               return "-" + c.toLowerCase();
+                                       })));
+                               }
+
+                               return refresh;
+                       };
+
+                       /**
+                        * Returns true if widget has bounded events.
+                        *
+                        * This methods enables to check if the widget has bounded
+                        * events through the {@link ns.widget.BaseWidget#bindEvents} method.
+                        * @method isBound
+                        * @param {string} [type] Type of widget
+                        * @member ns.widget.BaseWidget
+                        * @ignore
+                        * @return {boolean} true if events are bounded
+                        */
+                       prototype.isBound = function (type) {
+                               var element = this.element;
+
+                               type = type || this.name;
+                               return element && element.hasAttribute(engineDataTau.bound) &&
+                                       element.getAttribute(engineDataTau.bound).indexOf(type) > -1;
+                       };
+
+                       /**
+                        * Returns true if widget is built.
+                        *
+                        * This methods enables to check if the widget was built
+                        * through the {@link ns.widget.BaseWidget#build} method.
+                        * @method isBuilt
+                        * @param {string} [type] Type of widget
+                        * @member ns.widget.BaseWidget
+                        * @ignore
+                        * @return {boolean} true if the widget was built
+                        */
+                       prototype.isBuilt = function (type) {
+                               var element = this.element;
+
+                               type = type || this.name;
+                               return element && element.hasAttribute(engineDataTau.built) &&
+                                       element.getAttribute(engineDataTau.built).indexOf(type) > -1;
+                       };
+
+                       /**
+                        * Protected method getting the value of widget
+                        * @method _getValue
+                        * @return {*}
+                        * @member ns.widget.BaseWidget
+                        * @template
+                        * @protected
+                        */
+                       /**
+                        * Protected method setting the value of widget
+                        * @method _setValue
+                        * @param {*} value
+                        * @return {*}
+                        * @member ns.widget.BaseWidget
+                        * @template
+                        * @protected
+                        */
+                       /**
+                        * Gets or sets value of the widget.
+                        *
+                        * @method value
+                        * @param {*} [value] New value of widget
+                        * @member ns.widget.BaseWidget
+                        * @return {*}
+                        */
+                       prototype.value = function (value) {
+                               var self = this;
+
+                               if (value !== undefined) {
+                                       if (typeof self._setValue === TYPE_FUNCTION) {
+                                               return self._setValue(value);
+                                       }
+                                       return self;
+                               }
+                               if (typeof self._getValue === TYPE_FUNCTION) {
+                                       return self._getValue();
+                               }
+                               return self;
+                       };
+
+                       /**
+                        * Triggers an event on widget's element.
+                        *
+                        * @method trigger
+                        * @param {string} eventName The name of event to trigger
+                        * @param {?*} [data] additional Object to be carried with the event
+                        * @param {boolean} [bubbles=true] Indicating whether the event
+                        * bubbles up through the DOM or not
+                        * @param {boolean} [cancelable=true] Indicating whether
+                        * the event is cancelable
+                        * @member ns.widget.BaseWidget
+                        * @return {boolean} False, if any callback invoked preventDefault on event object
+                        */
+                       prototype.trigger = function (eventName, data, bubbles, cancelable) {
+                               if (this.element) {
+                                       return eventUtils.trigger(this.element, eventName, data, bubbles, cancelable);
+                               }
+                               return false;
+                       };
+
+                       /**
+                        * Adds event listener to widget's element.
+                        * @method on
+                        * @param {string} eventName The name of event
+                        * @param {Function} listener Function called after event will be trigger
+                        * @param {boolean} [useCapture=false] useCapture Parameter of addEventListener
+                        * @member ns.widget.BaseWidget
+                        */
+                       prototype.on = function (eventName, listener, useCapture) {
+                               eventUtils.on(this.element, eventName, listener, useCapture);
+                       };
+
+                       /**
+                        * Removes event listener from  widget's element.
+                        * @method off
+                        * @param {string} eventName The name of event
+                        * @param {Function} listener Function call after event will be trigger
+                        * @param {boolean} [useCapture=false] useCapture Parameter of addEventListener
+                        * @member ns.widget.BaseWidget
+                        */
+                       prototype.off = function (eventName, listener, useCapture) {
+                               eventUtils.off(this.element, eventName, listener, useCapture);
+                       };
+
+                       prototype._framesFlow = function () {
+                               var self = this,
+                                       args = slice.call(arguments),
+                                       func = args.shift();
+
+                               if (typeof func === "function") {
+                                       func();
+                               }
+                               if (func !== undefined) {
+                                       util.requestAnimationFrame(function () {
+                                               self._framesFlow.apply(self, args);
+                                       });
+                               }
+                       };
+
+                       function callbacksFilter(item) {
+                               return !item.toRemove;
+                       }
+
+                       function callbacksForEach(item) {
+                               if (item.object[item.property] === item.value) {
+                                       util.requestAnimationFrame(item.callback.bind(item.object));
+                                       item.toRemove = true;
+                               }
+                       }
+
+                       function _controlWaitFor() {
+                               __callbacks.forEach(callbacksForEach);
+                               __callbacks = __callbacks.filter(callbacksFilter);
+                               if (__callbacks.length) {
+                                       util.requestAnimationFrame(_controlWaitFor);
+                               }
+                       }
+
+                       prototype._waitFor = function (property, value, callback) {
+                               var self = this;
+
+                               if (self[property] === value) {
+                                       callback.call(self);
+                               } else {
+                                       __callbacks = __callbacks || [];
+                                       __callbacks.push({
+                                               object: self,
+                                               property: property,
+                                               value: value,
+                                               callback: callback
+                                       });
+                               }
+                               _controlWaitFor();
+                       };
+
+                       function readDOMElementStateClassList(element, stateObject) {
+                               var classList = stateObject.classList;
+
+                               if (classList !== undefined) {
+                                       if (classList instanceof setUtils) {
+                                               classList.clear();
+                                       } else {
+                                               classList = new setUtils();
+                                               stateObject.classList = classList;
+                                       }
+                                       if (element.classList.length) {
+                                               slice.call(element.classList).forEach(function (className) {
+                                                       classList.add(className);
+                                               });
+                                       }
+                               }
+                       }
+
+                       function readDOMElementState(element, stateObject) {
+                               readDOMElementStateClassList(element, stateObject);
+                               if (stateObject.offsetWidth !== undefined) {
+                                       stateObject.offsetWidth = element.offsetWidth;
+                               }
+                               if (stateObject.style !== undefined) {
+                                       domUtils.extractCSSProperties(element, stateObject.style, null, true);
+                               }
+                               if (stateObject.children !== undefined) {
+                                       stateObject.children.forEach(function (child, index) {
+                                               readDOMElementState(element.children[index], child);
+                                       });
+                               }
+                       }
+
+                       function render(stateObject, element, isChild) {
+                               var recalculate = false;
+
+                               if (stateObject.classList !== undefined) {
+                                       slice.call(element.classList).forEach(function (className) {
+                                               if (!stateObject.classList.has(className)) {
+                                                       element.classList.remove(className);
+                                                       recalculate = true;
+                                               }
+                                       });
+                                       stateObject.classList.forEach(function (className) {
+                                               if (!element.classList.contains(className)) {
+                                                       element.classList.add(className);
+                                                       recalculate = true;
+                                               }
+                                       });
+                               }
+                               if (stateObject.style !== undefined) {
+                                       Object.keys(stateObject.style).forEach(function (styleName) {
+                                               element.style[styleName] = stateObject.style[styleName];
+                                       });
+                               }
+                               if (stateObject.children !== undefined) {
+                                       stateObject.children.forEach(function (child, index) {
+                                               render(child, element.children[index], true);
+                                       });
+                               }
+                               if (recalculate && !isChild) {
+                                       util.requestAnimationFrame(readDOMElementState.bind(null, element, stateObject));
+                               }
+                       }
+
+                       prototype._render = function (now) {
+                               var self = this,
+                                       stateDOM = self._stateDOM,
+                                       element = self.element;
+
+                               if (now === true) {
+                                       render(stateDOM, element, false);
+                               } else {
+                                       util.requestAnimationFrame(render.bind(null, stateDOM, element, false));
+                               }
+                       };
+
+                       prototype._initDOMstate = function () {
+                               readDOMElementState(this.element, this._stateDOM);
+                       };
+
+                       prototype._togglePrefixedClass = function (stateDOM, prefix, name) {
+                               var requireRefresh = false,
+                                       prefixedClassName = prefix + name;
+
+                               stateDOM.classList.forEach(function (className) {
+                                       if (className.indexOf(prefix) === 0 && prefixedClassName !== className) {
+                                               stateDOM.classList.delete(className);
+                                               requireRefresh = true;
+                                       }
+                               });
+                               if (!stateDOM.classList.has(prefixedClassName)) {
+                                       stateDOM.classList.add(prefixedClassName);
+                                       requireRefresh = true;
+                               }
+                               return requireRefresh;
+                       };
+
+                       /**
+                        * Create widget wrapper element
+                        * @param {string|null} [type=div] type of HTML element
+                        * @protected
+                        * @member ns.widget.BaseWidget
+                        * @return {HTMLElement}
+                        */
+                       prototype._createWrapper = function (type) {
+                               var wrapper;
+
+                               type = (typeof type === TYPE_STRING) ? type : "div";
+
+                               wrapper = document.createElement(type);
+                               wrapper.setAttribute(engineDataTau.widgetWrapper, true);
+                               return wrapper;
+                       }
+
+                       BaseWidget.prototype = prototype;
+
+                       // definition
+                       ns.widget.BaseWidget = BaseWidget;
+
+                       }(window.document, ns));
+
+/*global window, ns, define */
+/*jslint plusplus: true, nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #jQuery Mobile mapping widget
+ * Object maps widgets from TAU namespace to jQuery Mobile namespace.
+ * @class ns.jqm.widget
+ */
+(function (window, document) {
+       "use strict";
+                               /**
+                        * Alias to Array.slice function
+                        * @method slice
+                        * @member ns.jqm.widget
+                        * @private
+                        * @static
+                        */
+                       var slice = [].slice,
+                               $ = ns.jqm.jQuery,
+                               /**
+                                * Wrap function in closure and wrap first argument in jquery object
+                                * @param {Function} fn
+                                */
+                               wrapFn = function (fn) {
+                                       return function (el) {
+                                               return fn($(el));
+                                       };
+                               },
+                               /**
+                                * Alias to ns.engine
+                                * @member ns.jqm
+                                * @private
+                                * @static
+                                */
+                               engine = ns.engine,
+                               object = ns.util.object,
+                               jqmWidget = {
+                                       /**
+                                        * bind widget to jqm
+                                        * @method init
+                                        * @param {Object} engine ns.engine class
+                                        * @param {Object} definition widget definition
+                                        * @member ns.jqm.widget
+                                        * @static
+                                        */
+                                       init: function (engine, definition) {
+                                               var name = (definition.widgetNameToLowercase) ?
+                                                       definition.name.toLowerCase() :
+                                                       definition.name;
+
+                                               if ($) {
+                                                       document.addEventListener(name + "create", function (event) {
+                                                               var element = event.target,
+                                                                       instance = event.detail,
+                                                                       data = $(element).data(name);
+
+                                                               if (instance) {
+                                                                       instance.bindings = {};
+                                                                       instance.hoverable = {};
+                                                                       instance.focusable = {};
+                                                                       instance.document = $(element.style ? element.ownerDocument : element.document || element);
+                                                                       instance.window = $(instance.document[0].defaultView || instance.document[0].parentWindow);
+                                                                       object.merge(instance, data);
+                                                                       $(element).data(name, instance);
+                                                               }
+                                                       }, true);
+                                                       this.processDefinition(definition, engine);
+                                               }
+                                       },
+
+                                       /**
+                                        * bind widget to jqm
+                                        * @method processDefinition
+                                        * @param {Object} definition widget definition
+                                        * @param {Object} engine ns.engine class
+                                        * @member ns.jqm.widget
+                                        * @static
+                                        */
+                                       processDefinition: function (definition, engine) {
+                                               /*
+                                                * name of widget
+                                                * type string
+                                                */
+                                               var name = (definition.widgetNameToLowercase) ?
+                                                               definition.name.toLowerCase() :
+                                                               definition.name,
+                                                       /*
+                                                        * list of public methods
+                                                        * type Array
+                                                        */
+                                                       methods = definition.methods;
+
+                                               $.fn[name] = widgetConstructor(engine, name, methods, definition.name);
+                                               if (definition.namespace) {
+                                                       $[definition.namespace] = $[definition.namespace] || {};
+                                                       $[definition.namespace][definition.name.toLowerCase()] = definition.widgetClass;
+                                               }
+                                               definition = null;
+                                       }
+                               },
+                               eventType = engine.eventType;
+
+                       function widgetConstructor(engine, name, methods, instanceWidgetName) {
+                               /*
+                                * widget instance
+                                * type Object
+                                */
+                               var instance = null;
+
+                               return function () {
+                                       /*
+                                        * function arguments
+                                        * type Array
+                                        */
+                                       var args = slice.call(arguments),
+                                               /*
+                                                * element of jQuery collection
+                                                * type HTMLElement
+                                                */
+                                               element,
+                                               /*
+                                                * is built?
+                                                * type Boolean
+                                                */
+                                               built,
+                                               /*
+                                                * name of method
+                                                * type string
+                                                */
+                                               method,
+                                               /*
+                                                * result value
+                                                * type mixed
+                                                */
+                                               resultValue,
+                                               /*
+                                                * first argument of function
+                                                * type mixed
+                                                */
+                                               firstArg,
+                                               i,
+                                               options = {};
+
+                                       /*
+                                        * NOTE:
+                                        * The loop below contains some fixes/hacks for TizenSlider, Listview with FastScroll and AutoDividers
+                                        * and also Popup, please be aware while refactoring.
+                                        */
+                                       for (i = 0; i < this.length; i++) {
+                                               element = this.get(i);
+                                               switch (name) {
+                                                       case "slider":
+                                                               instance = engine.getBinding(element, "Slider") || engine.getBinding(element, "TizenSlider");
+                                                               break;
+                                                       default:
+                                                               instance = engine.getBinding(element, instanceWidgetName);
+                                               }
+
+                                               built = instance && instance.isBuilt();
+                                               firstArg = args.shift();
+                                               if (firstArg === undefined || typeof firstArg === "object") {
+                                                       if (typeof firstArg === "object") {
+                                                               options = firstArg;
+                                                       }
+                                                       if (!instance || !built) {
+                                                               engine.instanceWidget(element, instanceWidgetName, options);
+                                                       } else {
+                                                               instance.option(options);
+                                                       }
+                                               } else {
+                                                       if (instance === null) {
+                                                               return this;
+                                                       }
+                                                       method = firstArg;
+                                                       if (method === "destroy") {
+                                                               instance.destroy();
+                                                               return this;
+                                                       }
+                                                       if (methods.indexOf(method) < 0) {
+                                                               throw "Method " + method + " does not exist!";
+                                                       }
+                                                       if (name === "listview" &&
+                                                               method === "option" &&
+                                                               args[0] === "autodividersSelector" &&
+                                                               typeof args[1] === "function") {
+                                                               // wrap first argument of callback method in JQuery object
+                                                               args[1] = wrapFn(args[1]);
+                                                       }
+                                                       if (name === "popup" && method === "open") {
+                                                               // window.event is used because in Winset we open context popup by
+                                                               // $("#pop_text_only").popup("open") after clicking on input
+                                                               args[1] = window.event;
+                                                       }
+
+                                                       resultValue = instance[method].apply(instance, args);
+                                                       if (resultValue !== undefined) {
+                                                               if (resultValue !== instance) {
+                                                                       return resultValue;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       return this;
+                               };
+                       }
+
+                       /**
+                        * Callback for event widgetdefined, register widget in jqm namespace
+                        * @param {Event} event
+                        */
+                       function defineWidget(event) {
+                               jqmWidget.init(engine, event.detail);
+                       }
+
+                       /**
+                        * Removes event listeners on framework destroy.
+                        */
+                       function destroy() {
+                               document.removeEventListener(eventType.WIDGET_DEFINED, defineWidget, false);
+                               document.removeEventListener(eventType.INIT, defineOldWidgets, false);
+                               document.removeEventListener(eventType.DESTROY, destroy, false);
+                       }
+
+                       /**
+                        * Define widgets which names was changed for backward capability.
+                        */
+                       function defineOldWidgets() {
+                               engine.defineWidget(
+                                       "FixedToolbar",
+                                       "",
+                                       [],
+                                       ns.widget.Page,
+                                       "mobile"
+                               );
+                               engine.defineWidget(
+                                       "pagelayout",
+                                       "",
+                                       [],
+                                       ns.widget.Page,
+                                       "mobile"
+                               );
+                               engine.defineWidget(
+                                       "popupwindow",
+                                       "",
+                                       [],
+                                       ns.widget.Popup,
+                                       "tizen"
+                               );
+                               engine.defineWidget(
+                                       "ctxpopup",
+                                       "",
+                                       [],
+                                       ns.widget.Popup,
+                                       "tizen"
+                               );
+                       }
+
+                       document.addEventListener(eventType.WIDGET_DEFINED, defineWidget, false);
+                       document.addEventListener(eventType.INIT, defineOldWidgets, false);
+                       document.addEventListener(eventType.DESTROY, destroy, false);
+
+                       ns.jqm.widget = jqmWidget;
+                       }(window, window.document));
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Callback Utility
+ * Class creates a callback list
+ *
+ * Create a callback list using the following parameters:
+ *  options: an optional list of space-separated options that will change how
+ *            the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *    once:            will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *    memory:            will keep track of previous values and will call any callback added
+ *                    after the list has been fired right away with the latest "memorized"
+ *                    values (like a Deferred)
+ *
+ *    unique:            will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *    stopOnFalse:    interrupt callings when a callback returns false
+ * @class ns.util.callbacks
+ */
+(function (window, document, ns) {
+       "use strict";
+                               ns.util.callbacks = function (orgOptions) {
+
+                               var object = ns.util.object,
+                                       options = object.copy(orgOptions),
+                                       /**
+                                        * Alias to Array.slice function
+                                        * @method slice
+                                        * @member ns.util.callbacks
+                                        * @private
+                                        */
+                                       slice = [].slice,
+                                       /**
+                                        * Last fire value (for non-forgettable lists)
+                                        * @property {Object} memory
+                                        * @member ns.util.callbacks
+                                        * @private
+                                        */
+                                       memory,
+                                       /**
+                                        * Flag to know if list was already fired
+                                        * @property {boolean} fired
+                                        * @member ns.util.callbacks
+                                        * @private
+                                        */
+                                       fired,
+                                       /**
+                                        * Flag to know if list is currently firing
+                                        * @property {boolean} firing
+                                        * @member ns.util.callbacks
+                                        * @private
+                                        */
+                                       firing,
+                                       /**
+                                        * First callback to fire (used internally by add and fireWith)
+                                        * @property {number} [firingStart=0]
+                                        * @member ns.util.callbacks
+                                        * @private
+                                        */
+                                       firingStart,
+                                       /**
+                                        * End of the loop when firing
+                                        * @property {number} firingLength
+                                        * @member ns.util.callbacks
+                                        * @private
+                                        */
+                                       firingLength,
+                                       /**
+                                        * Index of currently firing callback (modified by remove if needed)
+                                        * @property {number} firingIndex
+                                        * @member ns.util.callbacks
+                                        * @private
+                                        */
+                                       firingIndex,
+                                       /**
+                                        * Actual callback list
+                                        * @property {Array} list
+                                        * @member ns.util.callbacks
+                                        * @private
+                                        */
+                                       list = [],
+                                       /**
+                                        * Stack of fire calls for repeatable lists
+                                        * @property {Array} stack
+                                        * @member ns.util.callbacks
+                                        * @private
+                                        */
+                                       stack = !options.once && [],
+                                       fire,
+                                       add,
+                                       self = {
+                                               /**
+                                                * Add a callback or a collection of callbacks to the list
+                                                * @method add
+                                                * @return {ns.util.callbacks} self
+                                                * @member ns.util.callbacks
+                                                */
+                                               add: function () {
+                                                       var start;
+
+                                                       if (list) {
+                                                               // First, we save the current length
+                                                               start = list.length;
+
+                                                               add(arguments);
+                                                               // Do we need to add the callbacks to the
+                                                               // current firing batch?
+                                                               if (firing) {
+                                                                       firingLength = list.length;
+                                                                       // With memory, if we're not firing then
+                                                                       // we should call right away
+                                                               } else if (memory) {
+                                                                       firingStart = start;
+                                                                       fire(memory);
+                                                               }
+                                                       }
+                                                       return this;
+                                               },
+                                               /**
+                                                * Remove a callback from the list
+                                                * @method remove
+                                                * @return {ns.util.callbacks} self
+                                                * @member ns.util.callbacks
+                                                */
+                                               remove: function () {
+                                                       if (list) {
+                                                               slice.call(arguments).forEach(function (arg) {
+                                                                       var index = list.indexOf(arg);
+
+                                                                       while (index > -1) {
+                                                                               list.splice(index, 1);
+                                                                               // Handle firing indexes
+                                                                               if (firing) {
+                                                                                       if (index <= firingLength) {
+                                                                                               firingLength--;
+                                                                                       }
+                                                                                       if (index <= firingIndex) {
+                                                                                               firingIndex--;
+                                                                                       }
+                                                                               }
+                                                                               index = list.indexOf(arg, index);
+                                                                       }
+                                                               });
+                                                       }
+                                                       return this;
+                                               },
+                                               /**
+                                                * Check if a given callback is in the list.
+                                                * If no argument is given,
+                                                * return whether or not list has callbacks attached.
+                                                * @method has
+                                                * @param {Function} fn
+                                                * @return {boolean}
+                                                * @member ns.util.callbacks
+                                                */
+                                               has: function (fn) {
+                                                       return fn ? !!list && list.indexOf(fn) > -1 : !!(list && list.length);
+                                               },
+                                               /**
+                                                * Remove all callbacks from the list
+                                                * @method empty
+                                                * @return {ns.util.callbacks} self
+                                                * @member ns.util.callbacks
+                                                */
+                                               empty: function () {
+                                                       list = [];
+                                                       firingLength = 0;
+                                                       return this;
+                                               },
+                                               /**
+                                                * Have the list do nothing anymore
+                                                * @method disable
+                                                * @return {ns.util.callbacks} self
+                                                * @member ns.util.callbacks
+                                                */
+                                               disable: function () {
+                                                       list = stack = memory = undefined;
+                                                       return this;
+                                               },
+                                               /**
+                                                * Is it disabled?
+                                                * @method disabled
+                                                * @return {boolean}
+                                                * @member ns.util.callbacks
+                                                */
+                                               disabled: function () {
+                                                       return !list;
+                                               },
+                                               /**
+                                                * Lock the list in its current state
+                                                * @method lock
+                                                * @return {ns.util.callbacks} self
+                                                * @member ns.util.callbacks
+                                                */
+                                               lock: function () {
+                                                       stack = undefined;
+                                                       if (!memory) {
+                                                               self.disable();
+                                                       }
+                                                       return this;
+                                               },
+                                               /**
+                                                * Is it locked?
+                                                * @method locked
+                                                * @return {boolean} stack
+                                                * @member ns.util.callbacks
+                                                */
+                                               locked: function () {
+                                                       return !stack;
+                                               },
+                                               /**
+                                                * Call all callbacks with the given context and
+                                                * arguments
+                                                * @method fireWith
+                                                * @param {Object} context
+                                                * @param {Array} args
+                                                * @return {ns.util.callbacks} self
+                                                * @member ns.util.callbacks
+                                                */
+                                               fireWith: function (context, args) {
+                                                       if (list && (!fired || stack)) {
+                                                               args = args || [];
+                                                               args = [context, args.slice ? args.slice() : args];
+                                                               if (firing) {
+                                                                       stack.push(args);
+                                                               } else {
+                                                                       fire(args);
+                                                               }
+                                                       }
+                                                       return this;
+                                               },
+                                               /**
+                                                * Call all the callbacks with the given arguments
+                                                * @method fire
+                                                * @return {ns.util.callbacks} self
+                                                * @member ns.util.callbacks
+                                                */
+                                               fire: function () {
+                                                       self.fireWith(this, arguments);
+                                                       return this;
+                                               },
+                                               /**
+                                                * To know if the callbacks have already been called at
+                                                * least once
+                                                * @method fired
+                                                * @return {boolean}
+                                                * @member ns.util.callbacks
+                                                */
+                                               fired: function () {
+                                                       return !!fired;
+                                               }
+                                       };
+                               /**
+                                * Adds functions to the callback list
+                                * @method add
+                                * @param {...*} argument
+                                * @member ns.util.bezierCurve
+                                * @private
+                                */
+
+                               add = function (args) {
+                                       slice.call(args).forEach(function (arg) {
+                                               var type = typeof arg;
+
+                                               if (type === "function") {
+                                                       if (!options.unique || !self.has(arg)) {
+                                                               list.push(arg);
+                                                       }
+                                               } else if (arg && arg.length && type !== "string") {
+                                                       // Inspect recursively
+                                                       add(arg);
+                                               }
+                                       });
+                               };
+                               /**
+                                * Fire callbacks
+                                * @method fire
+                                * @param {Array} data
+                                * @member ns.util.bezierCurve
+                                * @private
+                                */
+                               fire = function (data) {
+                                       memory = options.memory && data;
+                                       fired = true;
+                                       firingIndex = firingStart || 0;
+                                       firingStart = 0;
+                                       firingLength = list.length;
+                                       firing = true;
+                                       while (list && firingIndex < firingLength) {
+                                               if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {
+                                                       memory = false; // To prevent further calls using add
+                                                       break;
+                                               }
+                                               firingIndex++;
+                                       }
+                                       firing = false;
+                                       if (list) {
+                                               if (stack) {
+                                                       if (stack.length) {
+                                                               fire(stack.shift());
+                                                       }
+                                               } else if (memory) {
+                                                       list = [];
+                                               } else {
+                                                       self.disable();
+                                               }
+                                       }
+                               };
+
+                               return self;
+                       };
+
+                       }(window, window.document, ns));
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Deferred Utility
+ * Class creates object which can call registered callback depend from
+ * state of object..
+ * @class ns.util.deferred
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+*/(function (window, document, ns) {
+       "use strict";
+       
+                       var Deferred = function (callback) {
+                               var callbacks = ns.util.callbacks,
+                                       object = ns.util.object,
+                                       /**
+                                        * Register additional action for deferred object
+                                        * @property {Array} tuples
+                                        * @member ns.util.deferred
+                                        * @private
+                                        */
+                                       tuples = [
+                                               // action, add listener, listener list, final state
+                                               ["resolve", "done", callbacks({once: true, memory: true}), "resolved"],
+                                               ["reject", "fail", callbacks({once: true, memory: true}), "rejected"],
+                                               ["notify", "progress", callbacks({memory: true})]
+                                       ],
+                                       state = "pending",
+                                       deferred = {},
+                                       promise = {
+                                               /**
+                                                * Determine the current state of a Deferred object.
+                                                * @method state
+                                                * @return {"pending" | "resolved" | "rejected"} representing the current state
+                                                * @member ns.util.deferred
+                                                */
+                                               state: function () {
+                                                       return state;
+                                               },
+                                               /**
+                                                * Add handlers to be called when the Deferred object
+                                                * is either resolved or rejected.
+                                                * @method always
+                                                * @return {ns.util.deferred} self
+                                                * @member ns.util.deferred
+                                                */
+                                               always: function () {
+                                                       deferred.done(arguments).fail(arguments);
+                                                       return this;
+                                               },
+                                               /**
+                                                * Add handlers to be called when the Deferred object
+                                                * is resolved, rejected, or still in progress.
+                                                * @method then
+                                                * @return {Object} returns a new promise
+                                                * @member ns.util.deferred
+                                                */
+                                               then: function () { /* fnDone, fnFail, fnProgress */
+                                                       var functions = arguments;
+
+                                                       return new Deferred(function (newDefer) {
+                                                               tuples.forEach(function (tuple, i) {
+                                                                       var fn = (typeof functions[i] === "function") && functions[i];
+                                                                       // deferred[ done | fail | progress ] for forwarding actions to newDefer
+
+                                                                       deferred[tuple[1]](function () {
+                                                                               var returned = fn && fn.apply(this, arguments);
+
+                                                                               if (returned && (typeof returned.promise === "function")) {
+                                                                                       returned.promise()
+                                                                                               .done(newDefer.resolve)
+                                                                                               .fail(newDefer.reject)
+                                                                                               .progress(newDefer.notify);
+                                                                               } else {
+                                                                                       newDefer[tuple[0] + "With"](this === promise ? newDefer.promise() : this, fn ? [returned] : arguments);
+                                                                               }
+                                                                       });
+                                                               });
+                                                               functions = null;
+                                                       }).promise();
+                                               },
+                                               /**
+                                                * Get a promise for this deferred. If obj is provided,
+                                                * the promise aspect is added to the object
+                                                * @method promise
+                                                * @param {Object} obj
+                                                * @return {Object} return a Promise object
+                                                * @member ns.util.deferred
+                                                */
+                                               promise: function (obj) {
+                                                       if (obj) {
+                                                               return object.merge(obj, promise);
+                                                       }
+                                                       return promise;
+                                               }
+                                       };
+
+                               /**
+                                * alias for promise.then, Keep pipe for back-compat
+                                * @method pipe
+                                * @member ns.util.deferred
+                                */
+                               promise.pipe = promise.then;
+
+                               // Add list-specific methods
+
+                               tuples.forEach(function (tuple, i) {
+                                       var list = tuple[2],
+                                               stateString = tuple[3];
+
+                                       // promise[ done | fail | progress ] = list.add
+                                       promise[tuple[1]] = list.add;
+
+                                       // Handle state
+                                       if (stateString) {
+                                               list.add(function () {
+                                                       // state = [ resolved | rejected ]
+                                                       state = stateString;
+
+                                                       // mapping of values [ reject_list | resolve_list ].disable; progress_list.lock
+                                               }, tuples[i ^ 1][2].disable, tuples[2][2].lock);
+                                       }
+
+                                       // deferred[ resolve | reject | notify ]
+                                       deferred[tuple[0]] = function () {
+                                               deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments);
+                                               return this;
+                                       };
+                                       deferred[tuple[0] + "With"] = list.fireWith;
+                               });
+
+                               // Make the deferred a promise
+                               promise.promise(deferred);
+
+                               // Call given func if any
+                               if (callback) {
+                                       callback.call(deferred, deferred);
+                               }
+
+                               // All done!
+                               return deferred;
+                       };
+
+                       ns.util.deferred = Deferred;
+                       }(window, window.document, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Globalize Utility
+ * Object supports globalize options.
+ * @class ns.util.globalize
+ */
+
+(function (window, document, ns, Globalize) {
+       "use strict";
+                               var isGlobalizeInit = false,
+                               cldrDataCategory = {main: "main", supplemental: "supplemental"},
+                               cldrDataCache = {
+                                       main: {},
+                                       supplemental: {}
+                               },
+                               customDataCache = {},
+                               cldrJsonNames = {
+                                       main: [ //has language dependency
+                                               "currencies",
+                                               "ca-gregorian",
+                                               "numbers"
+                                       ],
+                                       supplemental: [
+                                               "scriptMetaData",
+                                               "likelySubtags",
+                                               "currencyData",
+                                               "plurals",
+                                               "timeData",
+                                               "weekData",
+                                               "numberingSystems" // this is for arab locale
+                                       ]
+                               },
+                               UtilDeferred = ns.util.deferred,
+                               globalizeInstance = null,
+                               rtlClassName = "ui-script-direction-rtl",
+                               extension = ".json",
+                               cldrDataName = "cldr-data",
+                               libPath = "lib",
+                               customLocalePathName = "locale";
+
+                       /**
+                        * Get filtered path from array
+                        * @method pathFilter
+                        * @param {Array} path
+                        * @return {string}
+                        * @private
+                        */
+                       function pathFilter(path) {
+                               return path.filter(function (item) {
+                                       return item;
+                               }).join("/");
+                       }
+
+                       /**
+                        * Get Language code
+                        * @method getLang
+                        * @param {string} language
+                        * @return {string}
+                        * @private
+                        */
+                       function getLang(language) {
+                               var lang = language ||
+                                               document.getElementsByTagName("html")[0].getAttribute("lang") ||
+                                               window.navigator.language.split(".")[0] || // Webkit, Safari + workaround for Tizen
+                                               "en",
+                                       countryCode,
+                                       countryCodeIdx = lang.lastIndexOf("-"),
+                                       ignoreCodes = ["Cyrl", "Latn", "Mong"]; // Not country code!
+
+                               if (countryCodeIdx !== -1) {    // Found country code!
+                                       countryCode = lang.substr(countryCodeIdx + 1);
+                                       if (ignoreCodes.join("-").indexOf(countryCode) < 0) {
+                                               // countryCode is not found from ignoreCodes.
+                                               // Make countryCode to uppercase.
+                                               lang = [lang.substr(0, countryCodeIdx), countryCode.toUpperCase()].join("-");
+                                       }
+                               }
+                               // NOTE: "en-US"" to "en" because we do not use CLDR full data TODO:Make Guide document for CLDR full data
+                               lang = getNeutralLang(lang);
+                               return lang;
+                       }
+
+                       /**
+                        * Get neutral language
+                        * @method getNeutralLang
+                        * @param {string} lang
+                        * @return {string}
+                        * @private
+                        */
+                       function getNeutralLang(lang) {
+                               var neutralLangIdx = lang.lastIndexOf("-"),
+                                       neutralLang;
+
+                               if (neutralLangIdx !== -1) {
+                                       neutralLang = lang.substr(0, neutralLangIdx);
+                               } else {
+                                       neutralLang = lang;
+                               }
+                               return neutralLang;
+                       }
+
+                       /**
+                        * Get path of CLDR data
+                        * @method getCldrFilesPath
+                        * @param {string} subPath
+                        * @param {string} lang
+                        * @param {string} jsonName
+                        * @return {string}
+                        * @private
+                        */
+                       function getCldrFilesPath(subPath, lang, jsonName) {
+                               var path;
+
+                               lang = (subPath === "supplemental") ? null : lang;
+
+                               // Default Globalize culture file path
+                               path = [
+                                       libPath,
+                                       cldrDataName,
+                                       subPath,
+                                       lang,
+                                       jsonName + extension //TODO:Use gregorian
+                               ];
+
+                               return pathFilter(path);
+                       }
+
+                       /**
+                        * Get path of Custom data which is matched with language
+                        * @method getCustomFilesPath
+                        * @param {string} lang
+                        * @return {string}
+                        * @private
+                        */
+                       function getCustomFilesPath(lang) {
+                               return pathFilter([
+                                       customLocalePathName,
+                                       lang + extension
+                               ]);
+                       }
+
+                       /**
+                        * Loads json file
+                        * @method loadJSON
+                        * @param {string} path
+                        * @return {Deferred}
+                        * @private
+                        */
+                       function loadJSON(path) {
+                               var xhrObj,
+                                       jsonObj,
+                                       info,
+                                       deferred = new UtilDeferred();
+
+                               if (path) {     // Invalid path -> Regard it as "404 Not Found" error.
+                                       try {
+                                               xhrObj = new XMLHttpRequest();
+                                               xhrObj.onreadystatechange = function () {
+                                                       if (xhrObj.readyState === 4) {
+                                                               switch (xhrObj.status) {
+                                                                       case 0:
+                                                                       case 200:
+                                                                               jsonObj = JSON.parse(xhrObj.responseText);
+                                                                               info = {"state": xhrObj.status, "path": path, "data": jsonObj};
+                                                                               deferred.resolve(info);
+                                                                               break;
+                                                                       case 404:
+                                                                               info = {"state": xhrObj.status, "path": path, "data": null};
+                                                                               deferred.reject(info);
+                                                                               break;
+                                                                       default:
+                                                                               jsonObj = JSON.parse(xhrObj.responseText);
+                                                                               info = {"state": xhrObj.status, "path": path, "data": jsonObj};
+                                                                               deferred.reject(info);
+                                                                               break;
+                                                               }
+                                                       }
+                                               };
+                                               xhrObj.open("GET", path, true);
+                                               xhrObj.send("");
+                                       } catch (e) {
+                                               info = {"state": -1, "path": path, "data": null};
+                                               deferred.reject(info);
+                                       }
+                               } else {
+                                       info = {"state": -2, "path": path, "data": null};
+                                       deferred.reject(info);
+
+                               }
+                               return deferred;
+                       }
+
+                       /**
+                        * Loads CLDR data
+                        * @method loadCldrData
+                        * @param {string|null} language
+                        * @param {string} category
+                        * @return {Deferred}
+                        * @private
+                        */
+                       function loadCldrData(language, category) {
+                               var path,
+                                       cldrDataTotal = cldrJsonNames[category].length,
+                                       cache = null,
+                                       deferred = new UtilDeferred();
+
+                               if (language) { // when category is "main" , language must have value like "en" , "ko" .etc
+                                       if (!cldrDataCache[category].hasOwnProperty(language)) {
+                                               cache = cldrDataCache[category][language] = {};
+                                       } else {
+                                               cache = cldrDataCache[category][language];
+                                       }
+                               } else { // when category is "supplement" language is empty
+                                       cache = cldrDataCache[category];
+                               }
+
+                               cldrJsonNames[category].forEach(function (fileName) {
+
+                                       path = getCldrFilesPath(category, language, fileName);
+
+                                       if (!cache[path]) {
+                                               loadJSON(path).then(function (info) {
+                                                       var jsonObj = info.data,
+                                                               key = info.path;
+
+                                                       cache[key] = jsonObj; //cache likelySubtags for Globalize
+                                                       Globalize.load(jsonObj); //load likelySubtags json
+                                                       if (Object.keys(cache).length === cldrDataTotal) {
+                                                               deferred.resolve(language);
+                                                       }
+
+                                               }, deferred.reject);
+
+                                       } else {
+                                               //Globalize.load(cache[path]);
+                                               deferred.resolve(language);
+                                       }
+                               });
+
+                               return deferred;
+                       }
+
+                       /**
+                        * Loads custom data
+                        * @method loadCustomData
+                        * @param {string} localeId
+                        * @return {Deferred}
+                        * @private
+                        */
+                       function loadCustomData(localeId) {
+                               var path = null,
+                                       deferred = new UtilDeferred(),
+                                       cache = customDataCache;
+
+                               path = getCustomFilesPath(localeId);
+                               if (!cache[path]) {
+                                       loadJSON(path).then(function (info) {
+                                               cache[path] = info;
+                                               info.fromCache = false;
+                                               deferred.resolve(info);
+                                       },
+                                               deferred.reject);
+                               } else {
+                                       cache[path].fromCache = true;
+                                       deferred.resolve(cache[path]);
+                               }
+                               return deferred;
+                       }
+
+                       /**
+                        * Init Globalize
+                        * @method initGlobalize
+                        * @return {Deferred}
+                        * @private
+                        */
+                       function initGlobalize() {
+                               var deferred = new UtilDeferred();
+
+                               isGlobalizeInit = true;
+                               loadCldrData(null, cldrDataCategory.supplemental).then(deferred.resolve, deferred.reject);
+                               return deferred;
+                       }
+
+                       /**
+                        * Check script direction of locale
+                        * @method isRTL
+                        * @param {string} locale
+                        * @private
+                        */
+                       function isRTL(locale) {
+                               var path = getCldrFilesPath(cldrDataCategory.supplemental, locale, cldrJsonNames.supplemental[0]),
+                                       scriptMetaData = cldrDataCache.supplemental[path] || null,
+                                       result = null;
+
+                               locale = Globalize.locale().attributes.script;
+
+                               if (scriptMetaData) {
+                                       scriptMetaData.some(function (item) {
+                                               if (item.IDENTIFIER === locale) {
+                                                       switch (item.RTL) {
+                                                               case "YES":
+                                                                       result = true;
+                                                                       break;
+                                                               case "NO":
+                                                                       result = false;
+                                                                       break;
+                                                               case "UNKNOWN":
+                                                                       result = true;
+                                                                       break;
+                                                       }
+                                                       return true;
+                                               }
+                                               return false;
+                                       });
+                                       return result;
+                               } else {
+                                       throw new Error("Globalize is not initialized");
+                               }
+                       }
+
+
+                       /**
+                        * Load Basic Locale files for "locale id" in cldr-data directory
+                        * @method loadLocaleData
+                        * Language code. ex) en-US, en, ko-KR, ko, If language is not
+                        * given,
+                        * first. Check window.tizen.systeminfo to get locale information
+                        * second. Check language from html "lang" attribute.
+                        * @param {string} localeId
+                        * @return {Deferred}
+                        * @private
+                        */
+                       function loadLocaleData(localeId) {
+                               var deferred = new UtilDeferred();
+
+                               if (!isGlobalizeInit) {
+                                       initGlobalize().then(function () {
+                                               loadLocaleData(localeId).then(function (locale) {
+                                                       deferred.resolve(locale);
+                                               }, deferred.reject);
+                                       });
+                               } else {
+                                       if (window.tizen && !localeId) {
+                                               window.tizen.systeminfo.getPropertyValue("LOCALE", function (locale) {
+                                                       var countryLang = locale.country;
+
+                                                       if (countryLang) {
+                                                               countryLang = getNeutralLang(countryLang.replace("_", "-")); //TODO: Need to fix local id type
+                                                       }
+                                                       loadCldrData(countryLang, cldrDataCategory.main).then(function (locale) {
+                                                               deferred.resolve(locale);
+                                                       }, deferred.reject);
+                                               });
+                                       } else {
+                                               //first  find "lang" attribute in html
+                                               //second find "locale" in navigator in window.navigator
+                                               loadCldrData(localeId, cldrDataCategory.main).then(function (locale) {
+                                                       deferred.resolve(locale);
+                                               }, deferred.reject);
+
+                                       }
+                               }
+                               return deferred;
+                       }
+
+                       /**
+                        * Update class of body to indicate right-to-left language
+                        * @method updateScriptDirectionClass
+                        * if give language is rtl type than add class ("ui-script-direction-rtl") in body element
+                        * @private
+                        */
+                       function updateScriptDirectionClass() {
+                               var rtl = isRTL(Globalize.locale().locale),
+                                       body = document.body,
+                                       classList = body.classList;
+
+                               if (rtl) {
+                                       if (!classList.contains(rtlClassName)) {
+                                               classList.add(rtlClassName);
+                                       }
+                                       Globalize.prototype.rtl = true;
+                               } else {
+                                       if (classList.contains(rtlClassName)) {
+                                               classList.remove(rtlClassName);
+                                       }
+                                       Globalize.prototype.rtl = false;
+                               }
+                       }
+
+                       /**
+                        * Update Globalize prototype
+                        * @method updateGlobalize
+                        * @private
+                        */
+                       function updateGlobalize() {
+                               Globalize.prototype.getLocale = ns.util.globalize.getLocale;
+                               Globalize.prototype.getCalendar = ns.util.globalize.getCalendar;
+                       }
+
+                       /**
+                        * Check Globalize and Cldr object in window object to use core/util/globalize.js
+                        * @method checkDependency
+                        * @private
+                        */
+                       function checkDependency() {
+                               return (window.Globalize && window.Cldr);
+                       }
+
+                       ns.util.globalize = {
+
+                               /**
+                                * Put the module into module array of core.util.globalize
+                                * @method importModule
+                                * @param {string} fileName
+                                * @member ns.util.globalize
+                                * @static
+                                */
+                               importModule: function (fileName) {
+                                       var module = fileName.split("/"),
+                                               path = module.shift(),
+                                               moduleMain = cldrJsonNames.main,
+                                               moduleSupplemental = cldrJsonNames.supplemental,
+                                               i = 0,
+                                               j;
+
+                                       fileName = module.shift();
+
+                                       switch (path) {
+                                               case "main":
+                                                       for (j = moduleMain.length; i < j; i++) {
+                                                               if (moduleMain[i] === fileName) {
+                                                                       return;
+                                                               }
+                                                       }
+                                                       moduleMain.push(fileName);
+                                                       break;
+                                               case "supplemental":
+                                                       for (j = moduleSupplemental.length; i < j; i++) {
+                                                               if (moduleSupplemental[i] === fileName) {
+                                                                       return;
+                                                               }
+                                                       }
+                                                       moduleSupplemental.push(fileName);
+                                                       break;
+                                       }
+                               },
+
+                               /**
+                                * Set Locale. This API is Async API.
+                                * Please use deferred callback functions which are returned( .done(), .then() .etc)
+                                * @method setLocale
+                                * @param {string} localeId
+                                * @member ns.util.globalize
+                                * @return {Deferred}
+                                * @static
+                                */
+                               setLocale: function (localeId) {
+                                       var deferred = new UtilDeferred();
+
+                                       localeId = getLang(localeId);
+                                       if (checkDependency()) {
+                                               loadLocaleData(localeId)
+                                                       .then(function (locale) {
+                                                               Globalize.locale(locale);
+                                                               globalizeInstance = new Globalize(locale);
+                                                               return locale;
+                                                       }, deferred.reject)
+                                                       .done(function (locale) {
+                                                               loadCustomData(locale)
+                                                                       .then(function (info) {
+                                                                               if (!info.fromCache) { // data
+                                                                                       Globalize.loadMessages(info.data);
+                                                                               }
+                                                                               globalizeInstance = new Globalize(locale);
+                                                                               deferred.resolve(globalizeInstance);
+                                                                       }, function () {
+                                                                               globalizeInstance = new Globalize(locale);
+                                                                               deferred.resolve(globalizeInstance); //we do not care of failure of "loadCustomData on purpose"
+                                                                       });
+                                                       })
+                                                       .done(updateScriptDirectionClass)
+                                                       .done(updateGlobalize);
+
+                                               return deferred;
+                                       } else {
+                                               throw new Error("Globalize is not loaded");
+                                       }
+
+                               },
+
+                               /**
+                                * Get Locale.
+                                * @method getLocale
+                                * @return {string} Current locale
+                                * @member ns.util.globalize
+                                * @static
+                                */
+                               getLocale: function () {
+                                       if (checkDependency()) {
+                                               return Globalize.locale().locale;
+                                       } else {
+                                               throw new Error("Globalize is not loaded");
+                                       }
+
+                               },
+
+                               /**
+                                * Get gregorian calendar.
+                                * @method getCalendar
+                                * @return {Object} gregorian calendar data given locale.
+                                * @member ns.util.globalize
+                                * @static
+                                */
+                               getCalendar: function () {
+                                       //default is gregorian calendar
+                                       //TODO: Need to implementation in jquery/globalize
+                                       //TODO: Need to implement validation
+                                       if (checkDependency() && globalizeInstance) {
+                                               return globalizeInstance.cldr.main("dates/calendars/gregorian");
+                                       } else {
+                                               throw new Error("Globalize is not initialized");
+                                       }
+
+                               }
+
+                       };
+
+                       }(window, window.document, ns, window.Globalize));
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Zoom Utility
+ * Object supports enabling and disabling zoom.
+ * @class ns.util.zoom
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var meta = document.querySelector("meta[name=viewport]"),
+                               initialContent = meta && meta.getAttribute("content"),
+                               disabledZoom = initialContent + ",maximum-scale=1, user-scalable=no",
+                               enabledZoom = initialContent + ",maximum-scale=10, user-scalable=yes",
+                               disabledInitially = /(user-scalable[\s]*=[\s]*no)|(maximum-scale[\s]*=[\s]*1)[$,\s]/.test(initialContent),
+                               zoom = {
+                                       /**
+                                        * Status of zoom
+                                        * @property {boolean} enabled
+                                        * @static
+                                        * @member ns.util.zoom
+                                        */
+                                       enabled: !disabledInitially,
+                                       /**
+                                        * Flag shows actual locked/unlocked status
+                                        * @property {boolean} [locked=false]
+                                        * @static
+                                        * @member ns.util.zoom
+                                        */
+                                       locked: false,
+                                       /**
+                                        * Disable zoom
+                                        * @method disable
+                                        * @param {boolean} lock
+                                        * @static
+                                        * @member ns.util.zoom
+                                        */
+                                       disable: function (lock) {
+                                               if (!disabledInitially && !zoom.locked) {
+                                                       if (meta) {
+                                                               meta.setAttribute("content", disabledZoom);
+                                                       }
+                                                       zoom.enabled = false;
+                                                       zoom.locked = lock || false;
+                                               }
+                                       },
+                                       /**
+                                        * Enable zoom
+                                        * @method enable
+                                        * @param {boolean} unlock
+                                        * @static
+                                        * @member ns.util.zoom
+                                        */
+                                       enable: function (unlock) {
+                                               if (!disabledInitially && (!zoom.locked || unlock === true)) {
+                                                       if (meta) {
+                                                               meta.setAttribute("content", enabledZoom);
+                                                       }
+                                                       zoom.enabled = true;
+                                                       zoom.locked = false;
+                                               }
+                                       },
+                                       /**
+                                        * Restore zoom
+                                        * @method restore
+                                        * @static
+                                        * @member ns.util.zoom
+                                        */
+                                       restore: function () {
+                                               if (!disabledInitially) {
+                                                       if (meta) {
+                                                               meta.setAttribute("content", initialContent);
+                                                       }
+                                                       zoom.enabled = true;
+                                               }
+                                       }
+                               };
+
+                       ns.util.zoom = zoom;
+                       }(window, window.document, ns));
+
+/*global window, ns, define, XMLHttpRequest, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Load Utility
+ * Object contains function to load external resources.
+ * @class ns.util.load
+ */
+(function (document, ns) {
+       "use strict";
+       
+                       /**
+                        * Local alias for document HEAD element
+                        * @property {HTMLHeadElement} head
+                        * @static
+                        * @private
+                        * @member ns.util.load
+                        */
+                       var head = document.head,
+                               /**
+                                * Local alias for document styleSheets element
+                                * @property {HTMLStyleElement} styleSheets
+                                * @static
+                                * @private
+                                * @member ns.util.load
+                                */
+                               styleSheets = document.styleSheets,
+                               /**
+                                * Local alias for ns.util.DOM
+                                * @property {Object} utilsDOM Alias for {@link ns.util.DOM}
+                                * @member ns.util.load
+                                * @static
+                                * @private
+                                */
+                               utilDOM = ns.util.DOM,
+                               getNSData = utilDOM.getNSData,
+                               setNSData = utilDOM.setNSData,
+                               load = ns.util.load || {},
+                               /**
+                                * Regular expression for extracting path to the image
+                                * @property {RegExp} IMAGE_PATH_REGEXP
+                                * @static
+                                * @private
+                                * @member ns.util.load
+                                */
+                               IMAGE_PATH_REGEXP = /url\((\.\/)?images/gm,
+                               /**
+                                * Regular expression for extracting url from css content
+                                * @property {RegExp} CSS_URL_REGEXP
+                                * @static
+                                * @private
+                                * @member ns.util.load
+                                */
+                               CSS_URL_REGEXP = /url\((.+)\)/gm,
+                               /**
+                                * Regular expression for extracting path to the css
+                                * @property {RegExp} CSS_FILE_REGEXP
+                                * @static
+                                * @private
+                                * @member ns.util.load
+                                */
+                               CSS_FILE_REGEXP = /[^/]+\.css$/,
+                               /**
+                                * Regular expression for extracting base path of css file
+                                * @property {RegExp} BASE_PATH_REGEXP
+                                * @static
+                                * @private
+                                * @member ns.util.load
+                                */
+                               BASE_PATH_REGEXP = /[^\/]+$/;
+
+                       /**
+                        * Load file
+                        * (synchronous loading)
+                        * @method loadFileSync
+                        * @param {string} scriptPath
+                        * @param {?Function} successCB
+                        * @param {?Function} errorCB
+                        * @static
+                        * @private
+                        * @member ns.util.load
+                        */
+                       function loadFileSync(scriptPath, successCB, errorCB) {
+                               var xhrObj = new XMLHttpRequest();
+
+                               // open and send a synchronous request
+                               xhrObj.open("GET", scriptPath, false);
+                               xhrObj.send();
+                               // add the returned content to a newly created script tag
+                               if (xhrObj.status === 200 || xhrObj.status === 0) {
+                                       if (typeof successCB === "function") {
+                                               successCB(xhrObj, xhrObj.status);
+                                       }
+                               } else {
+                                       if (typeof errorCB === "function") {
+                                               errorCB(xhrObj, xhrObj.status, new Error(xhrObj.statusText));
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Load JSON file
+                        * (asynchronous loading)
+                        * @method loadJSON
+                        * @param {string} scriptPath
+                        * @param {?Function} successCB
+                        * @param {?Function} errorCB
+                        * @static
+                        * @member ns.util.load
+                        */
+                       function loadJSON(scriptPath, successCB, errorCB) {
+                               var xhrObj = new XMLHttpRequest(),
+                                       responseJSON,
+                                       onsuccess = function () {
+                                               if (xhrObj.status === 200) {
+                                                       if (typeof successCB === "function") {
+                                                               try {
+                                                                       responseJSON = JSON.parse(xhrObj.responseText);
+                                                                       successCB(responseJSON, xhrObj.status);
+                                                               } catch (err) {
+                                                                       errorCB(xhrObj, xhrObj.status, new Error(err));
+                                                               }
+                                                       }
+                                               } else {
+                                                       if (typeof errorCB === "function") {
+                                                               errorCB(xhrObj, xhrObj.status, new Error(xhrObj.statusText));
+                                                       }
+                                               }
+                                       },
+                                       onreadystatechange = function () {
+                                               if (xhrObj.status === 4) {
+                                                       onsuccess();
+                                               }
+                                       };
+
+                               // open and send a synchronous request
+                               xhrObj.open("GET", scriptPath, true);
+                               xhrObj.onreadystatechange = onreadystatechange;
+                               xhrObj.onload = onsuccess;
+                               xhrObj.onerror = function (err) {
+                                       errorCB(xhrObj, xhrObj.status, new Error(err));
+                               };
+                               xhrObj.send();
+                       }
+
+                       /**
+                        * Callback function on javascript load success
+                        * @method scriptSyncSuccess
+                        * @private
+                        * @static
+                        * @param {?Function} successCB
+                        * @param {?Function} xhrObj
+                        * @param {?string} status
+                        * @member ns.util.load
+                        */
+                       function scriptSyncSuccess(successCB, xhrObj, status) {
+                               var script = document.createElement("script");
+
+                               script.type = "text/javascript";
+                               script.text = xhrObj.responseText;
+                               document.body.appendChild(script);
+                               if (typeof successCB === "function") {
+                                       successCB(xhrObj, status);
+                               }
+                       }
+
+
+                       /**
+                        * Add script to document
+                        * (synchronous loading)
+                        * @method scriptSync
+                        * @param {string} scriptPath
+                        * @param {?Function} successCB
+                        * @param {?Function} errorCB
+                        * @static
+                        * @member ns.util.load
+                        */
+                       function scriptSync(scriptPath, successCB, errorCB) {
+                               loadFileSync(scriptPath, scriptSyncSuccess.bind(null, successCB), errorCB);
+                       }
+
+                       /**
+                        * Callback function on css load success
+                        * @method cssSyncSuccess
+                        * @param {string} cssPath
+                        * @param {?Function} successCB
+                        * @param {Object} xhrObj
+                        * @member ns.util.load
+                        * @static
+                        * @private
+                        */
+                       function cssSyncSuccess(cssPath, successCB, xhrObj) {
+                               var css = document.createElement("style"),
+                                       pathRelatedToBaseApp = cssPath.replace(BASE_PATH_REGEXP, "");
+
+                               css.type = "text/css";
+                               css.textContent = xhrObj.responseText.replace(
+                                       CSS_URL_REGEXP,
+                                       "url(" + pathRelatedToBaseApp + "$1)"
+                               );
+                               if (typeof successCB === "function") {
+                                       successCB(css);
+                               }
+                       }
+
+                       /**
+                        * Callback function on tau theme css load success
+                        * @method cssThemeSyncSuccess
+                        * @param {string} cssPath
+                        * @param {?Function} successCB
+                        * @param {Object} xhrObj
+                        * @member ns.util.load
+                        * @static
+                        * @private
+                        */
+                       function cssThemeSyncSuccess(cssPath, successCB, xhrObj) {
+                               var css = document.createElement("style");
+
+                               css.type = "text/css";
+                               css.textContent = xhrObj.responseText.replace(
+                                       IMAGE_PATH_REGEXP,
+                                       "url(" + cssPath.replace(CSS_FILE_REGEXP, "images")
+                               );
+                               if (typeof successCB === "function") {
+                                       successCB(css);
+                               }
+                       }
+
+                       /**
+                        * Add css to document
+                        * (synchronous loading)
+                        * @method cssSync
+                        * @param {string} cssPath
+                        * @param {?Function} successCB
+                        * @param {?Function} errorCB
+                        * @static
+                        * @member ns.util.load
+                        */
+                       function cssSync(cssPath, successCB, errorCB) {
+                               loadFileSync(cssPath, cssSyncSuccess.bind(null, cssPath, successCB), errorCB);
+                       }
+
+                       /**
+                        * Add tau theme css to document
+                        * (synchronous loading)
+                        * @method cssThemeSync
+                        * @param {string} cssPath
+                        * @param {?Function} successCB
+                        * @param {?Function} errorCB
+                        * @static
+                        * @member ns.util.load
+                        */
+                       function cssThemeSync(cssPath, successCB, errorCB) {
+                               loadFileSync(cssPath, cssThemeSyncSuccess.bind(null, cssPath, successCB), errorCB);
+                       }
+
+                       /**
+                        * Add element to head tag
+                        * @method addElementToHead
+                        * @param {HTMLElement} element
+                        * @param {boolean} [asFirstChildElement=false]
+                        * @member ns.util.load
+                        * @static
+                        */
+                       function addElementToHead(element, asFirstChildElement) {
+                               var firstElement;
+
+                               if (head) {
+                                       if (asFirstChildElement) {
+                                               firstElement = head.firstElementChild;
+                                               if (firstElement) {
+                                                       head.insertBefore(element, firstElement);
+                                                       return;
+                                               }
+                                       }
+                                       head.appendChild(element);
+                               }
+                       }
+
+                       /**
+                        * Create HTML link element with href
+                        * @method makeLink
+                        * @param {string} href
+                        * @return {HTMLLinkElement}
+                        * @member ns.util.load
+                        * @static
+                        */
+                       function makeLink(href) {
+                               var cssLink = document.createElement("link");
+
+                               cssLink.setAttribute("rel", "stylesheet");
+                               cssLink.setAttribute("href", href);
+                               cssLink.setAttribute("name", "tizen-theme");
+                               return cssLink;
+                       }
+
+                       /**
+                        * Adds the given node to document head or replaces given 'replaceElement'.
+                        * Additionally adds 'name' and 'theme-name' attribute
+                        * @param {HTMLElement} node Element to be placed as theme link
+                        * @param {string} themeName Theme name passed to the element
+                        * @param {HTMLElement} [replaceElement=null] If replaceElement is given it gets replaced by node
+                        */
+                       function addNodeAsTheme(node, themeName, replaceElement) {
+                               setNSData(node, "name", "tizen-theme");
+                               setNSData(node, "theme-name", themeName);
+
+                               if (replaceElement) {
+                                       replaceElement.parentNode.replaceChild(node, replaceElement);
+                               } else {
+                                       addElementToHead(node, true);
+                               }
+                       }
+
+                       /**
+                        * Add css link element to head if not exists
+                        * @method themeCSS
+                        * @param {string} path
+                        * @param {string} themeName
+                        * @param {boolean} [embed=false] Embeds the CSS content to the document
+                        * @member ns.util.load
+                        * @static
+                        */
+                       function themeCSS(path, themeName, embed) {
+                               var i,
+                                       styleSheetsLength = styleSheets.length,
+                                       ownerNode,
+                                       previousElement = null,
+                                       linkElement;
+                               // Find css link or style elements
+
+                               for (i = 0; i < styleSheetsLength; i++) {
+                                       ownerNode = styleSheets[i].ownerNode;
+
+                                       // We try to find a style / link node that matches current style or is linked to
+                                       // the proper theme. We cannot use ownerNode.href because this returns the absolute path
+                                       if (getNSData(ownerNode, "name") === "tizen-theme" || ownerNode.getAttribute("href") === path) {
+                                               if (getNSData(ownerNode, "theme-name") === themeName) {
+                                                       // Nothing to change
+                                                       return;
+                                               }
+                                               previousElement = ownerNode;
+                                               break;
+                                       }
+                               }
+
+                               if (embed) {
+                                       // Load and replace old styles or append new styles
+                                       cssThemeSync(path, function (styleElement) {
+                                               addNodeAsTheme(styleElement, themeName, previousElement);
+                                       }, function (xhrObj, xhrStatus) {
+                                               ns.warn("There was a problem when loading '" + themeName + "', status: " + xhrStatus);
+                                       });
+                               } else {
+                                       linkElement = makeLink(path);
+                                       addNodeAsTheme(linkElement, themeName, previousElement);
+                               }
+                       }
+
+                       /**
+                        * In debug mode add time to url to disable cache
+                        * @property {string} cacheBust
+                        * @member ns.util.load
+                        * @static
+                        */
+                       load.cacheBust = (document.location.href.match(/debug=true/)) ? "?cacheBust=" + (new Date()).getTime() : "";
+                       // the binding a local methods with the namespace
+                       load.scriptSync = scriptSync;
+                       load.addElementToHead = addElementToHead;
+                       load.makeLink = makeLink;
+                       load.themeCSS = themeCSS;
+                       load.cssSync = cssSync;
+                       load.JSON = loadJSON;
+
+                       ns.util.load = load;
+                       }(window.document, ns));
+
+/*global window, define, ns*/
+/*jslint bitwise: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Copyright (c) 2010 - 2014 Samsung Electronics Co., Ltd.
+ * License : MIT License V2
+ */
+/**
+ * #Framework Data Object
+ * Object contains properties describing run time environment.
+ * @class ns.frameworkData
+ */
+(function (document, ns) {
+       "use strict";
+                               var slice = Array.prototype.slice,
+                               FRAMEWORK_WEBUI = "tizen-web-ui-fw",
+                               FRAMEWORK_TAU = "tau",
+                               IS_TAU_REGEXP = /(^|[\\\/])(tau(\.full|\.mvc)?(\.min)?\.js)$/,
+                               // Regexp detect framework js file
+                               LIB_FILENAME_REGEXP = /(^|[\\\/])(tau|tizen-web-ui-fw)(\.full|\.mvc|\.custom)?(\.min)?\.js$/,
+                               // Regexp detect framework css file
+                               CSS_FILENAME_REGEXP = /(^|[\\\/])(tau|tizen-web-ui-fw)(\.full|\.mvc|\.custom)?(\.min)?\.css$/,
+                               // Regexp detect correct theme name
+                               TIZEN_THEMES_REGEXP = /^(changeable|white|black|default)$/i,
+                               MINIFIED_REGEXP = /\.min\.js$/,
+                               frameworkData = {
+                                       /**
+                                        * The name of framework
+                                        * @property {string} frameworkName="tizen-web-ui-fw"
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       frameworkName: FRAMEWORK_WEBUI,
+                                       /**
+                                        * The root directory of framework on current device
+                                        * @property {string} rootDir="/usr/share/tizen-web-ui-fw"
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       rootDir: "/usr/share/" + FRAMEWORK_WEBUI,
+                                       /**
+                                        * The version of framework
+                                        * @property {string} version="latest"
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       version: "latest",
+                                       /**
+                                        * The theme of framework
+                                        * @property {string} theme="default"
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       theme: "default",
+                                       /**
+                                        * Tells if the theme that is set was already loaded
+                                        * @property {boolean} themeLoaded=false
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       themeLoaded: false,
+                                       /**
+                                        * The default width of viewport in framework.
+                                        * @property {number} defaultViewportWidth=360
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       defaultViewportWidth: 360,
+                                       /**
+                                        * The type of width of viewport in framework.
+                                        * @property {string} viewportWidth="device-width"
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       viewportWidth: "device-width",
+                                       /**
+                                        * Determines whether the viewport should be scaled
+                                        * @property {boolean} isMinified=false
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       viewportScale: false,
+                                       /**
+                                        * The default font size in framework.
+                                        * @property {number} defaultFontSize=22
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       defaultFontSize: 22,
+                                       /**
+                                        * Determines whether the framework is minified
+                                        * @property {boolean} minified=false
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       minified: false,
+                                       /**
+                                        * Determines the capability of device
+                                        * @property {Object} deviceCapa
+                                        * @property {boolean} deviceCapa.inputKeyBack=true
+                                        * Determines whether the back key is supported.
+                                        * @property {boolean} deviceCapa.inputKeyMenu=true
+                                        *  Determines whether the menu key is supported.
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       deviceCapa: {inputKeyBack: true, inputKeyMenu: true},
+                                       /**
+                                        * Determines whether the framework is loaded in debug profile.
+                                        * @property {boolean} debug=false
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       debug: false,
+                                       /**
+                                        * The version of framework's package
+                                        * @property {string} pkgVersion="0.2.83"
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       pkgVersion: "0.2.83",
+                                       /**
+                                        * The prefix of data used in framework
+                                        * @property {string} dataPrefix="data-framework-"
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       dataPrefix: "data-framework-",
+                                       /**
+                                        * The profile of framework
+                                        * @property {string} profile=""
+                                        * @member ns.frameworkData
+                                        * @static
+                                        */
+                                       profile: ""
+                               };
+
+                       /**
+                        * Get data-* params from <script> tag, and set tizen.frameworkData.* values
+                        * Returns true if proper <script> tag is found, or false if not.
+                        * @method getParams
+                        * @return {boolean} Returns true if proper <script> tag is found, or false if not.
+                        * @member ns.frameworkData
+                        * @static
+                        */
+                       frameworkData.getParams = function () {
+                               var self = this,
+                                       dataPrefix = self.dataPrefix,
+                                       scriptElements = slice.call(document.querySelectorAll("script[src]")),
+                                       cssElements = slice.call(document.styleSheets),
+                                       themeLoaded = false,
+                                       theme;
+
+                               /**
+                                * Following cases should be covered here (by recognizing on-page css files).
+                                * The final theme and themePath values are determined after going through all script elements
+                                *
+                                *
+                                * none                                       -> theme: null
+                                * <link href="theme.css" />                  -> theme: null
+                                * <link href="default/theme.css" />          -> theme: null
+                                * <link href="tau.css" />                    -> theme: null
+                                * <link href="white/tau.min.css" />          -> theme: "white"
+                                * <link href="other/path/black/tau.css" />   -> theme: "black"
+                                * <link href="other/path/black/tau.css" />   -> theme: "black"
+                                * <link href="other/path/black/other.css" /> -> theme: null
+                                * <link href="other/path/black/other.css" data-theme-name="white" />     -> theme: "white"
+                                * @method findThemeInLinks
+                                * @param {CSSStyleSheet} styleSheet
+                                */
+                               // @TODO write unit tests for covering those cases
+                               function findThemeInLinks(styleSheet) {
+                                       var cssElement = styleSheet.ownerNode,
+                                               dataThemeName = cssElement.getAttribute("data-theme-name"),
+                                               // Attribute value is taken because href property gives different output
+                                               href = cssElement.getAttribute("href"),
+                                               hrefFragments = href && href.split("/"),
+                                               hrefDirPart;
+
+                                       // If we have the theme name defined we can use it right away
+                                       // without thinking about the naming convention
+                                       if (dataThemeName) {
+                                               if (TIZEN_THEMES_REGEXP.test(dataThemeName)) {
+                                                       theme = dataThemeName;
+                                               }
+                                       } else if (href && CSS_FILENAME_REGEXP.test(href)) {
+                                               // We try to find file matching library theme CSS
+                                               // If we have the theme name defined we can use it right away
+                                               // We can only determine the current theme using path based approach when the .css file
+                                               // is located in at least one directory
+                                               if (hrefFragments.length >= 2) {
+                                                       // When the second to last element matches known themes set the theme to that name
+                                                       hrefDirPart = hrefFragments.slice(-2)[0].match(TIZEN_THEMES_REGEXP);
+                                                       theme = hrefDirPart && hrefDirPart[0];
+                                               }
+                                       }
+
+                                       // In case a theme was found (here or in a previous stylesheet) this will be true
+                                       themeLoaded = themeLoaded || !!theme;
+                               }
+
+                               /**
+                                * Sets framework data based on found framework library
+                                * @param {HTMLElement} scriptElement
+                                */
+                               // @TODO write unit cases
+                               function findFrameworkDataInScripts(scriptElement) {
+                                       var src = scriptElement.getAttribute("src"),
+                                               profileName = "",
+                                               frameworkName,
+                                               themePath,
+                                               jsPath;
+
+                                       // Check if checked file is a known framework
+                                       // no need to check if src exists because of the query selector
+                                       if (LIB_FILENAME_REGEXP.test(src)) {
+
+                                               // Priority:
+                                               // 1. theme loaded with css
+                                               // 2. theme from attribute
+                                               // 3. default theme
+                                               theme = theme || scriptElement.getAttribute(dataPrefix + "theme") || self.theme;
+
+                                               theme = theme.toLowerCase();
+
+                                               if (IS_TAU_REGEXP.test(src)) {
+                                                       frameworkName = FRAMEWORK_TAU;
+                                                       // Get profile name.
+                                                       // Profile may be defined from framework script or
+                                                       // it can be assumed, that profile name is second up directory name
+                                                       // e.g. pathToLib/profileName/js/tau.js
+                                                       profileName = scriptElement.getAttribute(dataPrefix + "profile") || src.split("/").slice(-3)[0];
+                                                       themePath = "/" + profileName + "/theme/" + theme;
+
+                                                       // TAU framework library link
+                                                       jsPath = "/" + profileName + "/js";
+                                               } else {
+                                                       // tizen-web-ui framework
+                                                       frameworkName = FRAMEWORK_WEBUI;
+                                                       themePath = "/latest/themes/" + theme;
+                                                       jsPath = "/latest/js";
+                                               }
+
+                                               self.rootDir = scriptElement.getAttribute(dataPrefix + "root") ||
+                                                       // remove from src path jsPath and "/" sign
+                                                       src.substring(0, src.lastIndexOf(frameworkName) - jsPath.length - 1) ||
+                                                       self.rootDir;
+
+                                               self.themePath = self.rootDir + themePath;
+                                               self.jsPath = self.rootDir + jsPath;
+                                               self.version = scriptElement.getAttribute(dataPrefix + "version") || self.version;
+                                               self.theme = theme;
+                                               self.themeLoaded = themeLoaded;
+                                               self.frameworkName = frameworkName;
+                                               self.minified = src.search(MINIFIED_REGEXP) > -1;
+                                               self.profile = profileName;
+                                       }
+                               }
+
+                               cssElements.forEach(findThemeInLinks);
+                               scriptElements.forEach(findFrameworkDataInScripts);
+                       };
+
+                       ns.frameworkData = frameworkData;
+                       // self init
+                       ns.frameworkData.getParams();
+                       }(window.document, ns));
+
+/*global window, ns, define */
+/*jslint plusplus: true, nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #jQuery Mobile mapping engine
+ * Object maps engine object from TAU namespace to jQuery Mobile namespace.
+ * @class ns.jqm.engine
+ */
+(function (window, document) {
+       "use strict";
+                               /**
+                        * Alias to Array.slice function
+                        * @method slice
+                        * @member ns.jqm.engine
+                        * @private
+                        * @static
+                        */
+                       var slice = [].slice,
+                               /**
+                                * @property {Object} nsNormalizeDict directory of data-* attributes normalized name
+                                * @member ns.jqm.engine
+                                * @private
+                                * @static
+                                */
+                               nsNormalizeDict = {},
+                               $ = ns.jqm.jQuery,
+                               util = ns.util,
+                               zoom = util.zoom,
+                               events = ns.event,
+                               load = util.load,
+                               utilsObject = util.object,
+                               /*
+                                * Convert jQuery object to HTMLElement or Array of HTMLElements
+                                * @param {jQuery|HTMLElement|Array} item
+                          * @return {HTMLElement|Array}
+                                */
+                               mapItem = function (item) {
+                                       if (typeof item === "object" && item.selector && item.get) {
+                                               return item.length === 1 ? item.get(0) : item.toArray();
+                                       }
+
+                                       return item;
+                               },
+                               engine = ns.engine,
+                               eventType = engine.eventType,
+
+                       /**
+                        * append ns functions to jQuery Mobile namespace
+                        * @method init
+                        * @member ns.jqm.engine
+                        * @static
+                        */
+                               init = function () {
+                                       var keys = Object.keys(engine),
+                                               i,
+                                               len,
+                                               name,
+                                               /*
+                                                * original jQuery find function
+                                                * type function
+                                                */
+                                               oldFind,
+                                               /*
+                                                * regular expression to find data-{namespace}-attribute
+                                                */
+                                               jqmDataRE = /:jqmData\(([^)]*)\)/g, // @TODO fix, insecure (jslint)
+                                               /*
+                                                * string to detect exists jqmData selector
+                                                */
+                                               jqmDataStr = ":jqmData",
+
+
+                                               tizen;
+
+                                       if ($) {
+
+                                               for (i = 0, len = keys.length; i < len; ++i) {
+                                                       name = keys[i];
+                                                       $[name] = widgetFunction.bind(null, arguments, mapItem, engine, name);
+                                               }
+
+                                               utilsObject.merge($.mobile, {
+                                                       /*
+                                                        * jQuery Mobile namespace
+                                                        */
+                                                       ns: "",
+                                                       /**
+                                                        *
+                                                        * @param {string} prop
+                                                        * @return {?string}
+                                                        */
+                                                       nsNormalize: function (prop) {
+                                                               if (!prop) {
+                                                                       return null;
+                                                               }
+                                                               nsNormalizeDict[prop] = nsNormalizeDict[prop] || $.camelCase($.mobile.ns + prop);
+                                                               return nsNormalizeDict[prop];
+                                                       },
+                                                       activeBtnClass: ns.widget.core.Button.classes.uiBtnActive,
+                                                       activePageClass: ns.widget.core.Page.classes.uiPageActive,
+                                                       focusClass: ns.widget.core.Button.classes.uiFocus,
+                                                       version: "1.2.0",
+                                                       getAttrFixed: function (element, key) {
+                                                               var value = element.getAttribute(key);
+
+                                                               return value === "true" ? true :
+                                                                       value === "false" ? false :
+                                                                               value === null ? undefined :
+                                                                                       value;
+                                                       },
+                                                       path: ns.util.path,
+                                                       back: window.history.back.bind(window.history),
+                                                       silentScroll: function (yPos) {
+                                                               if (yPos === undefined) {
+                                                                       yPos = $.mobile.defaultHomeScroll;
+                                                               }
+
+                                                               // prevent scrollstart and scrollstop events
+                                                               // @TODO enable event control
+                                                               //ns.event.special.scrollstart.enabled = false;
+
+                                                               setTimeout(function () {
+                                                                       window.scrollTo(0, yPos);
+                                                                       events.trigger(document, "silentscroll", {x: 0, y: yPos});
+                                                               }, 20);
+
+                                                               setTimeout(function () {
+                                                                       // @TODO enable event control
+                                                                       //$.event.special.scrollstart.enabled = true;
+                                                               }, 150);
+                                                       },
+                                                       nsNormalizeDict: nsNormalizeDict,
+                                                       closestPageData: function (target) {
+                                                               var page = ns.util.selectors.getClosestBySelector($(target)[0],
+                                                                       "[data-" + ($.mobile.ns || "") + "role='page'], [data-" + ($.mobile.ns || "") + "role='dialog']");
+
+                                                               return ns.engine.instanceWidget(page, "Page");
+                                                       },
+                                                       enhanceable: function ($set) {
+                                                               return this.haveParents($set, "enhance");
+                                                       },
+                                                       hijackable: function ($set) {
+                                                               return this.haveParents($set, "ajax");
+                                                       },
+                                                       haveParents: function ($set, attr) {
+                                                               var count = 0,
+                                                                       $newSet = null,
+                                                                       e,
+                                                                       $element,
+                                                                       excluded,
+                                                                       i,
+                                                                       c;
+
+                                                               if (!$.mobile.ignoreContentEnabled) {
+                                                                       return $set;
+                                                               }
+
+                                                               count = $set.length;
+                                                               $newSet = $();
+
+                                                               for (i = 0; i < count; i++) {
+                                                                       $element = $set.eq(i);
+                                                                       excluded = false;
+                                                                       e = $set[i];
+
+                                                                       while (e) {
+                                                                               c = e.getAttribute ? e.getAttribute("data-" + $.mobile.ns + attr) : "";
+
+                                                                               if (c === "false") {
+                                                                                       excluded = true;
+                                                                                       break;
+                                                                               }
+
+                                                                               e = e.parentNode;
+                                                                       }
+
+                                                                       if (!excluded) {
+                                                                               $newSet = $newSet.add($element);
+                                                                       }
+                                                               }
+
+                                                               return $newSet;
+                                                       },
+                                                       getScreenHeight: function () {
+                                                               // Native innerHeight returns more accurate value for this across platforms,
+                                                               // jQuery version is here as a normalized fallback for platforms like Symbian
+                                                               return window.innerHeight;
+                                                       },
+                                                       widget: function () {
+                                                               // @todo fill data
+                                                               return null;
+                                                       },
+                                                       media: ns.support.media,
+                                                       browser: {},
+                                                       gradeA: function () {
+                                                               // @todo fill data
+                                                               return null;
+                                                       },
+                                                       zoom: zoom,
+                                                       popupwindow: {}
+                                               });
+                                               $.mobile.buttonMarkup = $.mobile.buttonMarkup || ns.widget.mobile.Button;
+                                               $.mobile.$window = $(window);
+                                               $.mobile.$document = $(document);
+                                               $.mobile.keyCode = {
+                                                       ALT: 18,
+                                                       BACKSPACE: 8,
+                                                       CAPS_LOCK: 20,
+                                                       COMMA: 188,
+                                                       COMMAND: 91,
+                                                       COMMAND_LEFT: 91, // COMMAND
+                                                       COMMAND_RIGHT: 93,
+                                                       CONTROL: 17,
+                                                       DELETE: 46,
+                                                       DOWN: 40,
+                                                       END: 35,
+                                                       ENTER: 13,
+                                                       ESCAPE: 27,
+                                                       HOME: 36,
+                                                       INSERT: 45,
+                                                       LEFT: 37,
+                                                       MENU: 93, // COMMAND_RIGHT
+                                                       NUMPAD_ADD: 107,
+                                                       NUMPAD_DECIMAL: 110,
+                                                       NUMPAD_DIVIDE: 111,
+                                                       NUMPAD_ENTER: 108,
+                                                       NUMPAD_MULTIPLY: 106,
+                                                       NUMPAD_SUBTRACT: 109,
+                                                       PAGE_DOWN: 34,
+                                                       PAGE_UP: 33,
+                                                       PERIOD: 190,
+                                                       RIGHT: 39,
+                                                       SHIFT: 16,
+                                                       SPACE: 32,
+                                                       TAB: 9,
+                                                       UP: 38,
+                                                       WINDOWS: 91 // COMMAND
+                                               };
+                                               $.tizen = $.tizen || {};
+                                               tizen = $.tizen;
+                                               tizen.globalize = ns.util.globalize;
+                                               $.mobile.tizen = utilsObject.merge($.mobile.tizen, {
+                                                       _widgetPrototypes: {},
+                                                       disableSelection: function () {
+                                                               ns.warn("Function $.mobile.tizen.disableSelection is deprecated");
+                                                       },
+                                                       enableSelection: function () {
+                                                               ns.warn("Function $.mobile.tizen.enableSelection is deprecated");
+                                                       },
+                                                       enableContextMenu: function () {
+                                                               ns.warn("Function $.mobile.tizen.enableContextMenu is deprecated");
+                                                       },
+                                                       disableContextMenu: function () {
+                                                               ns.warn("Function $.mobile.tizen.disableContextMenu is deprecated");
+                                                       }
+                                               });
+                                               $.mobile.tizen.loadPrototype = null;
+
+                                               /*
+                                                * jqmData function from jQuery Mobile
+                                                */
+                                               $.fn.jqmData = function (prop, value) {
+                                                       var result;
+
+                                                       if (prop !== undefined) {
+                                                               if (prop) {
+                                                                       prop = $.mobile.nsNormalize(prop);
+                                                               }
+                                                               if (arguments.length < 2 || value === undefined) {
+                                                                       result = this.data(prop);
+                                                               } else {
+                                                                       result = this.data(prop, value);
+                                                               }
+                                                       }
+                                                       return result;
+                                               };
+
+                                               $.fn.jqmRemoveData = function (prop) {
+                                                       if (prop !== undefined) {
+                                                               if (prop) {
+                                                                       prop = $.mobile.nsNormalize(prop);
+                                                               }
+                                                               this.removeData(prop);
+                                                       }
+                                                       return this;
+                                               };
+
+                                               $.jqmData = function (context, prop, value) {
+                                                       var result = $(context).jqmData(prop, value);
+
+                                                       return value || result;
+                                               };
+
+                                               $.jqmRemoveData = function (context, prop) {
+                                                       $(context).jqmRemoveData(prop);
+                                               };
+
+                                               $.fn.removeWithDependents = function () {
+                                                       $.removeWithDependents(this);
+                                               };
+
+                                               $.removeWithDependents = function (elem) {
+                                                       var $elem = $(elem);
+
+                                                       ($elem.jqmData("dependents") || $()).remove();
+                                                       $elem.remove();
+                                               };
+
+                                               $.fn.addDependents = function (newDependents) {
+                                                       $.addDependents($(this), newDependents);
+                                               };
+
+                                               $.addDependents = function (elem, newDependents) {
+                                                       var dependents = $(elem).jqmData("dependents") || $();
+
+                                                       $(elem).jqmData("dependents", $.merge(dependents, newDependents));
+                                               };
+
+                                               $.fn.getEncodedText = function () {
+                                                       return $("<div/>").text($(this).text()).html();
+                                               };
+
+                                               // fluent helper function for the mobile namespaced equivalent
+                                               $.fn.jqmEnhanceable = function () {
+                                                       return $.mobile.enhanceable(this);
+                                               };
+
+                                               $.fn.jqmHijackable = function () {
+                                                       return $.mobile.hijackable(this);
+                                               };
+
+                                               /*
+                                                * Add support of jqmData() in jQuery find
+                                                */
+                                               oldFind = $.find;
+
+                                               $.find = function (selector, context, ret, extra) {
+                                                       if (selector.indexOf(jqmDataStr) > -1) {
+                                                               selector = selector.replace(jqmDataRE, "[data-" + ($.mobile.ns || "") + "$1]");
+                                                       }
+                                                       return oldFind.call(this, selector, context, ret, extra);
+                                               };
+
+                                               $.extend($.find, oldFind);
+
+                                               $.find.matches = function (expr, set) {
+                                                       return $.find(expr, null, null, set);
+                                               };
+
+                                               $.find.matchesSelector = function (node, expr) {
+                                                       return $.find(expr, null, null, [node]).length > 0;
+                                               };
+
+                                               /* support for global object $.mobile
+                                                * @TODO this is temporary fix, we have to think about this function
+                                                */
+                                               $(document).bind("create", ns.engine._createEventHandler);
+                                               // support creating widgets by triggering pagecreate
+                                               $(document).bind("pagecreate", function (event) {
+                                                       var originalEvent = event.originalEvent || event,
+                                                               isPage = originalEvent.detail instanceof ns.widget.core.Page,
+                                                               pageWidget;
+
+                                                       if (!isPage) { // trigger create when the pagecreate trigger is from outside
+                                                               pageWidget = engine.instanceWidget(originalEvent.target, "Page");
+                                                               pageWidget.refresh();
+                                                               ns.engine._createEventHandler(originalEvent);
+                                                       }
+                                               });
+                                               $(document).bind("activePopup", function (event) {
+                                                       $.mobile.popup.active = $.mobile.popupwindow.active = event.originalEvent.detail;
+                                               });
+
+                                               // @TODO fill this object proper data
+                                               $.tizen.frameworkData = ns.frameworkData;
+
+                                               $.tizen.__tizen__ = tizen;
+                                               tizen.libFileName = "tizen-web-ui-fw(.custom|.full)?(.min)?.js";
+                                               tizen.log = {
+                                                       debug: function (msg) {
+                                                               if ($.tizen.frameworkData.debug) {
+                                                                       ns.log(msg);
+                                                               }
+                                                       },
+                                                       warn: ns.warn.bind(ns),
+                                                       error: ns.error.bind(ns),
+                                                       alert: window.alert.bind(window)
+                                               };
+                                               tizen.util = {
+                                                       loadScriptSync: load.scriptSync,
+                                                       isMobileBrowser: function () {
+                                                               ns.warn("Function $.tizen.__tizen__.util.isMobileBrowser is deprecated");
+                                                       }
+                                               };
+                                               tizen.css = {
+                                                       cacheBust: load.cacheBust,
+                                                       addElementToHead: load.addElementToHead.bind(load),
+                                                       makeLink: load.makeLink.bind(load),
+                                                       load: load.themeCSS
+                                               };
+                                               tizen.loadTheme = function () {
+                                                       ns.warn("Function $.tizen.__tizen__.loadTheme is deprecated");
+                                               };
+                                               //tizen.loadGlobalizeCulture = ns.util.globalize.loadGlobalizeCulture.bind(ns.util.globalize);
+                                               tizen.setLocale = util.globalize.setLocale;
+                                               tizen.setViewport = function () {
+                                                       ns.warn("Function $.tizen.__tizen__.setViewport is deprecated");
+                                               };
+                                               tizen.scaleBaseFontSize = function () {
+                                                       ns.warn("Function $.tizen.__tizen__.scaleBaseFontSize is deprecated");
+                                               };
+                                               tizen.setScaling = function () {
+                                                       ns.warn("Function $.tizen.__tizen__.setScaling is deprecated");
+                                               };
+                                               tizen.getParams = ns.frameworkData.getParams.bind(ns.frameworkData);
+
+                                               ns.setConfig("enableHWKeyHandler", $.mobile.tizen.enableHWKeyHandler);
+                                       }
+                               },
+                               /**
+                                * Removes events listeners on destroy of framework.
+                                */
+                               destroy = function () {
+                                       document.removeEventListener(eventType.INIT, init, false);
+                                       document.removeEventListener(eventType.DESTROY, destroy, false);
+                               };
+
+                       /**
+                        * Function which is used as jQuery mapping engine method
+                        * @param {Arguments} parentArguments
+                        * @param {Function} mapItem
+                        * @param {Object} engine
+                        * @param {string} name
+                        */
+                       function widgetFunction(parentArguments, mapItem, engine, name) {
+                               var args = slice.call(parentArguments).map(mapItem);
+
+                               engine[name].apply(engine, args);
+                       }
+
+                       // Listen when framework is ready
+                       document.addEventListener(eventType.INIT, init, false);
+                       document.addEventListener(eventType.DESTROY, destroy, false);
+
+                       }(window, window.document));
+
+/*global CustomEvent, define, window, ns */
+/*jslint plusplus: true, nomen: true, bitwise: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Virtual Mouse Events
+ * Reimplementation of jQuery Mobile virtual mouse events.
+ *
+ * ##Purpose
+ * It will let for users to register callbacks to the standard events like bellow,
+ * without knowing if device support touch or mouse events
+ * @class ns.event.vmouse
+ */
+/**
+ * Triggered after mouse-down or touch-started.
+ * @event vmousedown
+ * @member ns.event.vmouse
+ */
+/**
+ * Triggered when mouse-click or touch-end when touch-move didn't occur
+ * @event vclick
+ * @member ns.event.vmouse
+ */
+/**
+ * Triggered when mouse-up or touch-end
+ * @event vmouseup
+ * @member ns.event.vmouse
+ */
+/**
+ * Triggered when mouse-move or touch-move
+ * @event vmousemove
+ * @member ns.event.vmouse
+ */
+/**
+ * Triggered when mouse-over or touch-start if went over coordinates
+ * @event vmouseover
+ * @member ns.event.vmouse
+ */
+/**
+ * Triggered when mouse-out or touch-end
+ * @event vmouseout
+ * @member ns.event.vmouse
+ */
+/**
+ * Triggered when mouse-cancel or touch-cancel and when scroll occur during touchmove
+ * @event vmousecancel
+ * @member ns.event.vmouse
+ */
+(function (window, document, ns) {
+       "use strict";
+                               /**
+                        * Object with default options
+                        * @property {Object} vmouse
+                        * @member ns.event.vmouse
+                        * @static
+                        * @private
+                        **/
+                       var vmouse,
+                               /**
+                                * @property {Object} eventProps Contains the properties which are copied from the original
+                                * event to custom v-events
+                                * @member ns.event.vmouse
+                                * @static
+                                * @private
+                                **/
+                               eventProps,
+                               /**
+                                * Indicates if the browser support touch events
+                                * @property {boolean} touchSupport
+                                * @member ns.event.vmouse
+                                * @static
+                                **/
+                               touchSupport = window.hasOwnProperty("ontouchstart"),
+                               /**
+                                * @property {boolean} didScroll The flag tell us if the scroll event was triggered
+                                * @member ns.event.vmouse
+                                * @static
+                                * @private
+                                **/
+                               didScroll,
+                               /** @property {HTMLElement} lastOver holds reference to last element that touch was over
+                                * @member ns.event.vmouse
+                                * @private
+                                */
+                               lastOver = null,
+                               /**
+                                * @property {number} [startX=0] Initial data for touchstart event
+                                * @member ns.event.vmouse
+                                * @static
+                                * @private
+                                **/
+                               startX = 0,
+                               /**
+                                * @property {number} [startY=0] Initial data for touchstart event
+                                * @member ns.event.vmouse
+                                * @private
+                                * @static
+                                **/
+                               startY = 0,
+                               touchEventProps = ["clientX", "clientY", "pageX", "pageY", "screenX", "screenY"],
+                               KEY_CODES = {
+                                       enter: 13
+                               };
+
+                       /**
+                        * Extends objects with other objects
+                        * @method copyProps
+                        * @param {Object} from Sets the original event
+                        * @param {Object} to Sets the new event
+                        * @param {Object} properties Sets the special properties for position
+                        * @param {Object} propertiesNames Describe parameters which will be copied from Original to
+                        * event
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function copyProps(from, to, properties, propertiesNames) {
+                               var i,
+                                       length,
+                                       descriptor,
+                                       property;
+
+                               for (i = 0, length = propertiesNames.length; i < length; ++i) {
+                                       property = propertiesNames[i];
+                                       if (isNaN(properties[property]) === false || isNaN(from[property]) === false) {
+                                               descriptor = Object.getOwnPropertyDescriptor(to, property);
+                                               if (property !== "detail" && (!descriptor || descriptor.writable)) {
+                                                       to[property] = properties[property] || from[property];
+                                               }
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Create custom event
+                        * @method createEvent
+                        * @param {string} newType gives a name for the new Type of event
+                        * @param {Event} original Event which trigger the new event
+                        * @param {Object} properties Sets the special properties for position
+                        * @return {Event}
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function createEvent(newType, original, properties) {
+                               var evt = new CustomEvent(newType, {
+                                               "bubbles": original.bubbles,
+                                               "cancelable": original.cancelable,
+                                               "detail": original.detail
+                                       }),
+                                       originalType = original.type,
+                                       changeTouches,
+                                       touch,
+                                       j = 0,
+                                       len,
+                                       prop;
+
+                               copyProps(original, evt, properties, eventProps);
+                               evt._originalEvent = original;
+
+                               if (originalType.indexOf("touch") !== -1) {
+                                       originalType = original.touches;
+                                       changeTouches = original.changedTouches;
+
+                                       if (originalType && originalType.length) {
+                                               touch = originalType[0];
+                                       } else {
+                                               touch = (changeTouches && changeTouches.length) ? changeTouches[0] : null;
+                                       }
+
+                                       if (touch) {
+                                               for (len = touchEventProps.length; j < len; j++) {
+                                                       prop = touchEventProps[j];
+                                                       evt[prop] = touch[prop];
+                                               }
+                                       }
+                               }
+
+                               return evt;
+                       }
+
+                       /**
+                        * Dispatch Events
+                        * @method fireEvent
+                        * @param {string} eventName event name
+                        * @param {Event} evt original event
+                        * @param {Object} [properties] Sets the special properties for position
+                        * @return {boolean}
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function fireEvent(eventName, evt, properties) {
+                               return evt.target.dispatchEvent(createEvent(eventName, evt, properties || {}));
+                       }
+
+                       eventProps = [
+                               "currentTarget",
+                               "detail",
+                               "button",
+                               "buttons",
+                               "clientX",
+                               "clientY",
+                               "offsetX",
+                               "offsetY",
+                               "pageX",
+                               "pageY",
+                               "screenX",
+                               "screenY",
+                               "toElement",
+                               "which"
+                       ];
+
+                       vmouse = {
+                               /**
+                                * Sets the distance of pixels after which the scroll event will be successful
+                                * @property {number} [eventDistanceThreshold=10]
+                                * @member ns.event.vmouse
+                                * @static
+                                */
+                               eventDistanceThreshold: 10,
+
+                               touchSupport: touchSupport
+                       };
+
+                       /**
+                        * Handle click down
+                        * @method handleDown
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleDown(evt) {
+                               fireEvent("vmousedown", evt);
+                       }
+
+                       /**
+                        * Prepare position of event for keyboard events.
+                        * @method preparePositionForClick
+                        * @param {Event} event
+                        * @return {?Object} options
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function preparePositionForClick(event) {
+                               var x = event.clientX,
+                                       y = event.clientY;
+                               // event comes from keyboard
+
+                               if (!x && !y) {
+                                       return preparePositionForEvent(event);
+                               }
+                               return null;
+                       }
+
+                       /**
+                        * Handle click
+                        * @method handleClick
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleClick(evt) {
+                               fireEvent("vclick", evt, preparePositionForClick(evt));
+                       }
+
+                       /**
+                        * Handle click up
+                        * @method handleUp
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleUp(evt) {
+                               fireEvent("vmouseup", evt);
+                       }
+
+                       /**
+                        * Handle click move
+                        * @method handleMove
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleMove(evt) {
+                               fireEvent("vmousemove", evt);
+                       }
+
+                       /**
+                        * Handle click over
+                        * @method handleOver
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleOver(evt) {
+                               fireEvent("vmouseover", evt);
+                       }
+
+                       /**
+                        * Handle click out
+                        * @method handleOut
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleOut(evt) {
+                               fireEvent("vmouseout", evt);
+                       }
+
+                       /**
+                        * Handle touch start
+                        * @method handleTouchStart
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleTouchStart(evt) {
+                               var touches = evt.touches,
+                                       firstTouch;
+
+                               //if touches are registered and we have only one touch
+                               if (touches && touches.length === 1) {
+                                       didScroll = false;
+                                       firstTouch = touches[0];
+                                       startX = firstTouch.pageX || firstTouch.clientX || 0; // for touch converted from mouse event
+                                       startY = firstTouch.pageY || firstTouch.clientX || 0; // for touch converted from mouse event
+
+                                       // Check if we have touched something on our page
+                                       // @TODO refactor for multi touch
+                                       /*
+                                        over = document.elementFromPoint(startX, startY);
+                                        if (over) {
+                                        lastOver = over;
+                                        fireEvent("vmouseover", evt);
+                                        }
+                                        */
+                                       fireEvent("vmousedown", evt);
+                               }
+
+                       }
+
+                       /**
+                        * Handle touch end
+                        * @method handleTouchEnd
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleTouchEnd(evt) {
+                               var touches = evt.touches;
+
+                               if (touches && touches.length === 0) {
+                                       fireEvent("vmouseup", evt);
+                                       fireEvent("vmouseout", evt);
+                                       // Reset flag for last over element
+                                       lastOver = null;
+                               }
+                       }
+
+                       /**
+                        * Handle touch move
+                        * @method handleTouchMove
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleTouchMove(evt) {
+                               var over,
+                                       firstTouch = evt.touches && evt.touches[0],
+                                       pointerX,
+                                       pointerY,
+                                       didCancel = didScroll,
+                                       //sets the threshold, based on which we consider if it was the touch-move event
+                                       moveThreshold = vmouse.eventDistanceThreshold;
+
+                               /**
+                                * Ignore the touch which has identifier other than 0.
+                                * Only first touch has control others are ignored.
+                                * Patch for webkit behavior where touchmove event
+                                * is triggered between touchend events
+                                * if there is multi touch.
+                                */
+
+                               if ((firstTouch === undefined) || firstTouch.identifier > 0) {
+                                       //evt.preventDefault(); // cant preventDefault passive events!!!
+                                       evt.stopPropagation();
+                                       return;
+                               }
+
+                               pointerX = firstTouch.pageX || firstTouch.clientX || 0, // for touch converted from mouse event
+                               pointerY = firstTouch.pageY || firstTouch.clientY || 0, // for touch converted from mouse event
+
+                               didScroll = didScroll ||
+                                       //check in both axes X,Y if the touch-move event occur
+                                       (Math.abs(pointerX - startX) > moveThreshold ||
+                                       Math.abs(pointerY - startY) > moveThreshold);
+
+                               // detect over event
+                               // for compatibility with mouseover because "touchenter" fires only once
+                               // @TODO Handle many touches
+                               over = document.elementFromPoint(pointerX, pointerY);
+                               if (over && lastOver !== over) {
+                                       lastOver = over;
+                                       fireEvent("vmouseover", evt);
+                               }
+
+                               //if didScroll occur and wasn't canceled then trigger touchend otherwise just touchmove
+                               if (didScroll && !didCancel) {
+                                       fireEvent("vmousecancel", evt);
+                                       lastOver = null;
+                               }
+                               fireEvent("vmousemove", evt);
+                       }
+
+                       /**
+                        * Handle Scroll
+                        * @method handleScroll
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleScroll(evt) {
+                               if (!didScroll) {
+                                       fireEvent("vmousecancel", evt);
+                               }
+                               didScroll = true;
+                       }
+
+                       /**
+                        * Handle touch cancel
+                        * @method handleTouchCancel
+                        * @param {Event} evt
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleTouchCancel(evt) {
+
+                               fireEvent("vmousecancel", evt);
+                               lastOver = null;
+                       }
+
+                       /**
+                        * Prepare position of event for keyboard events.
+                        * @method preparePositionForEvent
+                        * @param {Event} event
+                        * @return {Object} properties
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function preparePositionForEvent(event) {
+                               var targetRect = event.target && event.target.getBoundingClientRect(),
+                                       properties = {};
+
+                               if (targetRect) {
+                                       properties = {
+                                               "clientX": targetRect.left + targetRect.width / 2,
+                                               "clientY": targetRect.top + targetRect.height / 2,
+                                               "which": 1
+                                       };
+                               }
+                               return properties;
+                       }
+
+                       /**
+                        * Handle key up
+                        * @method handleKeyUp
+                        * @param {Event} event
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleKeyUp(event) {
+                               var properties;
+
+                               if (event.keyCode === KEY_CODES.enter) {
+                                       properties = preparePositionForEvent(event);
+                                       fireEvent("vmouseup", event, properties);
+                                       fireEvent("vclick", event, properties);
+                               }
+                       }
+
+                       /**
+                        * Handle key down
+                        * @method handleKeyDown
+                        * @param {Event} event
+                        * @private
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       function handleKeyDown(event) {
+                               if (event.keyCode === KEY_CODES.enter) {
+                                       fireEvent("vmousedown", event, preparePositionForEvent(event));
+                               }
+                       }
+
+                       /**
+                        * Binds events common to mouse and touch to support virtual mouse.
+                        * @method bindCommonEvents
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       vmouse.bindCommonEvents = function () {
+                               document.addEventListener("keyup", handleKeyUp, true);
+                               document.addEventListener("keydown", handleKeyDown, true);
+                               document.addEventListener("scroll", handleScroll, true);
+                               document.addEventListener("click", handleClick, true);
+                       };
+
+                       // @TODO delete touchSupport flag and attach touch and mouse listeners,
+                       // @TODO check if v-events are not duplicated if so then called only once
+
+                       /**
+                        * Binds touch events to support virtual mouse.
+                        * @method bindTouch
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       vmouse.bindTouch = function () {
+                               document.addEventListener("touchstart", handleTouchStart, true);
+                               document.addEventListener("touchend", handleTouchEnd, true);
+                               document.addEventListener("touchmove", handleTouchMove, true);
+                               document.addEventListener("touchcancel", handleTouchCancel, true);
+                       };
+
+                       /**
+                        * Binds mouse events to support virtual mouse.
+                        * @method bindMouse
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       vmouse.bindMouse = function () {
+                               document.addEventListener("mousedown", handleDown, true);
+                               document.addEventListener("mouseup", handleUp, true);
+                               document.addEventListener("mousemove", handleMove, true);
+                               document.addEventListener("mouseover", handleOver, true);
+                               document.addEventListener("mouseout", handleOut, true);
+                       };
+
+                       /**
+                        * Unbinds touch events to support virtual mouse.
+                        * @method unbindTouch
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       vmouse.unbindTouch = function () {
+                               document.removeEventListener("touchstart", handleTouchStart, true);
+                               document.removeEventListener("touchend", handleTouchEnd, true);
+                               document.removeEventListener("touchmove", handleTouchMove, true);
+
+                               document.removeEventListener("touchcancel", handleTouchCancel, true);
+
+                               document.removeEventListener("click", handleClick, true);
+                       };
+
+                       /**
+                        * Unbinds mouse events to support virtual mouse.
+                        * @method unbindMouse
+                        * @static
+                        * @member ns.event.vmouse
+                        */
+                       vmouse.unbindMouse = function () {
+                               document.removeEventListener("mousedown", handleDown, true);
+
+                               document.removeEventListener("mouseup", handleUp, true);
+                               document.removeEventListener("mousemove", handleMove, true);
+                               document.removeEventListener("mouseover", handleOver, true);
+                               document.removeEventListener("mouseout", handleOut, true);
+
+                               document.removeEventListener("keyup", handleKeyUp, true);
+                               document.removeEventListener("keydown", handleKeyDown, true);
+                               document.removeEventListener("scroll", handleScroll, true);
+                               document.removeEventListener("click", handleClick, true);
+                       };
+
+                       ns.event.vmouse = vmouse;
+
+                       if (touchSupport) {
+                               vmouse.bindTouch();
+                       } else {
+                               vmouse.bindMouse();
+                       }
+                       vmouse.bindCommonEvents();
+
+                       }(window, window.document, ns));
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Event orientationchange
+ * Namespace to support orientationchange event
+ * @class ns.event.orientationchange
+ */
+/**
+ * Event orientationchange
+ * @event orientationchange
+ * @member ns.event.orientationchange
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var eventUtils = ns.event,
+                               eventType = ns.engine.eventType,
+                               orientationchange = {
+                                       /**
+                                        * Window alias
+                                        * @property {Window} window
+                                        * @member ns.event.orientationchange
+                                        * @static
+                                        * @protected
+                                        */
+                                       _window: window,
+                                       /**
+                                        * Informs about support orientation change event.
+                                        * @property {boolean} supported
+                                        * @member ns.event.orientationchange
+                                        */
+                                       supported: (window.orientation !== undefined) && (window.onorientationchange !== undefined),
+                                       /**
+                                        * List of properties copied to event details object
+                                        * @property {Array} properties
+                                        * @member ns.event.orientationchange
+                                        * @static
+                                        */
+                                       properties: ["orientation"],
+
+                                       /**
+                                        * Chosen orientation
+                                        * @property {Window} [orientation=portrait]
+                                        * @member ns.event.orientationchange
+                                        * @protected
+                                        * @static
+                                        */
+                                       _orientation: "portrait"
+                               },
+                               detectOrientationByDimensions = function (omitCustomEvent) {
+                                       var win = orientationchange._window,
+                                               width = win.innerWidth,
+                                               height = win.innerHeight;
+
+                                       if (win.screen) {
+                                               width = win.screen.availWidth;
+                                               height = win.screen.availHeight;
+                                       }
+
+                                       if (width > height) {
+                                               orientationchange._orientation = "landscape";
+                                       } else {
+                                               orientationchange._orientation = "portrait";
+                                       }
+
+                                       if (!omitCustomEvent) {
+                                               eventUtils.trigger(window, "orientationchange", {"orientation": orientationchange._orientation});
+                                       }
+                               },
+                               checkReportedOrientation = function () {
+                                       if (orientationchange._window.orientation) {
+                                               switch (orientationchange._window.orientation) {
+                                                       case 90:
+                                                       case -90:
+                                                               orientationchange._orientation = "portrait";
+                                                               break;
+                                                       default:
+                                                               orientationchange._orientation = "landscape";
+                                                               break;
+                                               }
+                                       } else {
+                                               detectOrientationByDimensions(true);
+                                       }
+                               },
+                               matchMediaHandler = function (mediaQueryList, omitEvent) {
+                                       if (mediaQueryList.matches) {
+                                               orientationchange._orientation = "portrait";
+                                       } else {
+                                               orientationchange._orientation = "landscape";
+                                       }
+
+                                       if (!omitEvent) { // this was added explicit for testing
+                                               eventUtils.trigger(window, "orientationchange", {"orientation": orientationchange._orientation});
+                                       }
+                               },
+                               portraitMatchMediaQueryList = null;
+
+                       /**
+                       * Returns current orientation.
+                       * @method getOrientation
+                       * @return {"landscape"|"portrait"}
+                       * @member ns.event.orientationchange
+                       * @static
+                       */
+                       orientationchange.getOrientation = function () {
+                               return orientationchange._orientation;
+                       };
+
+                       /**
+                       * Triggers event orientationchange on element
+                       * @method trigger
+                       * @param {HTMLElement} element
+                       * @member ns.event.orientationchange
+                       * @static
+                       */
+                       orientationchange.trigger = function (element) {
+                               eventUtils.trigger(element, "orientationchange", {"orientation": orientationchange._orientation});
+                       };
+
+                       /**
+                       * Unbinds events
+                       * @member ns.event.orientationchange
+                       * @static
+                       */
+                       orientationchange.unbind = function () {
+                               window.removeEventListener("orientationchange", checkReportedOrientation, false);
+                               document.removeEventListener("throttledresize", detectOrientationByDimensions, true);
+                               document.removeEventListener(eventType.DESTROY, orientationchange.unbind, false);
+                       };
+
+                       /**
+                       * Performs orientation detection
+                       * @member ns.event.orientationchange
+                       * @static
+                       */
+                       orientationchange.detect = function () {
+                               if (orientationchange.supported) {
+                                       window.addEventListener("orientationchange", checkReportedOrientation, false);
+                                       checkReportedOrientation();
+                                       // try media queries
+                               } else {
+                                       if (orientationchange._window.matchMedia) {
+                                               portraitMatchMediaQueryList = orientationchange._window.matchMedia("(orientation: portrait)");
+                                               if (portraitMatchMediaQueryList.matches) {
+                                                       orientationchange._orientation = "portrait";
+                                               } else {
+                                                       orientationchange._orientation = "landscape";
+                                               }
+                                               portraitMatchMediaQueryList.addListener(matchMediaHandler);
+                                       } else {
+                                               document.addEventListener("throttledresize", detectOrientationByDimensions, true);
+                                               detectOrientationByDimensions();
+                                       }
+                               }
+                       };
+
+                       document.addEventListener(eventType.DESTROY, orientationchange.unbind, false);
+
+                       orientationchange.detect();
+
+                       ns.event.orientationchange = orientationchange;
+
+                       }(window, window.document, ns));
+
+/*global window, ns, define */
+/*jslint plusplus: true, nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #jQuery Mobile mapping events
+ * Object maps events from TAU namespace to jQuery Mobile namespace.
+ * @class ns.jqm.event
+ */
+(function (window, document) {
+       "use strict";
+       
+                       var eventUtils = ns.event,
+                               $ = ns.jqm.jQuery,
+                               originalTrigger,
+                               originalDispatch,
+                               eventType = {
+                                       CLICK: "click",
+                                       SUBMIT: "submit",
+                                       KEYUP: "keyup",
+                                       TOUCHSTART: "touchstart",
+                                       TOUCHEND: "touchend",
+                                       VCLICK: "vclick",
+                                       MOUSEDOWN: "mousedown",
+                                       MOUSEUP: "mouseup",
+                                       BEFOREROUTERINIT: "beforerouterinit",
+                                       DESTROY: "taudestroy"
+                               },
+                               registerEventNames = ["touchstart", "touchmove", "touchend", "tap", "taphold", "swipeleft", "swiperight", "scrollstart", "scrollstop"],
+
+                               event = {
+                                       /**
+                                        * Create method on jQuery object with name represent event.
+                                        * @method proxyEventTriggerMethod
+                                        * @param {string} name Name of event and new method
+                                        * @param {Function} trigger Function called after invoke method
+                                        * @member ns.jqm.event
+                                        * @static
+                                        */
+                                       proxyEventTriggerMethod: function (name, trigger) {
+                                               $.fn[name] = function () {
+                                                       var $elements = this,
+                                                               elementsLength = $elements.length,
+                                                               i;
+
+                                                       for (i = 0; i < elementsLength; i++) {
+                                                               trigger($elements.get(i));
+                                                       }
+                                               };
+                                       },
+
+                                       /**
+                                        * Adds proxy to jquery.trigger method
+                                        * @method proxyTrigger
+                                        * @param {string} type event type
+                                        * @param {Mixed} data event data
+                                        * @return {jQuery}
+                                        * @member ns.jqm.event
+                                        */
+                                       proxyTrigger: function (type, data) {
+                                               var $elements = this,
+                                                       elementsLength = $elements.length,
+                                                       i;
+
+                                               if (!eventType[type.toUpperCase()]) {
+                                                       originalTrigger.call($elements, type, data);
+                                               }
+
+                                               for (i = 0; i < elementsLength; i++) {
+                                                       eventUtils.trigger($elements.get(i), type);
+                                               }
+
+                                               return this;
+                                       },
+
+                                       /**
+                                        * Method read additional data from event.detail and move these data as additional argument to jQuery.event.dispatch
+                                        * @method proxyDispatch
+                                        * @param {jQuery.Event} event event type
+                                        * @return {jQuery}
+                                        * @member ns.jqm.event
+                                        */
+                                       proxyDispatch: function (event) {
+                                               var data = (event.originalEvent && event.originalEvent.detail) || event.detail,
+                                                       args;
+
+                                               args = [].slice.call(arguments);
+                                               if (data) {
+                                                       args.push(data);
+                                               }
+                                               return originalDispatch.apply(this, args);
+                                       },
+
+                                       /**
+                                        * Copy properties from originalEvent.detail.* to event Object.
+                                        * @method copyEventProperties
+                                        * @param {HTMLElement} root root element to catch all events window/document
+                                        * @param {string} name Name of event
+                                        * @param {Array.<string>} properties Array of properties to copy from originalEvent to jQuery Event
+                                        * @member ns.jqm.event
+                                        * @static
+                                        */
+                                       copyEventProperties: function (root, name, properties) {
+                                               $(root).on(name, function (event) {
+                                                       var i,
+                                                               property;
+
+                                                       for (i = 0; i < properties.length; i++) {
+                                                               property = properties[i];
+                                                               if (!event[property]) {
+                                                                       if (root instanceof window.screen.constructor) {
+                                                                               // In case of orientation change event the properties are set to window.screen object
+                                                                               // that's why we check if root is Screen in the first place
+                                                                               event[property] = event.originalEvent.detail &&
+                                                                                       event.originalEvent.detail[property] ||
+                                                                                       event.target[property];
+                                                                       } else {
+                                                                               event[property] = event.originalEvent.detail && event.originalEvent.detail[property];
+                                                                       }
+                                                               }
+                                                       }
+                                               });
+                                       },
+
+                                       /**
+                                        * Proxy events from ns namespace to jQM namespace
+                                        * @method init
+                                        * @member ns.jqm.event
+                                        * @static
+                                        */
+                                       init: function () {
+                                               var removeEvents = function (event) {
+                                                               event.stopPropagation();
+                                                               event.preventDefault();
+                                                               return false;
+                                                       },
+                                                       blockedEvents = [eventType.TOUCHSTART, eventType.TOUCHEND, eventType.VCLICK, eventType.MOUSEDOWN, eventType.MOUSEUP, eventType.CLICK],
+                                                       blockedEventsLength = blockedEvents.length,
+                                                       html = document.body.parentNode;
+
+                                               if ($) {
+                                                       // setup new event shortcuts
+                                                       registerEventNames.forEach(function (name) {
+                                                               $.fn[name] = function (fn) {
+                                                                       return fn ? this.bind(name, fn) : this.trigger(name);
+                                                               };
+                                                               // jQuery < 1.8
+                                                               if ($.attrFn) {
+                                                                       $.attrFn[name] = true;
+                                                               }
+                                                       });
+
+                                                       event.copyEventProperties(window.screen, "orientationchange", eventUtils.orientationchange.properties);
+                                                       event.proxyEventTriggerMethod("orientationchange", eventUtils.orientationchange.trigger);
+
+                                                       // Proxies jQuery's trigger method to fire swipe event
+                                                       if (originalTrigger === undefined) {
+                                                               originalTrigger = $.fn.trigger;
+                                                               $.fn.trigger = event.proxyTrigger;
+                                                       }
+
+                                                       if (!originalDispatch) {
+                                                               originalDispatch = $.event.dispatch;
+                                                               $.event.dispatch = event.proxyDispatch;
+                                                       }
+
+                                                       $.mobile = $.mobile || {};
+                                                       $.mobile.tizen = $.mobile.tizen || {};
+                                                       $.mobile.tizen.documentRelativeCoordsFromEvent = null;
+                                                       $.mobile.tizen.targetRelativeCoordsFromEvent = null;
+                                                       $.mobile.addEventBlocker = function () {
+                                                               var i;
+
+                                                               html.classList.add("ui-blocker");
+                                                               for (i = 0; i < blockedEventsLength; i++) {
+                                                                       html.addEventListener(blockedEvents[i], removeEvents, true);
+                                                               }
+                                                       };
+                                                       $.mobile.removeEventBlocker = function () {
+                                                               var i;
+
+                                                               html.classList.remove("ui-blocker");
+                                                               for (i = 0; i < blockedEventsLength; i++) {
+                                                                       html.removeEventListener(blockedEvents[i], removeEvents, true);
+                                                               }
+                                                       };
+                                                       $.mobile.tizen.documentRelativeCoordsFromEvent = eventUtils.documentRelativeCoordsFromEvent.bind(eventUtils);
+                                                       $.mobile.tizen.targetRelativeCoordsFromEvent = eventUtils.targetRelativeCoordsFromEvent.bind(eventUtils);
+                                               }
+                                       },
+                                       /**
+                                        * Removes events listeners on destroy of framework.
+                                        */
+                                       destroy: function () {
+                                               document.removeEventListener(eventType.BEFOREROUTERINIT, event.init, false);
+                                               document.removeEventListener(eventType.DESTROY, event.destroy, false);
+                                       }
+                               };
+
+                       // Listen when framework is ready
+                       document.addEventListener(eventType.BEFOREROUTERINIT, event.init, false);
+                       document.addEventListener(eventType.DESTROY, event.destroy, false);
+
+                       ns.jqm.event = event;
+                       }(window, window.document));
+
+/*global window, ns, define, RegExp */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Path Utility
+ * Object helps work with paths.
+ * @class ns.util.path
+ * @static
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               /**
+                                * Local alias for ns.util.selectors
+                                * @property {Object} utilsSelectors Alias for {@link ns.util.selectors}
+                                * @member ns.util.path
+                                * @static
+                                * @private
+                                */
+                               utilsSelectors = ns.util.selectors,
+                               /**
+                                * Local alias for ns.util.DOM
+                                * @property {Object} utilsDOM Alias for {@link ns.util.DOM}
+                                * @member ns.util.path
+                                * @static
+                                * @private
+                                */
+                               utilsDOM = ns.util.DOM,
+                               /**
+                                * Cache for document base element
+                                * @member ns.util.path
+                                * @property {HTMLBaseElement} base
+                                * @static
+                                * @private
+                                */
+                               base,
+                               /**
+                                * location object
+                                * @property {Object} location
+                                * @static
+                                * @private
+                                * @member ns.util.path
+                                */
+                               location = {},
+                               path = {
+                                       /**
+                                        * href part for mark state
+                                        * @property {string} [uiStateKey="&ui-state"]
+                                        * @static
+                                        * @member ns.util.path
+                                        */
+                                       uiStateKey: "&ui-state",
+
+                                       // This scary looking regular expression parses an absolute URL or its relative
+                                       // variants (protocol, site, document, query, and hash), into the various
+                                       // components (protocol, host, path, query, fragment, etc that make up the
+                                       // URL as well as some other commonly used sub-parts. When used with RegExp.exec()
+                                       // or String.match, it parses the URL into a results array that looks like this:
+                                       //
+                                       //      [0]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#
+                                       //       msg-content?param1=true&param2=123
+                                       //      [1]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread
+                                       //      [2]: http://jblas:password@mycompany.com:8080/mail/inbox
+                                       //      [3]: http://jblas:password@mycompany.com:8080
+                                       //      [4]: http:
+                                       //      [5]: //
+                                       //      [6]: jblas:password@mycompany.com:8080
+                                       //      [7]: jblas:password
+                                       //      [8]: jblas
+                                       //      [9]: password
+                                       //      [10]: mycompany.com:8080
+                                       //      [11]: mycompany.com
+                                       //      [12]: 8080
+                                       //      [13]: /mail/inbox
+                                       //      [14]: /mail/
+                                       //      [15]: inbox
+                                       //      [16]: ?msg=1234&type=unread
+                                       //      [17]: #msg-content?param1=true&param2=123
+                                       //      [18]: #msg-content
+                                       //      [19]: ?param1=true&param2=123
+                                       //
+                                       /**
+                                        * @property {RegExp} urlParseRE Regular expression for parse URL
+                                        * @member ns.util.path
+                                        * @static
+                                        */
+                                       urlParseRE: /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)((#[^\?]*)(\?.*)?)?/,
+
+                                       /**
+                                        * Abstraction to address xss (Issue #4787) by removing the authority in
+                                        * browsers that auto decode it. All references to location.href should be
+                                        * replaced with a call to this method so that it can be dealt with properly here
+                                        * @method getLocation
+                                        * @param {string|Object} [url]
+                                        * @return {string}
+                                        * @member ns.util.path
+                                        */
+                                       getLocation: function (url) {
+                                               var uri = this.parseUrl(url || window.location.href),
+                                                       hash = uri.hash,
+                                                       search = uri.hashSearch;
+                                               // mimic the browser with an empty string when the hash and hashSearch are empty
+
+                                               hash = hash === "#" && !search ? "" : hash;
+                                               location = uri;
+                                               // Make sure to parse the url or the location object for the hash because using
+                                               // location.hash is automatically decoded in firefox, the rest of the url should be from the
+                                               // object (location unless we're testing) to avoid the inclusion of the authority
+                                               return uri.protocol + "//" + uri.host + uri.pathname + uri.search + hash + search;
+                                       },
+
+                                       /**
+                                        * Return the original document url
+                                        * @method getDocumentUrl
+                                        * @member ns.util.path
+                                        * @param {boolean} [asParsedObject=false]
+                                        * @return {string|Object}
+                                        * @static
+                                        */
+                                       getDocumentUrl: function (asParsedObject) {
+                                               return asParsedObject ? utilsObject.copy(path.documentUrl) : path.documentUrl.href;
+                                       },
+
+                                       /**
+                                        * Parse a location into a structure
+                                        * @method parseLocation
+                                        * @return {Object}
+                                        * @member ns.util.path
+                                        */
+                                       parseLocation: function () {
+                                               return this.parseUrl(this.getLocation());
+                                       },
+
+                                       /**
+                                        * Parse a URL into a structure that allows easy access to
+                                        * all of the URL components by name.
+                                        * If we're passed an object, we'll assume that it is
+                                        * a parsed url object and just return it back to the caller.
+                                        * @method parseUrl
+                                        * @member ns.util.path
+                                        * @param {string|Object} url
+                                        * @return {Object} uri record
+                                        * @return {string} return.href
+                                        * @return {string} return.hrefNoHash
+                                        * @return {string} return.hrefNoSearch
+                                        * @return {string} return.domain
+                                        * @return {string} return.protocol
+                                        * @return {string} return.doubleSlash
+                                        * @return {string} return.authority
+                                        * @return {string} return.username
+                                        * @return {string} return.password
+                                        * @return {string} return.host
+                                        * @return {string} return.hostname
+                                        * @return {string} return.port
+                                        * @return {string} return.pathname
+                                        * @return {string} return.directory
+                                        * @return {string} return.filename
+                                        * @return {string} return.search
+                                        * @return {string} return.hash
+                                        * @return {string} return.hashSearch
+                                        * @static
+                                        */
+                                       parseUrl: function (url) {
+                                               var matches;
+
+                                               if (typeof url === "object") {
+                                                       return url;
+                                               }
+                                               matches = path.urlParseRE.exec(url || "") || [];
+
+                                               // Create an object that allows the caller to access the sub-matches
+                                               // by name. Note that IE returns an empty string instead of undefined,
+                                               // like all other browsers do, so we normalize everything so its consistent
+                                               // no matter what browser we're running on.
+                                               return {
+                                                       href: matches[0] || "",
+                                                       hrefNoHash: matches[1] || "",
+                                                       hrefNoSearch: matches[2] || "",
+                                                       domain: matches[3] || "",
+                                                       protocol: matches[4] || "",
+                                                       doubleSlash: matches[5] || "",
+                                                       authority: matches[6] || "",
+                                                       username: matches[8] || "",
+                                                       password: matches[9] || "",
+                                                       host: matches[10] || "",
+                                                       hostname: matches[11] || "",
+                                                       port: matches[12] || "",
+                                                       pathname: matches[13] || "",
+                                                       directory: matches[14] || "",
+                                                       filename: matches[15] || "",
+                                                       search: matches[16] || "",
+                                                       hash: matches[18] || "",
+                                                       hashSearch: matches[19] || ""
+                                               };
+                                       },
+
+                                       /**
+                                        * Turn relPath into an absolute path. absPath is
+                                        * an optional absolute path which describes what
+                                        * relPath is relative to.
+                                        * @method makePathAbsolute
+                                        * @member ns.util.path
+                                        * @param {string} relPath
+                                        * @param {string} [absPath=""]
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       makePathAbsolute: function (relPath, absPath) {
+                                               var absStack,
+                                                       relStack,
+                                                       directory,
+                                                       i;
+
+                                               if (relPath && relPath.charAt(0) === "/") {
+                                                       return relPath;
+                                               }
+
+                                               relPath = relPath || "";
+                                               absPath = absPath ? absPath.replace(/^\/|(\/[^\/]*|[^\/]+)$/g, "") : "";
+
+                                               absStack = absPath ? absPath.split("/") : [];
+                                               relStack = relPath.split("/");
+                                               for (i = 0; i < relStack.length; i++) {
+                                                       directory = relStack[i];
+                                                       switch (directory) {
+                                                               case ".":
+                                                                       break;
+                                                               case "..":
+                                                                       if (absStack.length) {
+                                                                               absStack.pop();
+                                                                       }
+                                                                       break;
+                                                               default:
+                                                                       absStack.push(directory);
+                                                                       break;
+                                                       }
+                                               }
+                                               return "/" + absStack.join("/");
+                                       },
+
+                                       /**
+                                        * Returns true if both urls have the same domain.
+                                        * @method isSameDomain
+                                        * @member ns.util.path
+                                        * @param {string|Object} absUrl1
+                                        * @param {string|Object} absUrl2
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       isSameDomain: function (absUrl1, absUrl2) {
+                                               return path.parseUrl(absUrl1).domain === path.parseUrl(absUrl2).domain;
+                                       },
+
+                                       /**
+                                        * Returns true for any relative variant.
+                                        * @method isRelativeUrl
+                                        * @member ns.util.path
+                                        * @param {string|Object} url
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       isRelativeUrl: function (url) {
+                                               // All relative Url variants have one thing in common, no protocol.
+                                               return path.parseUrl(url).protocol === "";
+                                       },
+
+                                       /**
+                                        * Returns true for an absolute url.
+                                        * @method isAbsoluteUrl
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       isAbsoluteUrl: function (url) {
+                                               return path.parseUrl(url).protocol !== "";
+                                       },
+
+                                       /**
+                                        * Turn the specified relative URL into an absolute one. This function
+                                        * can handle all relative variants (protocol, site, document, query, fragment).
+                                        * @method makeUrlAbsolute
+                                        * @member ns.util.path
+                                        * @param {string} relUrl
+                                        * @param {string} absUrl
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       makeUrlAbsolute: function (relUrl, absUrl) {
+                                               var relObj,
+                                                       absObj,
+                                                       protocol,
+                                                       doubleSlash,
+                                                       authority,
+                                                       hasPath,
+                                                       pathname,
+                                                       search,
+                                                       hash;
+
+                                               if (!path.isRelativeUrl(relUrl)) {
+                                                       return relUrl;
+                                               }
+
+                                               relObj = path.parseUrl(relUrl);
+                                               absObj = path.parseUrl(absUrl);
+                                               protocol = relObj.protocol || absObj.protocol;
+                                               doubleSlash = relObj.protocol ? relObj.doubleSlash : (relObj.doubleSlash || absObj.doubleSlash);
+                                               authority = relObj.authority || absObj.authority;
+                                               hasPath = relObj.pathname !== "";
+                                               pathname = path.makePathAbsolute(relObj.pathname || absObj.filename, absObj.pathname);
+                                               search = relObj.search || (!hasPath && absObj.search) || "";
+                                               hash = relObj.hash;
+
+                                               return protocol + doubleSlash + authority + pathname + search + hash;
+                                       },
+
+                                       /**
+                                        * Add search (aka query) params to the specified url.
+                                        * If page is embedded page, search query will be added after
+                                        * hash tag. It's allowed to add query content for both external
+                                        * pages and embedded pages.
+                                        * Examples:
+                                        * http://domain/path/index.html#embedded?search=test
+                                        * http://domain/path/external.html?s=query#embedded?s=test
+                                        * @method addSearchParams
+                                        * @member ns.util.path
+                                        * @param {string|Object} url
+                                        * @param {Object|string} params
+                                        * @return {string}
+                                        */
+                                       addSearchParams: function (url, params) {
+                                               var urlObject = path.parseUrl(url),
+                                                       paramsString = (typeof params === "object") ? this.getAsURIParameters(params) : params,
+                                                       searchChar,
+                                                       urlObjectHash = urlObject.hash;
+
+                                               if (path.isEmbedded(url) && paramsString.length > 0) {
+                                                       searchChar = urlObject.hashSearch || "?";
+                                                       return urlObject.hrefNoHash + (urlObjectHash || "") + searchChar + (searchChar.charAt(searchChar.length - 1) === "?" ? "" : "&") + paramsString;
+                                               }
+
+                                               searchChar = urlObject.search || "?";
+                                               return urlObject.hrefNoSearch + searchChar + (searchChar.charAt(searchChar.length - 1) === "?" ? "" : "&") + paramsString + (urlObjectHash || "");
+                                       },
+
+                                       /**
+                                        * Add search params to the specified url with hash
+                                        * @method addHashSearchParams
+                                        * @member ns.util.path
+                                        * @param {string|Object} url
+                                        * @param {Object|string} params
+                                        * @return {string}
+                                        */
+                                       addHashSearchParams: function (url, params) {
+                                               var urlObject = path.parseUrl(url),
+                                                       paramsString = (typeof params === "object") ? path.getAsURIParameters(params) : params,
+                                                       hash = urlObject.hash,
+                                                       searchChar = hash ? (hash.indexOf("?") < 0 ? hash + "?" : hash + "&") : "#?";
+
+                                               return urlObject.hrefNoHash + searchChar + (searchChar.charAt(searchChar.length - 1) === "?" ? "" : "&") + paramsString;
+                                       },
+
+                                       /**
+                                        * Convert absolute Url to data Url
+                                        * - for embedded pages strips parameters
+                                        * - for the same domain as document base remove domain
+                                        * otherwise returns decoded absolute Url
+                                        * @method convertUrlToDataUrl
+                                        * @member ns.util.path
+                                        * @param {string} absUrl
+                                        * @param {boolean} dialogHashKey
+                                        * @param {Object} documentBase uri structure
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       convertUrlToDataUrl: function (absUrl, dialogHashKey, documentBase) {
+                                               var urlObject = path.parseUrl(absUrl);
+
+                                               if (path.isEmbeddedPage(urlObject, !!dialogHashKey)) {
+                                                       // Keep hash and search data for embedded page
+                                                       return path.getFilePath(urlObject.hash + urlObject.hashSearch, dialogHashKey);
+                                               }
+                                               documentBase = documentBase || path.documentBase;
+                                               if (path.isSameDomain(urlObject, documentBase)) {
+                                                       return urlObject.hrefNoHash.replace(documentBase.domain, "");
+                                               }
+
+                                               return window.decodeURIComponent(absUrl);
+                                       },
+
+                                       /**
+                                        * Get path from current hash, or from a file path
+                                        * @method get
+                                        * @member ns.util.path
+                                        * @param {string} newPath
+                                        * @return {string}
+                                        */
+                                       get: function (newPath) {
+                                               if (newPath === undefined) {
+                                                       newPath = this.parseLocation().hash;
+                                               }
+                                               return this.stripHash(newPath).replace(/[^\/]*\.[^\/*]+$/, "");
+                                       },
+
+                                       /**
+                                        * Test if a given url (string) is a path
+                                        * NOTE might be exceptionally naive
+                                        * @method isPath
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       isPath: function (url) {
+                                               return (/\//).test(url);
+                                       },
+
+                                       /**
+                                        * Return a url path with the window's location protocol/hostname/pathname removed
+                                        * @method clean
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @param {Object} documentBase  uri structure
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       clean: function (url, documentBase) {
+                                               return url.replace(documentBase.domain, "");
+                                       },
+
+                                       /**
+                                        * Just return the url without an initial #
+                                        * @method stripHash
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       stripHash: function (url) {
+                                               return url.replace(/^#/, "");
+                                       },
+
+                                       /**
+                                        * Return the url without an query params
+                                        * @method stripQueryParams
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       stripQueryParams: function (url) {
+                                               return url.replace(/\?.*$/, "");
+                                       },
+
+                                       /**
+                                        * Validation proper hash
+                                        * @method isHashValid
+                                        * @member ns.util.path
+                                        * @param {string} hash
+                                        * @static
+                                        */
+                                       isHashValid: function (hash) {
+                                               return (/^#[^#]+$/).test(hash);
+                                       },
+
+                                       /**
+                                        * Check whether a url is referencing the same domain, or an external domain or different
+                                        * protocol could be mailto, etc
+                                        * @method isExternal
+                                        * @member ns.util.path
+                                        * @param {string|Object} url
+                                        * @param {Object} documentUrl uri object
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       isExternal: function (url, documentUrl) {
+                                               var urlObject = path.parseUrl(url);
+
+                                               return urlObject.protocol && urlObject.domain !== documentUrl.domain ? true : false;
+                                       },
+
+                                       /**
+                                        * Check if the url has protocol
+                                        * @method hasProtocol
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       hasProtocol: function (url) {
+                                               return (/^(:?\w+:)/).test(url);
+                                       },
+
+                                       /**
+                                        * Check if the url refers to embedded content
+                                        * @method isEmbedded
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       isEmbedded: function (url) {
+                                               var urlObject = path.parseUrl(url);
+
+                                               if (urlObject.protocol !== "") {
+                                                       return (!path.isPath(urlObject.hash) && !!urlObject.hash && (urlObject.hrefNoHash === path.parseLocation().hrefNoHash));
+                                               }
+                                               return (/\?.*#|^#/).test(urlObject.href);
+                                       },
+
+                                       /**
+                                        * Get the url as it would look squashed on to the current resolution url
+                                        * @method squash
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @param {string} [resolutionUrl=undefined]
+                                        * @return {string}
+                                        */
+                                       squash: function (url, resolutionUrl) {
+                                               var href,
+                                                       cleanedUrl,
+                                                       search,
+                                                       stateIndex,
+                                                       isPath = this.isPath(url),
+                                                       uri = this.parseUrl(url),
+                                                       preservedHash = uri.hash,
+                                                       uiState = "";
+
+                                               // produce a url against which we can resole the provided path
+                                               resolutionUrl = resolutionUrl || (path.isPath(url) ? path.getLocation() : path.getDocumentUrl());
+
+                                               // If the url is anything but a simple string, remove any preceding hash
+                                               // eg #foo/bar -> foo/bar
+                                               //      #foo -> #foo
+                                               cleanedUrl = isPath ? path.stripHash(url) : url;
+
+                                               // If the url is a full url with a hash check if the parsed hash is a path
+                                               // if it is, strip the #, and use it otherwise continue without change
+                                               cleanedUrl = path.isPath(uri.hash) ? path.stripHash(uri.hash) : cleanedUrl;
+
+                                               // Split the UI State keys off the href
+                                               stateIndex = cleanedUrl.indexOf(this.uiStateKey);
+
+                                               // store the ui state keys for use
+                                               if (stateIndex > -1) {
+                                                       uiState = cleanedUrl.slice(stateIndex);
+                                                       cleanedUrl = cleanedUrl.slice(0, stateIndex);
+                                               }
+
+                                               // make the cleanedUrl absolute relative to the resolution url
+                                               href = path.makeUrlAbsolute(cleanedUrl, resolutionUrl);
+
+                                               // grab the search from the resolved url since parsing from
+                                               // the passed url may not yield the correct result
+                                               search = this.parseUrl(href).search;
+
+                                               // @TODO all this crap is terrible, clean it up
+                                               if (isPath) {
+                                                       // reject the hash if it's a path or it's just a dialog key
+                                                       if (path.isPath(preservedHash) || preservedHash.replace("#", "").indexOf(this.uiStateKey) === 0) {
+                                                               preservedHash = "";
+                                                       }
+
+                                                       // Append the UI State keys where it exists and it's been removed
+                                                       // from the url
+                                                       if (uiState && preservedHash.indexOf(this.uiStateKey) === -1) {
+                                                               preservedHash += uiState;
+                                                       }
+
+                                                       // make sure that pound is on the front of the hash
+                                                       if (preservedHash.indexOf("#") === -1 && preservedHash !== "") {
+                                                               preservedHash = "#" + preservedHash;
+                                                       }
+
+                                                       // reconstruct each of the pieces with the new search string and hash
+                                                       href = path.parseUrl(href);
+                                                       href = href.protocol + "//" + href.host + href.pathname + search + preservedHash;
+                                               } else {
+                                                       href += href.indexOf("#") > -1 ? uiState : "#" + uiState;
+                                               }
+
+                                               return href;
+                                       },
+
+                                       /**
+                                        * Check if the hash is preservable
+                                        * @method isPreservableHash
+                                        * @member ns.util.path
+                                        * @param {string} hash
+                                        * @return {boolean}
+                                        */
+                                       isPreservableHash: function (hash) {
+                                               return hash.replace("#", "").indexOf(this.uiStateKey) === 0;
+                                       },
+
+                                       /**
+                                        * Escape weird characters in the hash if it is to be used as a selector
+                                        * @method hashToSelector
+                                        * @member ns.util.path
+                                        * @param {string} hash
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       hashToSelector: function (hash) {
+                                               var hasHash = (hash.substring(0, 1) === "#");
+
+                                               if (hasHash) {
+                                                       hash = hash.substring(1);
+                                               }
+                                               return (hasHash ? "#" : "") + hash.replace(new RegExp("([!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~])", "g"), "\\$1");
+                                       },
+
+                                       /**
+                                        * Check if the specified url refers to the first page in the main application document.
+                                        * @method isFirstPageUrl
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @param {HTMLElement} firstPageElement first page element
+                                        * @param {string} documentBase uri structure
+                                        * @param {boolean} documentBaseDiffers
+                                        * @param {Object} documentUrl uri structure
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       isFirstPageUrl: function (url, firstPageElement, documentBase, documentBaseDiffers, documentUrl) {
+                                               var urlStructure,
+                                                       samePath,
+                                                       firstPageId,
+                                                       hash;
+
+                                               documentBase = documentBase === undefined ? path.documentBase : documentBase;
+                                               documentBaseDiffers = documentBaseDiffers === undefined ? path.documentBaseDiffers : documentBaseDiffers;
+                                               documentUrl = documentUrl === undefined ? path.documentUrl : documentUrl;
+
+                                               // We only deal with absolute paths.
+                                               urlStructure = path.parseUrl(path.makeUrlAbsolute(url, documentBase));
+
+                                               // Does the url have the same path as the document?
+                                               samePath = urlStructure.hrefNoHash === documentUrl.hrefNoHash || (documentBaseDiffers && urlStructure.hrefNoHash === documentBase.hrefNoHash);
+
+                                               // Get the id of the first page element if it has one.
+                                               firstPageId = firstPageElement && firstPageElement.id || false;
+                                               hash = urlStructure.hash;
+
+                                               // The url refers to the first page if the path matches the document and
+                                               // it either has no hash value, or the hash is exactly equal to the id of the
+                                               // first page element.
+                                               return samePath && (!hash || hash === "#" || (firstPageId && hash.replace(/^#/, "") === firstPageId));
+                                       },
+
+                                       /**
+                                        * Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR
+                                        * requests if the document doing the request was loaded via the file:// protocol.
+                                        * This is usually to allow the application to "phone home" and fetch app specific
+                                        * data. We normally let the browser handle external/cross-domain urls, but if the
+                                        * allowCrossDomainPages option is true, we will allow cross-domain http/https
+                                        * requests to go through our page loading logic.
+                                        * @method isPermittedCrossDomainRequest
+                                        * @member ns.util.path
+                                        * @param {Object} docUrl
+                                        * @param {string} reqUrl
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       isPermittedCrossDomainRequest: function (docUrl, reqUrl) {
+                                               return ns.getConfig("allowCrossDomainPages", false) &&
+                                                       docUrl.protocol === "file:" &&
+                                                       reqUrl.search(/^https?:/) !== -1;
+                                       },
+
+                                       /**
+                                        * Convert a object data to URI parameters
+                                        * @method getAsURIParameters
+                                        * @member ns.util.path
+                                        * @param {Object} data
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       getAsURIParameters: function (data) {
+                                               var url = "",
+                                                       key;
+
+                                               for (key in data) {
+                                                       if (data.hasOwnProperty(key)) {
+                                                               url += encodeURIComponent(key) + "=" + encodeURIComponent(data[key]) + "&";
+                                                       }
+                                               }
+                                               return url.substring(0, url.length - 1);
+                                       },
+
+                                       /**
+                                        * Document Url
+                                        * @member ns.util.path
+                                        * @property {string|null} documentUrl
+                                        */
+                                       documentUrl: null,
+
+                                       /**
+                                        * The document base differs
+                                        * @member ns.util.path
+                                        * @property {boolean} documentBaseDiffers
+                                        */
+                                       documentBaseDiffers: false,
+
+                                       /**
+                                        * Set location hash to path
+                                        * @method set
+                                        * @member ns.util.path
+                                        * @param {string} path
+                                        * @static
+                                        */
+                                       set: function (path) {
+                                               location.hash = path;
+                                       },
+
+                                       /**
+                                        * Return the substring of a file path before the sub-page key,
+                                        * for making a server request
+                                        * @method getFilePath
+                                        * @member ns.util.path
+                                        * @param {string} path
+                                        * @param {string} dialogHashKey
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       getFilePath: function (path, dialogHashKey) {
+                                               var splitKey = "&" + ns.getConfig("subPageUrlKey", "");
+
+                                               return path && path.split(splitKey)[0].split(dialogHashKey)[0];
+                                       },
+
+                                       /**
+                                        * Remove the preceding hash, any query params, and dialog notations
+                                        * @method cleanHash
+                                        * @member ns.util.path
+                                        * @param {string} hash
+                                        * @param {string} dialogHashKey
+                                        * @return {string}
+                                        * @static
+                                        */
+                                       cleanHash: function (hash, dialogHashKey) {
+                                               return path.stripHash(hash.replace(/\?.*$/, "").replace(dialogHashKey, ""));
+                                       },
+
+                                       /**
+                                        * Check if url refers to the embedded page
+                                        * @method isEmbeddedPage
+                                        * @member ns.util.path
+                                        * @param {string} url
+                                        * @param {boolean} allowEmbeddedOnlyBaseDoc
+                                        * @return {boolean}
+                                        * @static
+                                        */
+                                       isEmbeddedPage: function (url, allowEmbeddedOnlyBaseDoc) {
+                                               var urlObject = path.parseUrl(url);
+
+                                               //if the path is absolute, then we need to compare the url against
+                                               //both the documentUrl and the documentBase. The main reason for this
+                                               //is that links embedded within external documents will refer to the
+                                               //application document, whereas links embedded within the application
+                                               //document will be resolved against the document base.
+                                               if (urlObject.protocol !== "") {
+                                                       return (urlObject.hash &&
+                                                       (allowEmbeddedOnlyBaseDoc ?
+                                                               urlObject.hrefNoHash === path.documentUrl.hrefNoHash :
+                                                               urlObject.hrefNoHash === path.parseLocation().hrefNoHash));
+                                               }
+                                               return (/^#/).test(urlObject.href);
+                                       }
+                               };
+
+                       path.documentUrl = path.parseLocation();
+
+                       base = document.querySelector("base");
+
+                       /**
+                        * The document base URL for the purposes of resolving relative URLs,
+                        * and the name of the default browsing context for the purposes of
+                        * following hyperlinks
+                        * @member ns.util.path
+                        * @property {Object} documentBase uri structure
+                        * @static
+                        */
+                       path.documentBase = base ? path.parseUrl(path.makeUrlAbsolute(base.getAttribute("href"),
+                               path.documentUrl.href)) : path.documentUrl;
+
+                       path.documentBaseDiffers = (path.documentUrl.hrefNoHash !== path.documentBase.hrefNoHash);
+
+                       /**
+                        * Get document base
+                        * @method getDocumentBase
+                        * @member ns.util.path
+                        * @param {boolean} [asParsedObject=false]
+                        * @return {string|Object}
+                        * @static
+                        */
+                       path.getDocumentBase = function (asParsedObject) {
+                               return asParsedObject ? utilsObject.copy(path.documentBase) : path.documentBase.href;
+                       };
+
+                       /**
+                        * Find the closest page and extract out its url
+                        * @method getClosestBaseUrl
+                        * @member ns.util.path
+                        * @param {HTMLElement} element
+                        * @param {string} selector
+                        * @return {string}
+                        * @static
+                        */
+                       path.getClosestBaseUrl = function (element, selector) {
+                               // Find the closest page and extract out its url.
+                               var url = utilsDOM.getNSData(utilsSelectors.getClosestBySelector(element, selector), "url"),
+                                       baseUrl = path.documentBase.hrefNoHash;
+
+                               if (!ns.getConfig("dynamicBaseEnabled", true) || !url || !path.isPath(url)) {
+                                       url = baseUrl;
+                               }
+
+                               return path.makeUrlAbsolute(url, baseUrl);
+                       };
+
+                       ns.util.path = path;
+                       }(window, window.document, ns));
+
+/**
+ *
+ */
+(function (window) {
+       "use strict";
+                               var isarray = Array.isArray;
+
+                       pathToRegexp.parse = parse
+                       pathToRegexp.compile = compile
+                       pathToRegexp.tokensToFunction = tokensToFunction
+                       pathToRegexp.tokensToRegExp = tokensToRegExp
+
+/**
+ * Start original file
+ * Licence MIT
+ * https://github.com/pillarjs/path-to-regexp
+ */
+/**
+ * The main path matching regexp utility.
+ *
+ * @type {RegExp}
+ */
+var PATH_REGEXP = new RegExp([
+       // Match escaped characters that would otherwise appear in future matches.
+       // This allows the user to escape special characters that won't transform.
+       '(\\\\.)',
+       // Match Express-style parameters and un-named parameters with a prefix
+       // and optional suffixes. Matches appear as:
+       //
+       // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?"]
+       // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined]
+       '([\\/.])?(?:\\:(\\w+)(?:\\(((?:\\\\.|[^)])*)\\))?|\\(((?:\\\\.|[^)])*)\\))([+*?])?'
+].join('|'), 'g')
+
+/**
+ * Parse a string for the raw tokens.
+ *
+ * @param  {String} str
+ * @return {Array}
+ */
+function parse (str) {
+       var tokens = []
+       var key = 0
+       var index = 0
+       var path = ''
+       var res
+
+       while ((res = PATH_REGEXP.exec(str)) != null) {
+               var m = res[0]
+               var escaped = res[1]
+               var offset = res.index
+               path += str.slice(index, offset)
+               index = offset + m.length
+
+               // Ignore already escaped sequences.
+               if (escaped) {
+                       path += escaped[1]
+                       continue
+               }
+
+               // Push the current path onto the tokens.
+               if (path) {
+                       tokens.push(path)
+                       path = ''
+               }
+
+               var prefix = res[2]
+               var name = res[3]
+               var capture = res[4]
+               var group = res[5]
+               var suffix = res[6]
+
+               var repeat = suffix === '+' || suffix === '*'
+               var optional = suffix === '?' || suffix === '*'
+               var delimiter = prefix || '/'
+
+               tokens.push({
+                       name: name || key++,
+                       prefix: prefix || '',
+                       delimiter: delimiter,
+                       optional: optional,
+                       repeat: repeat,
+                       pattern: escapeGroup(capture || group || '[^' + delimiter + ']+?')
+               })
+       }
+
+       // Match any characters still remaining.
+       if (index < str.length) {
+               path += str.substr(index)
+       }
+
+       // If the path exists, push it onto the end.
+       if (path) {
+               tokens.push(path)
+       }
+
+       return tokens
+}
+
+/**
+ * Compile a string to a template function for the path.
+ *
+ * @param  {String}   str
+ * @return {Function}
+ */
+function compile (str) {
+       return tokensToFunction(parse(str))
+}
+
+/**
+ * Expose a method for transforming tokens into the path function.
+ */
+function tokensToFunction (tokens) {
+       // Compile all the tokens into regexps.
+       var matches = new Array(tokens.length)
+
+       // Compile all the patterns before compilation.
+       for (var i = 0; i < tokens.length; i++) {
+               if (typeof tokens[i] === 'object') {
+                       matches[i] = new RegExp('^' + tokens[i].pattern + '$')
+               }
+       }
+
+       return function (obj) {
+               var path = ''
+
+               obj = obj || {}
+
+               for (var i = 0; i < tokens.length; i++) {
+                       var key = tokens[i]
+
+                       if (typeof key === 'string') {
+                               path += key
+
+                               continue
+                       }
+
+                       var value = obj[key.name]
+
+                       if (value == null) {
+                               if (key.optional) {
+                                       continue
+                               } else {
+                                       throw new TypeError('Expected "' + key.name + '" to be defined')
+                               }
+                       }
+
+                       if (isarray(value)) {
+                               if (!key.repeat) {
+                                       throw new TypeError('Expected "' + key.name + '" to not repeat')
+                               }
+
+                               if (value.length === 0) {
+                                       if (key.optional) {
+                                               continue
+                                       } else {
+                                               throw new TypeError('Expected "' + key.name + '" to not be empty')
+                                       }
+                               }
+
+                               for (var j = 0; j < value.length; j++) {
+                                       if (!matches[i].test(value[j])) {
+                                               throw new TypeError('Expected all "' + key.name + '" to match "' + key.pattern + '"')
+                                       }
+
+                                       path += (j === 0 ? key.prefix : key.delimiter) + encodeURIComponent(value[j])
+                               }
+
+                               continue
+                       }
+
+                       if (!matches[i].test(value)) {
+                               throw new TypeError('Expected "' + key.name + '" to match "' + key.pattern + '"')
+                       }
+
+                       path += key.prefix + encodeURIComponent(value)
+               }
+
+               return path
+       }
+}
+
+/**
+ * Escape a regular expression string.
+ *
+ * @param  {String} str
+ * @return {String}
+ */
+function escapeString (str) {
+       return str.replace(/([.+*?=^!:${}()[\]|\/])/g, '\\$1')
+}
+
+/**
+ * Escape the capturing group by escaping special characters and meaning.
+ *
+ * @param  {String} group
+ * @return {String}
+ */
+function escapeGroup (group) {
+       return group.replace(/([=!:$\/()])/g, '\\$1')
+}
+
+/**
+ * Attach the keys as a property of the regexp.
+ *
+ * @param  {RegExp} re
+ * @param  {Array}  keys
+ * @return {RegExp}
+ */
+function attachKeys (re, keys) {
+       re.keys = keys
+       return re
+}
+
+/**
+ * Get the flags for a regexp from the options.
+ *
+ * @param  {Object} options
+ * @return {String}
+ */
+function flags (options) {
+       return options.sensitive ? '' : 'i'
+}
+
+/**
+ * Pull out keys from a regexp.
+ *
+ * @param  {RegExp} path
+ * @param  {Array}  keys
+ * @return {RegExp}
+ */
+function regexpToRegexp (path, keys) {
+       // Use a negative lookahead to match only capturing groups.
+       var groups = path.source.match(/\((?!\?)/g)
+
+       if (groups) {
+               for (var i = 0; i < groups.length; i++) {
+                       keys.push({
+                               name: i,
+                               prefix: null,
+                               delimiter: null,
+                               optional: false,
+                               repeat: false,
+                               pattern: null
+                       })
+               }
+       }
+
+       return attachKeys(path, keys)
+}
+
+/**
+ * Transform an array into a regexp.
+ *
+ * @param  {Array}  path
+ * @param  {Array}  keys
+ * @param  {Object} options
+ * @return {RegExp}
+ */
+function arrayToRegexp (path, keys, options) {
+       var parts = []
+
+       for (var i = 0; i < path.length; i++) {
+               parts.push(pathToRegexp(path[i], keys, options).source)
+       }
+
+       var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
+
+       return attachKeys(regexp, keys)
+}
+
+/**
+ * Create a path regexp from string input.
+ *
+ * @param  {String} path
+ * @param  {Array}  keys
+ * @param  {Object} options
+ * @return {RegExp}
+ */
+function stringToRegexp (path, keys, options) {
+       var tokens = parse(path)
+       var re = tokensToRegExp(tokens, options)
+
+       // Attach keys back to the regexp.
+       for (var i = 0; i < tokens.length; i++) {
+               if (typeof tokens[i] !== 'string') {
+                       keys.push(tokens[i])
+               }
+       }
+
+       return attachKeys(re, keys)
+}
+
+/**
+ * Expose a function for taking tokens and returning a RegExp.
+ *
+ * @param  {Array}  tokens
+ * @param  {Array}  keys
+ * @param  {Object} options
+ * @return {RegExp}
+ */
+function tokensToRegExp (tokens, options) {
+       options = options || {}
+
+       var strict = options.strict
+       var end = options.end !== false
+       var route = ''
+       var lastToken = tokens[tokens.length - 1]
+       var endsWithSlash = typeof lastToken === 'string' && /\/$/.test(lastToken)
+
+       // Iterate over the tokens and create our regexp string.
+       for (var i = 0; i < tokens.length; i++) {
+               var token = tokens[i]
+
+               if (typeof token === 'string') {
+                       route += escapeString(token)
+               } else {
+                       var prefix = escapeString(token.prefix)
+                       var capture = token.pattern
+
+                       if (token.repeat) {
+                               capture += '(?:' + prefix + capture + ')*'
+                       }
+
+                       if (token.optional) {
+                               if (prefix) {
+                                       capture = '(?:' + prefix + '(' + capture + '))?'
+                               } else {
+                                       capture = '(' + capture + ')?'
+                               }
+                       } else {
+                               capture = prefix + '(' + capture + ')'
+                       }
+
+                       route += capture
+               }
+       }
+
+       // In non-strict mode we allow a slash at the end of match. If the path to
+       // match already ends with a slash, we remove it for consistency. The slash
+       // is valid at the end of a path match, not in the middle. This is important
+       // in non-ending mode, where "/test/" shouldn't match "/test//route".
+       if (!strict) {
+               route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?'
+       }
+
+       if (end) {
+               route += '$'
+       } else {
+               // In non-ending mode, we need the capturing groups to match as much as
+               // possible by using a positive lookahead to the end or next path segment.
+               route += strict && endsWithSlash ? '' : '(?=\\/|$)'
+       }
+
+       return new RegExp('^' + route, flags(options))
+}
+
+/**
+ * Normalize the given path string, returning a regular expression.
+ *
+ * An empty array can be passed in for the keys, which will hold the
+ * placeholder key descriptions. For example, using `/user/:id`, `keys` will
+ * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
+ *
+ * @param  {(String|RegExp|Array)} path
+ * @param  {Array}                 [keys]
+ * @param  {Object}                [
+ *
+ * options]
+ * @return {RegExp}
+ */
+function pathToRegexp (path, keys, options) {
+       keys = keys || []
+
+       if (!isarray(keys)) {
+               options = keys
+               keys = []
+       } else if (!options) {
+               options = {}
+       }
+
+       if (path instanceof RegExp) {
+               return regexpToRegexp(path, keys, options)
+       }
+
+       if (isarray(path)) {
+               return arrayToRegexp(path, keys, options)
+       }
+
+       return stringToRegexp(path, keys, options)
+}
+
+/**
+ * End original file
+ */
+                       window.pathToRegexp = pathToRegexp;
+                       }(window));
+/*global define, ns */
+/*
+ * Copyright (c) 2010 - 2014 Samsung Electronics Co., Ltd.
+ * License : MIT License V2
+ */
+/**
+ * #Path to Regexp Utility
+ * Convert string to regexp and can match path string to one defined regex path
+ *
+ * Syntax of paths is the same as in Express for nodejs
+ *
+ * Library based on https://github.com/pillarjs/path-to-regexp
+ * @class ns.util.pathToRegexp
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ *
+ */
+(function (window) {
+       "use strict";
+       
+                       ns.util.pathToRegexp = window.pathToRegexp;
+
+                       }(window));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Router
+ * Namespace for routers
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @class ns.router
+ */
+(function () {
+       "use strict";
+                               ns.router = ns.router || {};
+                       }());
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Route Namespace
+ * Object contains rules for router.
+ *
+ * @class ns.router.route
+ */
+/*
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function () {
+       "use strict";
+                               ns.router.route = ns.router.route || {};
+                       }());
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/**
+ * #History
+ * Object controls history changes.
+ *
+ * @class ns.history
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function (window) {
+       "use strict";
+                               var historyVolatileMode,
+                               object = ns.util.object,
+                               historyUid = 0,
+                               historyActiveIndex = 0,
+                               windowHistory = window.history,
+                               history = {
+                                       /**
+                                        * Property contains active state in history.
+                                        * @property {Object} activeState
+                                        * @static
+                                        * @member ns.history
+                                        */
+                                       activeState: null,
+
+                                       /**
+                                        * Property contains starting url for tau instance
+                                        * @property {Object} startURL
+                                        * @static
+                                        * @member ns.history
+                                        */
+                                       startURL: null,
+
+                                       /**
+                                        * This method replaces or pushes state to history.
+                                        * @method replace
+                                        * @param {Object} state The state object
+                                        * @param {string} stateTitle The title of state
+                                        * @param {string} url The new history entry's URL
+                                        * @static
+                                        * @member ns.history
+                                        */
+                                       replace: function (state, stateTitle, url) {
+                                               var newState = object.merge({}, state, {
+                                                       uid: historyVolatileMode ? historyActiveIndex : ++historyUid,
+                                                       stateUrl: url,
+                                                       stateTitle: stateTitle
+                                               });
+
+                                               if (!this.startURL && url && url.length) {
+                                                       this.startURL = url;
+                                               }
+                                               windowHistory[historyVolatileMode ? "replaceState" : "pushState"](newState, stateTitle, url);
+                                               history.setActive(newState);
+                                       },
+
+                                       /**
+                                        * This method moves backward through history.
+                                        * @method back
+                                        * @static
+                                        * @member ns.history
+                                        */
+                                       back: function () {
+
+                                               var event;
+
+                                               // If we are out of the start page go back to previous page
+                                               // otherwise handle page internal history e.g. for panel
+                                               //
+                                               // TODO: handle widget history when on page different than start page
+                                               //
+                                               if (this.startURL !== window.location.href) {
+                                                       windowHistory.back();
+                                               } else {
+                                                       event = new CustomEvent("tauback", {
+                                                               "bubbles": true,
+                                                               "cancelable": true
+                                                       });
+
+                                                       document.body.dispatchEvent(event);
+                                               }
+                                       },
+
+                                       /**
+                                        * This method sets active state.
+                                        * @method setActive
+                                        * @param {Object} state Activated state
+                                        * @static
+                                        * @member ns.history
+                                        */
+                                       setActive: function (state) {
+                                               if (state) {
+                                                       history.activeState = state;
+                                                       historyActiveIndex = state.uid;
+
+                                                       if (state.volatileRecord) {
+                                                               history.enableVolatileMode();
+                                                               return;
+                                                       }
+                                               }
+
+                                               history.disableVolatileMode();
+                                       },
+
+                                       /**
+                                        * This method returns "back" if state is in history or "forward" if it is new state.
+                                        * @method getDirection
+                                        * @param {Object} state Checked state
+                                        * @return {"back"|"forward"}
+                                        * @static
+                                        * @member ns.history
+                                        */
+                                       getDirection: function (state) {
+                                               if (state) {
+                                                       return state.uid <= historyActiveIndex ? "back" : "forward";
+                                               }
+                                               return "back";
+                                       },
+
+                                       /**
+                                        * This method sets volatile mode to true.
+                                        * @method enableVolatileMode
+                                        * @static
+                                        * @member ns.history
+                                        */
+                                       enableVolatileMode: function () {
+                                               historyVolatileMode = true;
+                                       },
+
+                                       /**
+                                        * This method sets volatile mode to false.
+                                        * @method disableVolatileMode
+                                        * @static
+                                        * @member ns.history
+                                        */
+                                       disableVolatileMode: function () {
+                                               historyVolatileMode = false;
+                                       }
+                               };
+
+                       ns.history = history;
+                       }(window));
+
+/*global window, define, ns */
+/*jslint browser: true, nomen: true */
+/**
+ * # History manager
+ *
+ * Control events connected with history change and trigger events to controller
+ * or router.
+ *
+ * @class ns.history.manager
+ * @since 2.4
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+/**
+ * Event historystatechange
+ * @event historystatechange
+ * @class ns.history.manager
+ */
+/**
+ * Event historyhashchange
+ * @event historyhashchange
+ * @class ns.history.manager
+ */
+/**
+ * Event historyenabled
+ * @event historyenabled
+ * @class ns.history.manager
+ */
+/**
+ * Event historydisabled
+ * @event historydisabled
+ * @class ns.history.manager
+ */
+(function (window, document) {
+       "use strict";
+                               var manager = Object.create(null), // we don't need the Object proto
+                               WINDOW_EVENT_POPSTATE = "popstate",
+                               WINDOW_EVENT_HASHCHANGE = "hashchange",
+                               DOC_EVENT_VCLICK = "vclick",
+                               LINK_SELECTOR = "a,tau-button",
+                               util = ns.util,
+                               history = ns.history,
+                               eventUtils = ns.event,
+                               selectorUtils = util.selectors,
+                               objectUtils = util.object,
+                               pathUtils = util.path,
+                               DOM = util.DOM,
+                               EVENT_STATECHANGE = "historystatechange",
+                               EVENT_HASHCHANGE = "historyhashchange",
+                               EVENT_ENABLED = "historyenabled",
+                               EVENT_DISABLED = "historydisabled",
+                               /**
+                                * Engine event types
+                                * @property {Object} events
+                                * @property {string} events.STATECHANGE="historystatechange" event name on history manager change state
+                                * @property {string} events.HASHCHANGE="historyhashchange" event name on history manager change hash
+                                * @property {string} events.ENABLED="historyenabled" event name on enable history manager
+                                * @property {string} events.DISABLED="historydisabled" event name on disable history manager
+                                * @static
+                                * @readonly
+                                * @member ns.history.manager
+                                */
+                               events = {
+                                       STATECHANGE: EVENT_STATECHANGE,
+                                       HASHCHANGE: EVENT_HASHCHANGE,
+                                       ENABLED: EVENT_ENABLED,
+                                       DISABLED: EVENT_DISABLED
+                               };
+
+                       manager.events = events;
+
+                       /**
+                        * Trigger event "historystatechange" on document
+                        * @param {Object} options
+                        * @return {boolean}
+                        */
+                       function triggerStateChange(options) {
+                               return eventUtils.trigger(document, EVENT_STATECHANGE, options, true, true);
+                       }
+
+                       /**
+                        * Callback for link click
+                        * @param {Event} event
+                        * @return {boolean}
+                        */
+                       function onLinkAction(event) {
+                               var target = event.target,
+                                       link = selectorUtils.getClosestBySelector(target, LINK_SELECTOR),
+                                       href,
+                                       useDefaultUrlHandling,
+                                       result = true,
+                                       options, // this should be empty object but some utils that work on it
+                                       rel; // require hasOwnProperty :(
+
+                                                               if (link && event.which === 1) {
+                                       href = link.getAttribute("href");
+                                       rel = link.getAttribute("rel");
+                                       useDefaultUrlHandling = rel === "external" || link.hasAttribute("target");
+                                       if (!useDefaultUrlHandling) {
+                                               options = DOM.getData(link);
+                                               options.event = event;
+                                               if (rel && !options.rel) {
+                                                       options.rel = rel;
+                                               } else {
+                                                       rel = options.rel;
+                                               }
+                                               if (href && !options.href) {
+                                                       options.href = href;
+                                               }
+                                               if (rel === "popup" && !options.link) {
+                                                       options.link = link;
+                                               }
+                                               history.disableVolatileMode();
+                                               // mark as handled for back button
+                                               if (rel === "back") {
+                                                       eventUtils.preventDefault(event);
+                                                       result = false;
+                                               }
+                                               if (!triggerStateChange(options)) {
+                                                       // mark as handled
+                                                       eventUtils.preventDefault(event);
+                                                       result = false;
+                                               }
+                                       }
+                               }
+                               return result;
+                       }
+
+
+                       /**
+                        * Callback on popstate event.
+                        * @param {Event} event
+                        */
+                       function onPopState(event) {
+                               var state = event.state,
+                                       lastState = history.activeState,
+                                       options = {},
+                                       reverse,
+                                       resultOfTrigger = true,
+                                       skipTriggerStateChange = false;
+
+                                                               if (manager.locked) {
+                                       history.disableVolatileMode();
+                                       if (lastState) {
+                                               history.replace(lastState, lastState.stateTitle, lastState.stateUrl);
+                                       }
+                               } else if (state) {
+                                       reverse = history.getDirection(state) === "back";
+                                       options = objectUtils.merge(options, state, {
+                                               reverse: reverse,
+                                               transition: reverse ? ((lastState && lastState.transition) || "none") : state.transition,
+                                               fromHashChange: true
+                                       });
+
+                                       if (lastState) {
+                                               resultOfTrigger = eventUtils.trigger(document, EVENT_HASHCHANGE, objectUtils.merge(options,
+                                                       {url: pathUtils.getLocation(), stateUrl: lastState.stateUrl}), true, true);
+
+                                               
+                                               // if EVENT HASHCHANGE has been triggered successfully then skip trigger HistoryStateChange
+                                               skipTriggerStateChange = resultOfTrigger;
+                                       }
+
+                                       state.url = pathUtils.getLocation();
+                                       history.setActive(state);
+
+                                       if (!skipTriggerStateChange) {
+                                               options.event = event;
+                                               triggerStateChange(options);
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Callback on "hashchange" event
+                        * @param {Event} event
+                        */
+                       function onHashChange(event) {
+                               var newURL = event.newURL;
+
+                                                               if (newURL && history.activeState.url !== newURL) {
+                                       triggerStateChange({href: newURL, fromHashChange: true, event: event});
+                               }
+                       }
+
+                       /**
+                        * Inform that manager is enabled or not.
+                        * @property {boolean} [enabled=true]
+                        * @static
+                        * @since 2.4
+                        * @member ns.history.manager
+                        */
+                       manager.enabled = true;
+                       /**
+                        * Informs that manager is enabled or not.
+                        *
+                        * If manager is locked then not trigger events historystatechange.
+                        * @property {boolean} [locked=false]
+                        * @static
+                        * @since 2.4
+                        * @member ns.history.manager
+                        */
+                       manager.locked = false;
+
+                       /**
+                        * Locks history manager.
+                        *
+                        * Sets locked property to true.
+                        *
+                        *      @example
+                        *              tau.history.manager.lock();
+                        *
+                        * @method lock
+                        * @static
+                        * @since 2.4
+                        * @member ns.history.manager
+                        */
+                       manager.lock = function () {
+                               this.locked = true;
+                       };
+
+                       /**
+                        * Unlocks history manager.
+                        *
+                        * Sets locked property to false.
+                        *
+                        *      @example
+                        *              tau.history.manager.unlock();
+                        *
+                        * @method unlock
+                        * @static
+                        * @since 2.4
+                        * @member ns.history.manager
+                        */
+                       manager.unlock = function () {
+                               this.locked = false;
+                       };
+
+                       /**
+                        * Enables history manager.
+                        *
+                        * This method adds all event listeners connected with history manager.
+                        *
+                        * Event listeners:
+                        *
+                        *  - popstate on window
+                        *  - hashchange on window
+                        *  - vclick on document
+                        *
+                        * After set event listeners method sets property enabled to true.
+                        *
+                        *      @example
+                        *              tau.history.manager.enable();
+                        *              // add event's listeners
+                        *              // after click on link or hash change history manager will handle events
+                        *
+                        * @method enable
+                        * @static
+                        * @since 2.4
+                        * @member ns.history.manager
+                        */
+                       manager.enable = function () {
+                               document.addEventListener(DOC_EVENT_VCLICK, onLinkAction, false);
+                               window.addEventListener(WINDOW_EVENT_POPSTATE, onPopState, false);
+                               window.addEventListener(WINDOW_EVENT_HASHCHANGE, onHashChange, false);
+                               history.enableVolatileMode();
+                               this.enabled = true;
+                               eventUtils.trigger(document, EVENT_ENABLED, this);
+                       };
+
+                       /**
+                        * Disables history manager.
+                        *
+                        * This method removes all event listeners connected with history manager.
+                        *
+                        * After set event listeners method sets property enabled to true.
+                        *
+                        *      @example
+                        *              tau.history.manager.disable();
+                        *              // remove event's listeners
+                        *              // after click on link or hash change history manager will not handle events
+                        *
+                        * @method disable
+                        * @static
+                        * @since 2.4
+                        * @member ns.history.manager
+                        */
+                       manager.disable = function () {
+                               document.removeEventListener(DOC_EVENT_VCLICK, onLinkAction, false);
+                               window.removeEventListener(WINDOW_EVENT_POPSTATE, onPopState, false);
+                               window.removeEventListener(WINDOW_EVENT_HASHCHANGE, onHashChange, false);
+                               history.disableVolatileMode();
+                               this.enabled = false;
+                               eventUtils.trigger(document, EVENT_DISABLED, this);
+                       };
+
+                       ns.history.manager = manager;
+                       }(window, window.document));
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * #Namespace For Core Widgets
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @class ns.widget.core
+ */
+(function (document, ns) {
+       "use strict";
+                               ns.widget.core = ns.widget.core || {};
+                       }(window.document, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * # PageContainer Widget
+ * PageContainer is a widget, which is supposed to have multiple child pages but display only one at a time.
+ *
+ * @class ns.widget.core.PageContainer
+ * @extends ns.widget.BaseWidget
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Krzysztof Głodowski <k.glodowski@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               util = ns.util,
+                               DOM = util.DOM,
+                               engine = ns.engine,
+                               classes = {
+                                       pageContainer: "ui-page-container",
+                                       uiViewportTransitioning: "ui-viewport-transitioning",
+                                       out: "out",
+                                       in: "in",
+                                       reverse: "reverse",
+                                       uiPreIn: "ui-pre-in",
+                                       uiBuild: "ui-page-build"
+                               },
+                               PageContainer = function () {
+                                       /**
+                                        * Active page.
+                                        * @property {ns.widget.core.Page} [activePage]
+                                        * @member ns.widget.core.PageContainer
+                                        */
+                                       this.activePage = null;
+                                       this.inTransition = false;
+                               },
+                               EventType = {
+                                       /**
+                                        * Triggered before the changePage() request
+                                        * has started loading the page into the DOM.
+                                        * @event pagebeforechange
+                                        * @member ns.widget.core.PageContainer
+                                        */
+                                       PAGE_BEFORE_CHANGE: "pagebeforechange",
+                                       /**
+                                        * Triggered after the changePage() request
+                                        * has finished loading the page into the DOM and
+                                        * all page transition animations have completed.
+                                        * @event pagechange
+                                        * @member ns.widget.core.PageContainer
+                                        */
+                                       PAGE_CHANGE: "pagechange",
+                                       PAGE_REMOVE: "pageremove"
+                               },
+                               animationend = "animationend",
+                               webkitAnimationEnd = "webkitAnimationEnd",
+                               mozAnimationEnd = "mozAnimationEnd",
+                               msAnimationEnd = "msAnimationEnd",
+                               oAnimationEnd = "oAnimationEnd",
+                               animationEndNames = [
+                                       animationend,
+                                       webkitAnimationEnd,
+                                       mozAnimationEnd,
+                                       msAnimationEnd,
+                                       oAnimationEnd
+                               ],
+                               prototype = new BaseWidget();
+                       //When resolved deferred function is responsible for triggering events related to page change as well as
+                       //destroying unused widgets from last page and/or removing last page
+
+                       function deferredFunction(fromPageWidget, toPageWidget, self, options) {
+                               if (fromPageWidget) {
+                                       fromPageWidget.onHide();
+                                       self._removeExternalPage(fromPageWidget, options);
+                               }
+                               toPageWidget.onShow();
+                                                               self.trigger(EventType.PAGE_CHANGE);
+                                                       }
+
+                       /**
+                        * Dictionary for PageContainer related event types.
+                        * @property {Object} events
+                        * @property {string} [events.PAGE_CHANGE="pagechange"]
+                        * @member ns.router.route.popup
+                        * @static
+                        */
+                       PageContainer.events = EventType;
+
+                       /**
+                        * Dictionary for PageContainer related css class names
+                        * @property {Object} classes
+                        * @member ns.widget.core.Page
+                        * @static
+                        * @readonly
+                        */
+                       PageContainer.classes = classes;
+
+                       /**
+                        * Build widget structure
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.core.PageContainer
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               element.classList.add(classes.pageContainer);
+                               return element;
+                       };
+
+                       /**
+                        * This method changes active page to specified element.
+                        * @method change
+                        * @param {HTMLElement} toPageElement The element to set
+                        * @param {Object} [options] Additional options for the transition
+                        * @param {string} [options.transition=none] Specifies the type of transition
+                        * @param {boolean} [options.reverse=false] Specifies the direction of transition
+                        * @member ns.widget.core.PageContainer
+                        */
+                       prototype.change = function (toPageElement, options) {
+                               var self = this,
+                                       fromPageWidget = self.getActivePage(),
+                                       toPageWidget,
+                                       calculatedOptions = options || {};
+
+                               // store options to detect that option was changed before process finish
+                               self._options = calculatedOptions;
+
+                               calculatedOptions.widget = calculatedOptions.widget || "Page";
+
+                               // The change should be made only if no active page exists
+                               // or active page is changed to another one.
+                               if (!fromPageWidget || (fromPageWidget.element !== toPageElement)) {
+                                       if (toPageElement.parentNode !== self.element) {
+                                               toPageElement = self._include(toPageElement);
+                                       }
+
+                                       self.trigger(EventType.PAGE_BEFORE_CHANGE);
+
+                                       toPageElement.classList.add(classes.uiBuild);
+
+                                       delete options.url;
+                                       toPageWidget = engine.instanceWidget(toPageElement, calculatedOptions.widget, options);
+
+                                       // set sizes of page for correct display
+                                       toPageWidget.layout();
+
+                                       if (toPageWidget.option("autoBuildWidgets") || toPageElement.querySelector(".ui-i3d") || toPageElement.querySelector(".ui-coverflow")) {
+                                               engine.createWidgets(toPageElement, options);
+                                       }
+
+                                       if (fromPageWidget) {
+                                               fromPageWidget.onBeforeHide();
+                                       }
+                                       toPageWidget.onBeforeShow();
+
+                                       toPageElement.classList.remove(classes.uiBuild);
+
+                                       // if options is different that this mean that another change page was called and we need stop
+                                       // previous change page
+                                       if (calculatedOptions === self._options) {
+                                               calculatedOptions.deferred = {
+                                                       resolve: deferredFunction
+                                               };
+                                               self._transition(toPageWidget, fromPageWidget, calculatedOptions);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * This method performs transition between the old and a new page.
+                        * @method _transition
+                        * @param {ns.widget.core.Page} toPageWidget The new page
+                        * @param {ns.widget.core.Page} fromPageWidget The page to be replaced
+                        * @param {Object} [options] Additional options for the transition
+                        * @param {string} [options.transition=none] The type of transition
+                        * @param {boolean} [options.reverse=false] Specifies transition direction
+                        * @param {Object} [options.deferred] Deferred object
+                        * @member ns.widget.core.PageContainer
+                        * @protected
+                        */
+                       prototype._transition = function (toPageWidget, fromPageWidget, options) {
+                               var self = this,
+                                       element = self.element,
+                                       elementClassList = element.classList,
+                                       transition = !fromPageWidget || !options.transition ? "none" : options.transition,
+                                       deferred = options.deferred,
+                                       clearClasses = [classes.in, classes.out, classes.uiPreIn, transition],
+                                       oldDeferredResolve,
+                                       oneEvent;
+
+                               if (options.reverse) {
+                                       clearClasses.push(classes.reverse);
+                               }
+                               self.inTransition = true;
+                               elementClassList.add(classes.uiViewportTransitioning);
+                               oldDeferredResolve = deferred.resolve;
+                               deferred.resolve = function () {
+                                       var fromPageWidgetClassList = fromPageWidget && fromPageWidget.element.classList,
+                                               toPageWidgetClassList = toPageWidget.element.classList;
+
+                                       self._setActivePage(toPageWidget);
+                                       self._clearTransitionClasses(clearClasses, fromPageWidgetClassList, toPageWidgetClassList);
+                                       oldDeferredResolve(fromPageWidget, toPageWidget, self, options);
+                               };
+
+                               if (transition !== "none") {
+                                       oneEvent = function () {
+                                               toPageWidget.off(
+                                                       animationEndNames,
+                                                       oneEvent,
+                                                       false
+                                               );
+                                               deferred.resolve();
+                                       };
+                                       toPageWidget.on(
+                                               animationEndNames,
+                                               oneEvent,
+                                               false
+                                       );
+                                       self._appendTransitionClasses(fromPageWidget, toPageWidget, transition, options.reverse);
+                               } else {
+                                       window.setTimeout(deferred.resolve, 0);
+                               }
+                       };
+
+                       /**
+                        * This method adds proper transition classes to specified page widgets.
+                        * @param {ns.widget.core.Page} fromPageWidget Page widget from which transition will occur
+                        * @param {ns.widget.core.Page} toPageWidget Destination page widget for transition
+                        * @param {string} transition Specifies the type of transition
+                        * @param {boolean} reverse Specifies the direction of transition
+                        * @member ns.widget.core.PageContainer
+                        * @protected
+                        */
+                       prototype._appendTransitionClasses = function (fromPageWidget, toPageWidget, transition, reverse) {
+                               var classList;
+
+                               if (fromPageWidget) {
+                                       classList = fromPageWidget.element.classList;
+                                       classList.add(transition, classes.out);
+                                       if (reverse) {
+                                               classList.add(classes.reverse);
+                                       }
+                               }
+
+                               classList = toPageWidget.element.classList;
+                               classList.add(transition, classes.in, classes.uiPreIn);
+                               if (reverse) {
+                                       classList.add(classes.reverse);
+                               }
+                       };
+
+                       /**
+                        * This method removes transition classes from classLists of page widget elements.
+                        * @param {Object} clearClasses An array containing classes to be removed
+                        * @param {Object} fromPageWidgetClassList classList object from source page element
+                        * @param {Object} toPageWidgetClassList classList object from destination page element
+                        * @member ns.widget.core.PageContainer
+                        * @protected
+                        */
+                       prototype._clearTransitionClasses = function (clearClasses, fromPageWidgetClassList, toPageWidgetClassList) {
+                               var self = this,
+                                       element = self.element,
+                                       elementClassList = element.classList;
+
+                               elementClassList.remove(classes.uiViewportTransitioning);
+                               self.inTransition = false;
+                               clearClasses.forEach(function (className) {
+                                       toPageWidgetClassList.remove(className);
+                               });
+                               if (fromPageWidgetClassList) {
+                                       clearClasses.forEach(function (className) {
+                                               fromPageWidgetClassList.remove(className);
+                                       });
+                               }
+                       };
+
+                       /**
+                        * This method adds an element as a page.
+                        * @method _include
+                        * @param {HTMLElement} page an element to add
+                        * @return {HTMLElement}
+                        * @member ns.widget.core.PageContainer
+                        * @protected
+                        */
+                       prototype._include = function (page) {
+                               var element = this.element;
+
+                               if (!page.parentNode || page.ownerDocument !== document) {
+                                       page = util.importEvaluateAndAppendElement(page, element);
+                               }
+                               return page;
+                       };
+
+                       /**
+                        * This method sets currently active page.
+                        * @method _setActivePage
+                        * @param {ns.widget.core.Page} page a widget to set as the active page
+                        * @member ns.widget.core.PageContainer
+                        * @protected
+                        */
+                       prototype._setActivePage = function (page) {
+                               var self = this;
+
+                               if (self.activePage) {
+                                       self.activePage.setActive(false);
+                               }
+
+                               self.activePage = page;
+
+                               page.setActive(true);
+                       };
+
+                       /**
+                        * This method returns active page widget.
+                        * @method getActivePage
+                        * @member ns.widget.core.PageContainer
+                        * @return {ns.widget.core.Page} Currently active page
+                        */
+                       prototype.getActivePage = function () {
+                               return this.activePage;
+                       };
+
+                       /**
+                        * This method removes page element from the given widget and destroys it.
+                        * @method _removeExternalPage
+                        * @param {ns.widget.core.Page} fromPageWidget the widget to destroy
+                        * @param {Object} [options] transition options
+                        * @param {boolean} [options.reverse=false] specifies transition direction
+                        * @member ns.widget.core.PageContainer
+                        * @protected
+                        */
+                       prototype._removeExternalPage = function (fromPageWidget, options) {
+                               var fromPageElement = fromPageWidget.element;
+
+                               if (options && options.reverse && DOM.hasNSData(fromPageElement, "external") &&
+                                       fromPageElement.parentNode) {
+                                       fromPageWidget.destroy();
+                                       fromPageElement.parentNode.removeChild(fromPageElement);
+                                       this.trigger(EventType.PAGE_REMOVE);
+                               }
+                       };
+
+                       PageContainer.prototype = prototype;
+
+                       // definition
+                       ns.widget.core.PageContainer = PageContainer;
+
+                       engine.defineWidget(
+                               "pagecontainer",
+                               "",
+                               ["change", "getActivePage"],
+                               PageContainer,
+                               "core"
+                       );
+                       }(window.document, ns));
+
+/*global window, define, ns, HTMLElement, Node */
+/*
+ * Copyright (c) 2010 - 2014 Samsung Electronics Co., Ltd.
+ * License : MIT License V2
+ */
+
+(function (document, ns) {
+       "use strict";
+                               var engine = ns.engine,
+                               DOM = ns.util.DOM,
+                               object = ns.util.object,
+                               utilArray = ns.util.array,
+                               eventUtils = ns.event,
+                               selectorUtils = ns.util.selectors,
+                               atan2 = Math.atan2,
+                               abs = Math.abs,
+                               PI = Math.PI,
+                               sqrt = Math.sqrt,
+                               slice = [].slice,
+                               // focus configuration
+                               SIDE_DISTANCE_LIMIT = 200,
+                               prototype = {
+                                       _supportKeyboard: false
+                               },
+                               selectorsString = "",
+                               BaseKeyboardSupport = function () {
+                                       var self = this,
+                                               options = self.options || {};
+
+                                       object.merge(self, prototype);
+                                       // new options requires by keyboard support
+
+                                       object.merge(options, {
+                                               // "top"|"right"|"bottom"|"left"
+                                               focusDirection: null,
+                                               focusContext: null,
+                                               focusContainerContext: false,
+                                               focusUp: null,
+                                               focusDown: null,
+                                               focusLeft: null,
+                                               focusRight: null,
+                                               focusLock: false
+                                       });
+
+                                       // widget has keyboard support
+                                       self.isKeyboardSupport = true;
+
+                                       // prepare selector
+                                       if (selectorsString === "") {
+                                               prepareSelector();
+                                       }
+                                       self._onKeyupHandler = null;
+                                       self._onClickHandler = null;
+                                       self._onHWKeyHandler = null;
+                                       // time of keydown event
+                                       self.keydownEventTimeStart = null; // [ms]
+                                       // flag for keydown event
+                                       self.keydownEventRepeated = false;
+                               },
+                               classes = {
+                                       focusDisabled: "ui-focus-disabled",
+                                       focusEnabled: "ui-focus-enabled",
+                                       focusDisabledByWidget: "ui-focus-disabled-by-widget",
+                                       focus: "ui-focus"
+                               },
+                               KEY_CODES = {
+                                       left: 37,
+                                       up: 38,
+                                       right: 39,
+                                       down: 40,
+                                       enter: 13,
+                                       tab: 9,
+                                       escape: 27
+                               },
+                               activeElement = null,
+                               EVENT_POSITION = {
+                                       up: "up",
+                                       down: "down",
+                                       left: "left",
+                                       right: "right"
+                               },
+                               selectorSuffix = ":not(." + classes.focusDisabled + ")" +
+                                                               ":not(." + ns.widget.BaseWidget.classes.disable + ")",
+                               // define standard focus selectors
+                               // includeDisabled: false - disabled element will be not focusable
+                               // includeDisabled: true - disabled element will be focusable
+                               // count - number of defined selectors
+                               selectors = [{
+                                       value: "a",
+                                       includeDisabled: false,
+                                       count: 1
+                               }, {
+                                       value: "." + classes.focusEnabled,
+                                       includeDisabled: false,
+                                       count: 1
+                               }, {
+                                       value: "[tabindex]",
+                                       includeDisabled: false,
+                                       count: 1
+                               }, {
+                                       value: "[data-focus-lock=true]",
+                                       includeDisabled: false,
+                                       count: 1
+                               }
+                               ],
+                               /**
+                               * @property {Array} Array containing number of registrations of each selector
+                               * @member ns.widget.tv.BaseKeyboardSupport
+                               * @private
+                               */
+                               currentKeyboardWidget,
+                               lastMoveDirection,
+                               previousKeyboardWidgets = [],
+                               ANIMATION_MIN_TIME = 50;
+
+                       BaseKeyboardSupport.KEY_CODES = KEY_CODES;
+                       BaseKeyboardSupport.classes = classes;
+                       /**
+                        * Get focused element.
+                        * @method getFocusedLink
+                        * @return {HTMLElement}
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function getFocusedLink() {
+                               return document.querySelector(":focus") || document.activeElement;
+                       }
+
+                       /**
+                        * Test if the key code is a cursor key code
+                        * @method isCursorKey
+                        * @param {number} key
+                        * @return {boolean}
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function isCursorKey(key) {
+                               return key === KEY_CODES.left ||
+                                       key === KEY_CODES.right ||
+                                       key === KEY_CODES.up ||
+                                       key === KEY_CODES.down ||
+                                       key === KEY_CODES.enter ||
+                                       key === KEY_CODES.escape;
+                       }
+
+                       /**
+                        * Finds all visible links.
+                        * @method getFocusableElements
+                        * @param {HTMLElement} widgetElement
+                        * @param {boolean} visibleOnly select only visible elements
+                        * @return {Array}
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function getFocusableElements(widgetElement, visibleOnly) {
+                               var focusableElements = [];
+
+                               if (!widgetElement) {
+                                       return [];
+                               }
+
+                               focusableElements = slice.call(widgetElement.querySelectorAll(selectorsString));
+
+                               if (!visibleOnly) {
+                                       return focusableElements;
+                               }
+                               return focusableElements.filter(function (element) {
+                                       return element.offsetWidth && window.getComputedStyle(element).visibility !== "hidden";
+                               });
+                       }
+
+                       prototype.preventFocusOnElement = function (element) {
+                               element.classList.add(classes.focusDisabled);
+                       }
+
+                       /**
+                        * Method makes focusable element as disabled for focus selection
+                        * @method disableFocusableElements
+                        * @param {HTMLElement} element parent element for disabled elements
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype.disableFocusableElements = function (element) {
+                               this.getFocusableElements(element).forEach(function (focusableElement) {
+                                       focusableElement.classList.add(classes.focusDisabled);
+                                       // this class describe that focus on element was disabled by widget, not developer
+                                       focusableElement.classList.add(classes.focusDisabledByWidget);
+                               });
+                       }
+
+                       /**
+                        * Method enables previously disabled the focusable element
+                        * @method enableDisabledFocusableElements
+                        * @param {HTMLElement} element parent element for disabled elements
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype.enableDisabledFocusableElements = function (element) {
+                               var disabledFocusableElements;
+
+                               if (element) {
+                                       disabledFocusableElements = element.querySelectorAll("." + classes.focusDisabledByWidget);
+
+                                       slice.call(disabledFocusableElements).forEach(function (focusableElement) {
+                                               focusableElement.classList.remove(classes.focusDisabled);
+                                               // this class describe that focus on element was disabled by widget, not developer
+                                               focusableElement.classList.remove(classes.focusDisabledByWidget);
+                                       });
+                               }
+                       }
+
+                       /**
+                        * Extracts element from offsetObject.
+                        * @method mapToElement
+                        * @param {Object} linkOffset
+                        * @param {HTMLElement} linkOffset.element
+                        * @return {HTMLElement}
+                        * @private
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function mapToElement(linkOffset) {
+                               return linkOffset.element;
+                       }
+
+                       /**
+                        * Set string with selector
+                        * @method prepareSelector
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function prepareSelector() {
+                               var length = selectors.length;
+
+                               selectorsString = "";
+                               utilArray.forEach(selectors, function (object, index) {
+                                       selectorsString += object.value;
+                                       if (!object.includeDisabled) {
+                                               selectorsString += selectorSuffix;
+                                       }
+                                       if (index < length - 1) {
+                                               selectorsString += ",";
+                                       }
+                               });
+                       }
+
+                       prototype.getActiveSelector = function () {
+                               return selectorsString;
+                       };
+
+                       BaseKeyboardSupport.copyFocusAttributes = function (widgetInstance, wrapper) {
+                               var options = widgetInstance.options;
+
+                               DOM.setNSDataAttributes(wrapper, {
+                                       focusDirection: options.focusDirection,
+                                       focusContext: options.focusContext,
+                                       focusContainerContext: options.focusContainerContext,
+                                       focusUp: options.focusUp,
+                                       focusDown: options.focusDown,
+                                       focusLeft: options.focusLeft,
+                                       focusRight: options.focusRight
+                               }, true);
+                       };
+
+                       function getDistanceByCenter(contextRect, referenceElement) {
+                               var referenceRect = (referenceElement instanceof HTMLElement) ?
+                                               referenceElement.getBoundingClientRect() :
+                                               referenceElement,
+                                       contextCenter = {
+                                               x: contextRect.width / 2 + contextRect.left,
+                                               y: contextRect.height / 2 + contextRect.top
+                                       },
+                                       referenceCenter = {
+                                               x: referenceRect.width / 2 + referenceRect.left,
+                                               y: referenceRect.height / 2 + referenceRect.top
+                                       },
+                                       dy = contextCenter.y - referenceCenter.y,
+                                       dx = contextCenter.x - referenceCenter.x;
+
+                               return Math.sqrt(dy * dy + dx * dx);
+                       }
+
+                       function isInLine(contextRect, referenceElement, direction) {
+                               var a1,
+                                       a2,
+                                       b1,
+                                       b2,
+                                       result = false,
+                                       referenceRect = (referenceElement instanceof HTMLElement) ?
+                                               referenceElement.getBoundingClientRect() :
+                                               referenceElement;
+
+                               if (direction === "down" || direction === "up") {
+                                       a1 = referenceRect.left;
+                                       a2 = referenceRect.left + referenceRect.width;
+                                       b1 = contextRect.left;
+                                       b2 = contextRect.left + contextRect.width;
+                               } else if (direction === "left" || direction === "right") {
+                                       a1 = referenceRect.top;
+                                       a2 = referenceRect.top + referenceRect.height;
+                                       b1 = contextRect.top;
+                                       b2 = contextRect.top + contextRect.height;
+                               } else {
+                                       return result;
+                               }
+
+                               result = ((a1 > b1) && (a1 < b2)) || // at the left
+                                       ((a2 > b1) && (a2 < b2)) || // at the right
+                                       // above conditions are applicable also
+                                       // if the context contains the reference element
+                                       ((a1 <= b1) && (a2 >= b2)); // content is inside reference element
+
+                               return result;
+                       }
+
+                       /**
+                        * return angle between two elements
+                        * @method getRelativeAngle
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        * @param {Object} contextRect
+                        * @param {HTMLElement} referenceElement
+                        * @return {number}
+                        */
+                       function getRelativeAngle(contextRect, referenceElement) {
+                               var referenceRect = (referenceElement instanceof HTMLElement) ?
+                                               referenceElement.getBoundingClientRect() :
+                                               referenceElement,
+                                       contextCenter = {
+                                               x: contextRect.width / 2 + contextRect.left,
+                                               y: contextRect.height / 2 + contextRect.top
+                                       },
+                                       referenceCenter = {
+                                               x: referenceRect.width / 2 + referenceRect.left,
+                                               y: referenceRect.height / 2 + referenceRect.top
+                                       },
+                                       dy = contextCenter.y - referenceCenter.y,
+                                       dx = contextCenter.x - referenceCenter.x,
+                                       angle = atan2(-dy, dx) * 180 / PI;
+
+                               // determining the angle between the centers of two rectangles
+                               return angle;
+                       }
+
+                       /**
+                        * return direction from angle
+                        * @method getDirectionFromAngle
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        * @param {number} angle
+                        * @param {number} tolerance [0.0 .. 45.0]
+                        * @return {string}
+                        */
+                       function getDirectionFromAngle(angle, tolerance) {
+                               tolerance = tolerance || 0.0;
+
+                               if ((abs(angle - 180) < tolerance) || (abs(angle + 180) < tolerance)) {
+                                       return EVENT_POSITION.left;
+                               } else if (abs(angle - 90) < tolerance) {
+                                       return EVENT_POSITION.up;
+                               } else if (abs(angle) < tolerance) {
+                                       return EVENT_POSITION.right;
+                               } else if (abs(angle + 90) < tolerance) {
+                                       return EVENT_POSITION.down;
+                               }
+                               return "";
+                       }
+
+                       /**
+                        * Compares two numbers and return order for sorting functions
+                        * @method getOrder
+                        * @param {number} number1
+                        * @param {number} number2
+                        * @return {number}
+                        * @private
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function getOrder(number1, number2) {
+                               if (number1 === number2) {
+                                       return 0;
+                               }
+                               if (number1 < number2) {
+                                       return -1;
+                               }
+                               return 1;
+                       }
+
+                       /**
+                        * return direction from origin rect to element rect in movement direction
+                        * @param {DOMRect} originRect
+                        * @param {DOMRect} elementRect
+                        * @param {"top"|"right"|"bottom"|"left"} movementDirection
+                        * @return {"top"|"right"|"bottom"|"left"}
+                        * @static
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function getDirection(originRect, elementRect, movementDirection) {
+                               if (movementDirection === EVENT_POSITION.right &&
+                                       parseInt(originRect.right) <= parseInt(elementRect.left)) {
+                                       return movementDirection;
+                               }
+
+                               if (movementDirection === EVENT_POSITION.left &&
+                                       parseInt(elementRect.right) <= parseInt(originRect.left)) {
+                                       return movementDirection;
+                               }
+
+                               if (movementDirection === EVENT_POSITION.down &&
+                                       parseInt(originRect.bottom) <= parseInt(elementRect.top)) {
+                                       return movementDirection;
+                               }
+
+                               if (movementDirection === EVENT_POSITION.up &&
+                                       parseInt(originRect.top) >= parseInt(elementRect.bottom)) {
+                                       return movementDirection;
+                               }
+
+                               if (elementRect) {
+                                       // tolerance 5 degrees
+                                       return getDirectionFromAngle(getRelativeAngle(elementRect, originRect), 5.0);
+                               }
+
+                               return "";
+                       }
+
+                       /**
+                        * Gets distance between two ClientRects
+                        * @param {DOMRect} aElementRect
+                        * @param {DOMRect} bElementRect
+                        * @return {number}
+                        * @static
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function getDistanceLeftTopCorner(aElementRect, bElementRect) {
+                               var x = aElementRect.left - bElementRect.left,
+                                       y = aElementRect.top - bElementRect.top;
+
+                               return sqrt(x * x + y * y) | 0;
+                       }
+
+                       /**
+                        * Gets distance between two ClientRects by sides
+                        * @param {DOMRect} elementRect
+                        * @param {DOMRect} referenceElementRect
+                        * @return {Object}
+                        * @static
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function getDistanceBySides(elementRect, referenceElementRect) {
+                               /*
+                                * This values represents distance from reference element to element
+                                * at indicated direction:
+                                *
+                                * example:
+                                * =======
+                                *
+                                *     _ _ _ _
+                                *     ^      [element]
+                                *     |           ^
+                                *     | bottom    | top
+                                *     |           |
+                                *     |_ [reference element]
+                                *
+                                *
+                                *         _ _ _ _ _ _ _ _ _ _ _ _ [element]
+                                *           ^                     |       |
+                                *           | top                 |
+                                *           |              right  |       |
+                                *     [reference element] ------->|
+                                *     |                                   |
+                                *     |          left
+                                *     |---------------------------------->|
+                                *
+                                * example:
+                                * =======
+                                *
+                                *            _ _ _ _ _ _ _ _ _[reference element]
+                                *             |               |
+                                *             | bottom        |
+                                *             |               |
+                                *             /         left  |
+                                *         [element]<----------|
+                                *
+                                */
+                               var result = {
+                                       top: referenceElementRect.top - (elementRect.top + elementRect.height) + 0,
+                                       bottom: elementRect.top - referenceElementRect.top - referenceElementRect.height,
+                                       right: elementRect.left - referenceElementRect.left - referenceElementRect.width,
+                                       left: referenceElementRect.left - (elementRect.left + elementRect.width)
+                               };
+
+                               /*
+                                * example:
+                                * =======
+                                *
+                                *     [++++++++ element ++++++++]
+                                *     |                         |
+                                *     |                   left  |
+                                *     |               |-------->|
+                                *     |
+                                *     |<--leftRest----[reference element]
+                                *
+                                *    Focus on left should takes account also element
+                                *    which "leftRest" value is positive
+                                *
+                                */
+                               result.leftRest = result.left + elementRect.width;
+                               result.rightRest = result.right + elementRect.width;
+                               result.topRest = result.top + elementRect.height;
+                               result.bottomRest = result.bottom + elementRect.height;
+                               return result;
+                       }
+
+                       /**
+                        * Sorting callback, sorts by distance
+                        * @param {Object} a
+                        * @param {Object} b
+                        * @return {number}
+                        * @static
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function sortByDistanceByCenter(a, b) {
+                               return (a.distanceByCenter === b.distanceByCenter) ? 0 :
+                                       (a.distanceByCenter < b.distanceByCenter) ? -1 : 1;
+                       }
+
+                       function sortByDistance(a, b) {
+                               return (a.distanceByDirection.distance === b.distanceByDirection.distance) ?
+                                       sortByDistanceByCenter(a, b) :
+                                               (a.distanceByDirection.distance < b.distanceByDirection.distance) ? -1 : 1;
+                       }
+
+                       function sortByInSideDistanceLimit(a, b) {
+                               // sort by inSideDistanceLimit
+                               return (a.inSideDistanceLimit && b.inSideDistanceLimit) ? sortByDistance(a, b) :
+                                               (!a.inSideDistanceLimit && !b.inSideDistanceLimit) ? sortByDistanceByCenter(a, b) :
+                                                       (a.inSideDistanceLimit && !b.inSideDistanceLimit) ? -1 : 1;
+                       }
+
+                       /**
+                        * Sorting callback, sorts by distance
+                        * @param {Object} a
+                        * @param {Object} b
+                        * @return {number}
+                        * @static
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function sortFocusableElements(a, b) {
+                               /**
+                                * Sort order
+                                * - inLine
+                                * - inSideDistanceLimit
+                                * ---  distanceByDirection.distance
+                                * ---  distanceByCenter
+                                */
+                               // sort by inline
+                               return (a.inLine && b.inLine || !a.inLine && !b.inLine) ? sortByInSideDistanceLimit(a, b) :
+                                       (a.inLine && !b.inLine) ? -1 : 1;
+                       }
+
+                       function getDistanceByDirection(distances, direction) {
+                               switch (direction) {
+                                       case "left": return {
+                                               distance: distances.left,
+                                               distanceRest: distances.leftRest
+                                       };
+                                       case "right": return {
+                                               distance: distances.right,
+                                               distanceRest: distances.rightRest
+                                       };
+                                       case "up": return {
+                                               distance: distances.top,
+                                               distanceRest: distances.topRest
+                                       };
+                                       case "down": return {
+                                               distance: distances.bottom,
+                                               distanceRest: distances.bottomRest
+                                       };
+                               }
+                               return null;
+                       }
+
+                       /**
+                        * Calculates neighborhood links.
+                        * @method getNeighborhoodLinks
+                        * @param {HTMLElement} element Base element fo find links
+                        * @param {HTMLElement} [currentElement] current focused element
+                        * @param {Object} [options] Options for function
+                        * @param {Function} [options._filterNeighbors] Function used to filtering focusable elements
+                        * @param {"top"|"right"|"bottom"|"left"} [options.direction] direction
+                        * @return {Object}
+                        * @private
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function getNeighborhoodLinks(element, currentElement, options) {
+                               var links,
+                                       direction = options.direction,
+                                       currentLink = currentElement || getFocusedLink(),
+                                       customFocus,
+                                       linksOffset = [],
+                                       elementRect = currentLink.getBoundingClientRect(),
+                                       focusableElements = [],
+                                       focusableElement = null,
+                                       focusableElementRect = null,
+                                       distances = {},
+                                       distanceByDirection,
+                                       i = 0,
+                                       l = 0;
+
+                               customFocus = (currentLink && fetchCustomFocusElement(currentLink, direction, element));
+                               if (customFocus) {
+                                       return [customFocus];
+                               }
+
+                               links = getFocusableElements(element, true);
+
+                               if (currentLink && currentLink !== document.body) {
+
+                                       for (i = 0, l = links.length; i < l; ++i) {
+                                               focusableElement = links[i];
+                                               focusableElementRect = focusableElement.getBoundingClientRect();
+                                               distances = getDistanceBySides(focusableElementRect, elementRect);
+                                               distanceByDirection = getDistanceByDirection(distances, direction);
+                                               focusableElements.push({
+                                                       element: focusableElement,
+                                                       angle: getRelativeAngle(focusableElementRect, elementRect),
+                                                       direction: getDirection(elementRect, focusableElementRect, direction),
+                                                       distance: getDistanceLeftTopCorner(elementRect, focusableElementRect),
+                                                       distanceByDirection: distanceByDirection,
+                                                       distanceByCenter: getDistanceByCenter(focusableElementRect, elementRect),
+                                                       inLine: isInLine(focusableElementRect, elementRect, direction),
+                                                       inSideDistanceLimit: distanceByDirection.distance >= 0 &&
+                                                               distanceByDirection.distance < SIDE_DISTANCE_LIMIT
+                                               });
+                                       }
+
+                                       // remove from list an elements behind move direction
+                                       focusableElements = focusableElements.filter(function (focusableElement) {
+                                               return focusableElement.distanceByDirection.distanceRest > 0;
+                                       });
+
+                                       focusableElements = focusableElements.filter(function (focusableElement) {
+                                               // corner cases, when element positions overlap
+                                               if (focusableElement.distance === 0) {
+                                                       if (direction === EVENT_POSITION.down) {
+                                                               return !!(currentLink.compareDocumentPosition(typeof focusableElement === element ? focusableElement : focusableElement.element) &
+                                                                               Node.DOCUMENT_POSITION_CONTAINED_BY);
+                                                       } else if (direction === EVENT_POSITION.up) {
+                                                               return !!(currentLink.compareDocumentPosition(typeof focusableElement === element ? focusableElement : focusableElement.element) &
+                                                                               Node.DOCUMENT_POSITION_PRECEDING);
+                                                       }
+                                                       return false;
+                                               }
+                                               return focusableElement.direction === direction;
+                                       });
+
+                                       // This sort method is major action to make order in the moving of focus
+                                       focusableElements = focusableElements.sort(sortFocusableElements).map(mapToElement);
+
+                                       // return result;
+                                       return focusableElements;
+                               }
+                               linksOffset = utilArray.map(links, function (link) {
+                                       var linkOffset = link.getBoundingClientRect();
+
+                                       return {
+                                               offset: linkOffset,
+                                               element: link,
+                                               width: link.offsetWidth,
+                                               height: link.offsetHeight
+                                       };
+                               });
+                               return utilArray.map(linksOffset.sort(function (linkOffset1, linkOffset2) {
+                                       // every sort function *must* return 0 on equal elements to prevent
+                                       // changing of input order
+                                       if (linkOffset1.offset.top === linkOffset2.offset.top) {
+                                               return getOrder(linkOffset1.offset.left, linkOffset2.offset.left);
+                                       }
+                                       return getOrder(linkOffset1.offset.top, linkOffset2.offset.top);
+                               }), mapToElement);
+                       }
+
+                       /**
+                        * This method triggers 'blur' event on widget or html element
+                        * @method blurOnActiveElement
+                        * @param {Object} options
+                        * @static
+                        * @memberof ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function blurOnActiveElement(options) {
+                               var currentElement,
+                                       preventDefault,
+                                       currentWidget
+
+                               options = options || {};
+                               currentElement = options.current || activeElement || getFocusedLink();
+
+                               // and blur the previous one
+                               if (currentElement) {
+                                       currentWidget = engine.getBinding(currentElement);
+                                       if (currentWidget) {
+                                               currentWidget.blur(options);
+                                       } else {
+                                               options.element = currentElement;
+                                               preventDefault = !eventUtils.trigger(currentElement, "taublur", options);
+                                               if (!preventDefault) {
+                                                       currentElement.classList.remove(classes.focus);
+                                                       currentElement.blur();
+                                               }
+                                       }
+                                       // set active element to null;
+                                       activeElement = null;
+                               }
+                       }
+
+                       /**
+                        * Method trying to focus on widget or on HTMLElement and blur on active element or widget.
+                        * @method focusOnElement
+                        * @param {?ns.widget.BaseWidget} self
+                        * @param {HTMLElement} element
+                        * @param {Object} [options]
+                        * @return  {boolean} Return true if focus finished success
+                        * @static
+                        * @private
+                        * @memberof ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function focusOnElement(self, element, options) {
+                               var setFocus,
+                                       currentElement = options.current || activeElement || getFocusedLink(),
+                                       nextElementWidget,
+                                       lockedElement = element && selectorUtils.getClosestBySelectorNS(element.parentNode, "focus-lock=true"),
+                                       lockedWidget = (lockedElement && engine.getBinding(lockedElement)) || null,
+                                       preventDefault;
+
+                               if (lockedWidget && lockedWidget !== currentKeyboardWidget) {
+                                       return false;
+                               }
+
+                               options = options || {};
+                               nextElementWidget = engine.getBinding(element);
+
+                               if (nextElementWidget) {
+                                       // we call function focus if the element is connected with widget
+                                       options.previousElement = currentElement;
+                                       setFocus = nextElementWidget.focus(options);
+                                       blurOnActiveElement(options);
+                               } else {
+                                       if (element !== currentElement) {
+                                               options.previousElement = currentElement;
+                                               // or only set focus on element
+                                               // for mouse is possible to focus on null element
+                                               if (element) {
+                                                       options.element = element;
+                                                       preventDefault = !eventUtils.trigger(element, "taufocus", options);
+                                                       if (!preventDefault) {
+                                                               element.classList.add(classes.focus);
+                                                               element.focus();
+                                                       }
+                                               }
+                                               // and blur the previous one
+                                               blurOnActiveElement(options);
+                                               setFocus = true;
+                                       }
+                               }
+
+                               // The currently focused element becomes active
+                               // We need this for proper focus locking
+                               activeElement = element;
+
+                               if (self) {
+                                       if (self._openActiveElement) {
+                                               self._openActiveElement(element);
+                                       }
+                               }
+
+                               return setFocus;
+                       }
+
+                       /**
+                        * @method blurOnActiveElement
+                        */
+                       prototype.blurOnActiveElement = blurOnActiveElement;
+
+                       /**
+                        * Tries to fetch custom focus attributes and move to the specified element
+                        * @param {HTMLElement} element
+                        * @param {string} direction
+                        * @param {HTMLElement} [queryContext=undefined]
+                        * @method fetchCustomFocusElement
+                        * @private
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function fetchCustomFocusElement(element, direction, queryContext) {
+                               var selector = element.getAttribute("data-focus-" + direction),
+                                       eventData = {
+                                               selector: selector,
+                                               direction: direction,
+                                               currentElement: element,
+                                               nextElement: null
+                                       },
+                                       useQueryContext = element.getAttribute("data-focus-container-context") === "true",
+                                       customQueryContextSelector = element.getAttribute("data-focus-context");
+
+                               if (selector) {
+                                       // notify observers about custom query for focus element
+                                       // observers can catch the event and choose their own elements
+                                       // this supports customSelectors like ::virtualgrid-* which
+                                       // is implemented in virtualgrid, if the event was not consumed
+                                       // assume normal selector
+                                       if (eventUtils.trigger(element, "focusquery", eventData, true, true)) {
+                                               if (useQueryContext) {
+                                                       if (customQueryContextSelector) {
+                                                               queryContext = document.querySelector(customQueryContextSelector);
+                                                       }
+                                                       if (queryContext) {
+                                                               return queryContext.parentNode.querySelector(selector);
+                                                       }
+                                               }
+                                               return element.parentNode.querySelector(selector);
+                                       }
+                                       // if some code managed to fill nextElement use it
+                                       if (eventData.nextElement) {
+                                               return eventData.nextElement;
+                                       }
+                               }
+
+                               return null;
+                       }
+
+                       /**
+                        * Locks focus on element if possible
+                        * @param {ns.widget.tv.BaseKeyboardSupport} self
+                        * @param {HTMLElement} element
+                        * @return {boolean}
+                        * @private
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function lockFocus(self, element) {
+                               var widget = null;
+
+                               if (DOM.getNSData(element, "focus-lock") === true) {
+                                       widget = engine.getBinding(element);
+                                       if (widget && widget !== currentKeyboardWidget) {
+                                               widget.saveKeyboardSupport();
+                                               widget.enableKeyboardSupport();
+                                               widget.blur();
+                                               focusOnNeighborhood(self, element, {direction: lastMoveDirection, key: KEY_CODES.down});
+                                               return true;
+                                       }
+                               }
+                               return false;
+                       }
+
+                       /**
+                        * Unlocks focus from element if possible
+                        * @param {ns.widget.tv.BaseKeyboardSupport} self
+                        * @param {HTMLElement} element
+                        * @return {boolean}
+                        * @private
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function unlockFocus(self, element) {
+                               var widget;
+                               // enable escape from children (usability)
+
+                               if (DOM.getNSData(element, "focus-lock") !== true) {
+                                       element = selectorUtils.getClosestBySelectorNS(element.parentNode, "focus-lock=true");
+                                       if (!element) {
+                                               return false;
+                                       }
+                               }
+                               widget = engine.getBinding(element);
+                               if (widget && widget === currentKeyboardWidget) {
+                                       widget.disableKeyboardSupport();
+                                       widget.restoreKeyboardSupport();
+                                       focusOnElement(self, element, {direction: lastMoveDirection, key: KEY_CODES.down});
+                                       return true;
+                               }
+
+                               return false;
+                       }
+
+                       function focusOnNeighborhood(self, element, options) {
+                               var positionFrom = "",
+                                       nextElements = [],
+                                       nextElement,
+                                       nextNumber = 0,
+                                       current = options.current,
+                                       event = options.event,
+                                       widget,
+                                       setFocus = false;
+
+                               switch (options.key) {
+                                       case KEY_CODES.left:
+                                               positionFrom = EVENT_POSITION.left;
+                                               break;
+                                       case KEY_CODES.up:
+                                               positionFrom = EVENT_POSITION.up;
+                                               break;
+                                       case KEY_CODES.right:
+                                               positionFrom = EVENT_POSITION.right;
+                                               break;
+                                       case KEY_CODES.down:
+                                               positionFrom = EVENT_POSITION.down;
+                                               break;
+                                       case KEY_CODES.enter:
+                                               // @TODO context enter
+                                               if (current) {
+                                                       if (lockFocus(self, current)) {
+                                                               if (event) {
+                                                                       event.preventDefault();
+                                                                       event.stopImmediatePropagation();
+                                                               }
+                                                       } else {
+                                                               widget = ns.engine.getBinding(current);
+                                                               if (widget && typeof widget._actionEnter === "function") {
+                                                                       widget._actionEnter(current);
+                                                               }
+                                                       }
+                                                       return;
+                                               }
+                                               break;
+                                       case KEY_CODES.escape:
+                                               // this also is done by hwkey
+                                               if (current) {
+                                                       if (unlockFocus(self, current)) {
+                                                               if (event) {
+                                                                       event.preventDefault();
+                                                                       event.stopImmediatePropagation();
+                                                               }
+                                                       } else {
+                                                               widget = ns.engine.getBinding(current);
+                                                               if (widget && typeof widget._actionEscape === "function") {
+                                                                       widget._actionEscape(current);
+                                                               }
+                                                       }
+                                                       return;
+                                               }
+                                               break;
+                                       default:
+                                               return;
+                               }
+
+                               options.direction = options.direction || positionFrom;
+                               if (positionFrom) {
+                                       lastMoveDirection = positionFrom;
+                               }
+
+                               nextElement = fetchCustomFocusElement(element, positionFrom);
+
+                               if (!nextElement) {
+                                       nextElements = getNeighborhoodLinks(element, current, options);
+                                       nextElement = nextElements[nextNumber];
+                               }
+
+                               if (options._last) {
+                                       // we are looking for element to focus from the farthest to the nearest
+                                       nextNumber = nextElements.length - 1;
+                                       nextElement = nextElements[nextNumber];
+                                       while (nextElement && !setFocus) {
+                                               // if element to focus is found
+                                               setFocus = focusOnElement(self, nextElement, options);
+                                               nextElement = nextElements[--nextNumber];
+                                       }
+                               } else {
+                                       // we are looking for element to focus from the nearest
+                                       nextNumber = 0;
+                                       nextElement = nextElements[nextNumber];
+                                       if (nextElement) {
+                                               while (nextElement && !setFocus) {
+                                                       // if element to focus is found
+                                                       setFocus = focusOnElement(self, nextElement, options);
+                                                       nextElement = nextElements[++nextNumber];
+                                               }
+                                       } else {
+                                               eventUtils.trigger(
+                                                       // if current element is not parent of current element
+                                                       // then we cannot trigger event on current element
+                                                       // eg. current page doesn't have any focusable element
+                                                       //     and current focusable element is on previous page
+                                                       //     in this case event has to be trigger on current page
+                                                       //     not on previous page
+                                                       DOM.isChildElementOf(current, element) ? current : element,
+                                                       "taufocusborder",
+                                                       options
+                                               );
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Supports keyboard event.
+                        * @method _onKeyup
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype._onKeyup = function (event) {
+                               var self = this,
+                                       keyboardSupportState = ns.getConfig("keyboardSupport", false);
+
+                               if (keyboardSupportState && self._supportKeyboard) {
+                                       if (!self.keydownEventRepeated) {
+                                               // short press was detected
+                                               self._onShortPress(event);
+                                       }
+                                       self.keydownEventTimeStart = null;
+                                       self.keydownEventRepeated = false;
+                               }
+                       };
+
+                       /**
+                        * Mouse move listener
+                        * @method _onMouseMove
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype._onMouseMove = function (event) {
+                               var self = this,
+                                       // we finding element on current position
+                                       target = document.elementFromPoint(event.pageX, event.pageY),
+                                       keyboardSupportState = ns.getConfig("keyboardSupport", false),
+                                       element = null,
+                                       currentElement = activeElement,
+                                       fromPosition = EVENT_POSITION.down;
+
+                               if (keyboardSupportState && self._supportKeyboard) {
+                                       // check matching or find matching parent
+                                       element = selectorUtils.getClosestBySelector(target, selectorsString);
+
+                                       if (element !== currentElement) {
+                                               if (currentElement) {
+                                                       fromPosition = getDirectionFromAngle(
+                                                               getRelativeAngle({
+                                                                       left: event.pageX,
+                                                                       top: event.pageY
+                                                               }, currentElement)
+                                                       );
+                                               } else {
+                                                       // if we not have currently focused element we calculate move direction
+                                                       // in compare with previous mouse position
+                                                       fromPosition = getDirectionFromAngle(
+                                                               getRelativeAngle({
+                                                                       left: event.pageX,
+                                                                       top: event.pageY
+                                                               }, {
+                                                                       left: event.pageX - event.movementX,
+                                                                       top: event.pageY - event.movementY
+                                                               })
+                                                       );
+                                               }
+
+                                               focusOnElement(self, element, {
+                                                       direction: fromPosition
+                                               });
+                                       }
+                               }
+                       };
+
+                       /**
+                        * This function is used as a filtering function in function getNeighborhoodLinks.
+                        * @method _onKeyup
+                        * @param {string} direction
+                        * @param {Object} filteredElement Information about element, which is being already filtered.
+                        * @param {HTMLElement} element Current element
+                        * @param {Object} [elementOffset] Offset of current element
+                        * @private
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function filterNeighbors(direction, filteredElement, element, elementOffset) {
+                               var filteredElementOffset = filteredElement.offset,
+                                       filteredElementHeight = filteredElement.height,
+                                       filteredElementWidth = filteredElement.width,
+                                       elementHeight = element.offsetHeight,
+                                       elementWidth = element.offsetWidth;
+
+                               elementOffset = elementOffset || element.getBoundingClientRect();
+                               switch (direction) {
+                                       case "top":
+                                               // we are looking for elements, which are above the current element, but
+                                               // only in the same column
+                                               if (elementOffset.left >= filteredElementOffset.left + filteredElementWidth ||
+                                                       elementOffset.left + elementWidth <= filteredElementOffset.left) {
+                                                       // if element is on the right or on the left of the current element,
+                                                       // we remove it from the set
+                                                       return false;
+                                               }
+                                               return filteredElementOffset.top < elementOffset.top;
+                                       case "bottom":
+                                               // we are looking for elements, which are under the current element, but
+                                               // only in the same column
+                                               if (elementOffset.left >= filteredElementOffset.left + filteredElementWidth ||
+                                                       elementOffset.left + elementWidth <= filteredElementOffset.left) {
+                                                       return false;
+                                               }
+                                               return filteredElementOffset.top >= elementOffset.bottom;
+                                       case "left":
+                                               // we are looking for elements, which are on the left of the current element, but
+                                               // only in the same row
+                                               if (elementOffset.top >= filteredElementOffset.top + filteredElementHeight ||
+                                                       elementOffset.top + elementHeight <= filteredElementOffset.top) {
+                                                       return false;
+                                               }
+                                               return filteredElementOffset.left < elementOffset.left;
+                                       case "right":
+                                               // we are looking for elements, which are ont the right of the current element, but
+                                               // only in the same row
+                                               if (elementOffset.top >= filteredElementOffset.top + filteredElementHeight ||
+                                                       elementOffset.top + elementHeight <= filteredElementOffset.top) {
+                                                       return false;
+                                               }
+                                               return filteredElementOffset.left >= elementOffset.right;
+                               }
+                               return false;
+                       }
+
+                       prototype._onHWKey = function (event) {
+                               var self = this,
+                                       current = activeElement || getFocusedLink();
+
+                               if (event.keyName === "back" && current && unlockFocus(self, current)) {
+                                       event.preventDefault();
+                                       event.stopImmediatePropagation();
+                                       return true;
+                               }
+
+                               return false;
+                       };
+
+                       /**
+                        * Supports keyboard long press event.
+                        * It is called on keydown event, when the long press was not detected.
+                        * @method _onLongPress
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype._onLongPress = function (event) {
+                               var self = this,
+                                       delay = ns.getConfig("keyboardLongpressInterval", 100),
+                                       options = {
+                                               current: activeElement || getFocusedLink(),
+                                               key: event.keyCode,
+                                               // it is repeated event, so we make animation shorter
+                                               duration: ((delay - 30) >= ANIMATION_MIN_TIME ? delay - 30 : ANIMATION_MIN_TIME),
+                                               _last: true, // option for function focusOnNeighborhood
+                                               _filterNeighbors: filterNeighbors // option for function getNeighborhoodLinks
+                                       };
+
+                               // set focus on next element
+                               focusOnNeighborhood(self, self.keyboardElement || self.element, options);
+                       };
+
+                       /**
+                        * Supports keyboard short press event.
+                        * It is called on keyup event, when the long press was not detected.
+                        * @method _onShortPress
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype._onShortPress = function (event) {
+                               var self = this;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       // set focus on next element
+                                       focusOnNeighborhood(self, self.keyboardElement || self.element, {
+                                               current: activeElement || getFocusedLink(),
+                                               event: event,
+                                               key: event.keyCode
+                                       });
+                               }
+                       };
+
+                       /**
+                        * Supports keyboard event.
+                        * @method _onKeydown
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype._onKeydown = function (event) {
+                               var self = this,
+                                       delay = ns.getConfig("keyboardLongpressInterval", 1000),
+                                       keyboardSupportState = ns.getConfig("keyboardSupport", false),
+                                       currentTime;
+
+                               // if widget supports keyboard's events
+                               if (keyboardSupportState && self._supportKeyboard && isCursorKey(event.keyCode)) {
+                                       // stop scrolling
+                                       event.preventDefault();
+                                       event.stopPropagation();
+
+                                       currentTime = Date.now();
+                                       // we check if it is a single event or repeated one
+                                       // @note: On TV property .repeat for event is not available, so we have to count time
+                                       //        between events
+                                       if (!self.keydownEventTimeStart || (currentTime - self.keydownEventTimeStart > delay)) {
+                                               // stop scrolling
+                                               //event.preventDefault();
+                                               //event.stopPropagation();
+
+                                               // if it is repeated event, we make animation shorter
+                                               if (self.keydownEventTimeStart) {
+                                                       // long press was detected
+                                                       self._onLongPress(event);
+                                                       self.keydownEventRepeated = true;
+                                               }
+                                               self.keydownEventTimeStart = currentTime;
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Add Supports keyboard event.
+                        *
+                        * This method should be called in _bindEvent method in widget.
+                        * @method _bindEventKey
+                        * @protected
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype._bindEventKey = function () {
+                               var self = this;
+
+                               if (!self._onKeyupHandler) {
+                                       self._onKeyupHandler = self._onKeyup.bind(self);
+                                       self._onKeydownHandler = self._onKeydown.bind(self);
+                                       self._onHWKeyHandler = self._onHWKey.bind(self);
+                                       document.addEventListener("keyup", self._onKeyupHandler, false);
+                                       document.addEventListener("keydown", self._onKeydownHandler, false);
+                                       document.addEventListener("tizenhwkey", self._onHWKeyHandler, false);
+                               }
+                       };
+
+                       /**
+                        * Adds support for mouse events
+                        * @method _bindEventMouse
+                        * @protected
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype._bindEventMouse = function () {
+                               var self = this;
+
+                               if (!self._onMouseMoveHandler) {
+                                       self._onMouseMoveHandler = self._onMouseMove.bind(self);
+                                       //we resign from virtual events because of problems with enter event
+                                       document.addEventListener("mousemove", self._onMouseMoveHandler, false);
+                               }
+                       };
+
+                       /**
+                        * Supports keyboard event.
+                        *
+                        * This method should be called in _destroy method in widget.
+                        * @method _destroyEventKey
+                        * @protected
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype._destroyEventKey = function () {
+                               if (this._onKeyupHandler) {
+                                       document.removeEventListener("keyup", this._onKeyupHandler, false);
+                                       document.removeEventListener("keydown", this._onKeydownHandler, false);
+                                       document.removeEventListener("tizenhwkey", this._onHWKeyHandler, false);
+                                       this._onKeyupHandler = null;
+                               }
+                       };
+
+                       /**
+                        * Removes support for mouse events
+                        * @method _destroyEventMouse
+                        * @protected
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype._destroyEventMouse = function () {
+                               if (this._onClickHandler) {
+                                       //we resign from virtual events because of problems with enter event
+                                       document.removeEventListener("mousemove", this._onMouseMoveHandler, false);
+                               }
+                       };
+
+                       /**
+                        * Blurs from focused element.
+                        * @method blur
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       BaseKeyboardSupport.blurAll = function () {
+                               var focusedElement = activeElement || getFocusedLink(),
+                                       focusedElementWidget = focusedElement && engine.getBinding(focusedElement);
+
+                               if (focusedElementWidget) {
+                                       // call blur on widget
+                                       focusedElementWidget.blur();
+                               } else if (focusedElement) {
+                                       // or call blur on element
+                                       focusedElement.blur();
+                               }
+                       };
+
+                       /**
+                        * Focuses on element.
+                        * @method focusElement
+                        * @param {HTMLElement} [element] widget's element
+                        * @param {?HTMLElement|number|boolean|string} [elementToFocus] element to focus
+                        * @param {Object} [options]
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       BaseKeyboardSupport.focusElement = function (element, elementToFocus, options) {
+                               var links,
+                                       linksLength,
+                                       i;
+
+                               options = options || {};
+                               if (options.current === undefined) {
+                                       options.current = getFocusedLink();
+                               }
+
+                               if (elementToFocus instanceof HTMLElement) {
+                                       if (element) {
+                                               links = getFocusableElements(element, true);
+                                               linksLength = links.length;
+                                               for (i = 0; i < linksLength; i++) {
+                                                       if (links[i] === elementToFocus) {
+                                                               elementToFocus.focus();
+                                                       }
+                                               }
+                                       } else {
+                                               elementToFocus.focus();
+                                       }
+                               } else if (typeof elementToFocus === "number") {
+                                       links = getFocusableElements(element, true);
+                                       if (links[elementToFocus]) {
+                                               focusOnElement(null, links[elementToFocus], options);
+                                       }
+                               } else if (typeof elementToFocus === "string" && KEY_CODES[elementToFocus]) {
+                                       options.direction = KEY_CODES[elementToFocus];
+                                       focusOnNeighborhood(null, element, options);
+                               } else {
+                                       links = getFocusableElements(element, true);
+                                       if (links[0]) {
+                                               focusOnElement(null, links[0], options);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Enables keyboard support on widget.
+                        * @method enableKeyboardSupport
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype.enableKeyboardSupport = function () {
+                               this._supportKeyboard = true;
+                               currentKeyboardWidget = this;
+                       };
+
+                       /**
+                        * Enables keyboard support on widget.
+                        * @method restoreKeyboardSupport
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype.restoreKeyboardSupport = function () {
+                               var previousKeyboardWidget = previousKeyboardWidgets.pop();
+
+                               if (previousKeyboardWidget) {
+                                       previousKeyboardWidget.enableKeyboardSupport();
+                               }
+                       };
+
+                       /**
+                        * Disables keyboard support on widget.
+                        * @method disableKeyboardSupport
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype.disableKeyboardSupport = function () {
+                               currentKeyboardWidget = null;
+                               this._supportKeyboard = false;
+                       };
+
+                       /**
+                        * Save history of keyboard support on widget.
+                        * @method saveKeyboardSupport
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       prototype.saveKeyboardSupport = function () {
+                               if (currentKeyboardWidget) {
+                                       previousKeyboardWidgets.push(currentKeyboardWidget);
+                                       currentKeyboardWidget.disableKeyboardSupport();
+                               }
+                       };
+
+                       /**
+                        * Convert selector object to string
+                        * @method getValueOfSelector
+                        * @param {Object} selectorObject
+                        * @static
+                        * @private
+                        * @return {string}
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function getValueOfSelector(selectorObject) {
+                               return selectorObject.value;
+                       }
+
+                       /**
+                        * Find index in selectors array for given selector
+                        * @method findSelectorIndex
+                        * @param {string} selector
+                        * @static
+                        * @private
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       function findSelectorIndex(selector) {
+                               return utilArray.map(selectors, getValueOfSelector).indexOf(selector);
+                       }
+
+                       /**
+                        * @method getFocusableElements
+                        */
+                       prototype.getFocusableElements = getFocusableElements;
+
+                       /**
+                        * Registers an active selector.
+                        * @param {string} selector
+                        * @param {boolean} includeDisabled
+                        * @method registerActiveSelector
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       BaseKeyboardSupport.registerActiveSelector = function (selector, includeDisabled) {
+                               var selectorArray = selector.split(","),
+                                       index;
+
+                               utilArray.forEach(selectorArray, function (currentSelector) {
+                                       currentSelector = currentSelector.trim();
+                                       index = findSelectorIndex(currentSelector);
+
+                                       // check if not registered yet
+                                       if (index === -1) {
+                                               selectors.push({
+                                                       value: currentSelector,
+                                                       includeDisabled: includeDisabled,
+                                                       count: 1
+                                               });
+                                       } else {
+                                               selectors[index].count++;
+                                       }
+                               });
+
+                               prepareSelector();
+                       };
+
+                       /**
+                        * Unregister an active selector.
+                        * @param {string} selector
+                        * @method unregisterActiveSelector
+                        * @static
+                        * @member ns.widget.tv.BaseKeyboardSupport
+                        */
+                       BaseKeyboardSupport.unregisterActiveSelector = function (selector) {
+                               var selectorArray = selector.split(","),
+                                       index;
+
+                               utilArray.forEach(selectorArray, function (currentSelector) {
+                                       currentSelector = currentSelector.trim();
+                                       index = findSelectorIndex(currentSelector);
+
+                                       if (index !== -1) {
+                                               --selectors[index].count;
+                                               // check reference counter
+                                               if (selectors[index].count === 0) {
+                                                       // remove selector
+                                                       selectors.splice(index, 1);
+                                               }
+                                       }
+                               });
+
+                               prepareSelector();
+                       };
+
+                       ns.widget.core.BaseKeyboardSupport = BaseKeyboardSupport;
+
+                       }(window.document, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * # Page Widget
+ * Page is main element of application's structure.
+ *
+ * ## Default selectors
+ * In the Tizen Web UI framework the application page structure is based on a header, content and footer elements:
+ *
+ * - **The header** is placed at the top, and displays the page title and optionally buttons.
+ * - **The content** is the section below the header, showing the main content of the page.
+ * - **The footer** is a bottom part of page which can display for example buttons
+ *
+ * The following table describes the specific information for each section.
+ *
+ * <table>
+ *     <tr>
+ *         <th>Section</th>
+ *         <th>Class</th>
+ *         <th>Mandatory</th>
+ *         <th>Description</th>
+ *     </tr>
+ *     <tr>
+ *         <td rowspan="2">Page</td>
+ *         <td>ui-page</td>
+ *         <td>Yes</td>
+ *         <td>Defines the element as a page.
+ *
+ * The page widget is used to manage a single item in a page-based architecture.
+ *
+ * A page is composed of header (optional), content (mandatory), and footer (optional) elements.</td>
+ *      </tr>
+ *      <tr>
+ *          <td>ui-page-active</td>
+ *          <td>No</td>
+ *          <td>If an application has a static start page, insert the ui-page-active class in the page element to
+ *          speed up the application launch. The start page with the ui-page-active class can be displayed before
+ *          the framework is fully loaded.
+ *
+ *          If this class is not used, the framework inserts the class automatically to the first page of the
+ *          application.
+ *
+ *          However, this has a slowing effect on the application launch, because the page is displayed only after
+ *          *the* framework is fully loaded.</td>
+ *      </tr>
+ *      <tr>
+ *          <td>Header</td>
+ *          <td>ui-header</td>
+ *          <td>No</td>
+ *          <td>Defines the element as a header.</td>
+ *      </tr>
+ *      <tr>
+ *          <td>Content</td>
+ *          <td>ui-content</td>
+ *          <td>Yes</td>
+ *          <td>Defines the element as content.</td>
+ *      </tr>
+ *      <tr>
+ *          <td>Footer</td>
+ *          <td>ui-footer</td>
+ *          <td>No</td>
+ *          <td>Defines the element as a footer.
+ *
+ * The footer section is mostly used to include option buttons.</td>
+ *      </tr>
+ *  </table>
+ *
+ * All elements with class=ui-page will be become page widgets
+ *
+ *      @example
+ *         <!--Page layout-->
+ *         <div class="ui-page ui-page-active">
+ *             <header class="ui-header"></header>
+ *             <div class="ui-content"></div>
+ *             <footer class="ui-footer"></footer>
+ *         </div>
+ *
+ *         <!--Page layout with more button in header-->
+ *         <div class="ui-page ui-page-active">
+ *             <header class="ui-header ui-has-more">
+ *                 <h2 class="ui-title">Call menu</h2>
+ *                 <button type="button" class="ui-more ui-icon-overflow">More Options</button>
+ *             </header>
+ *             <div class="ui-content">Content message</div>
+ *             <footer class="ui-footer">
+ *                 <button type="button" class="ui-btn">Footer Button</button>
+ *             </footer>
+ *         </div>
+ *
+ * ## Manual constructor
+ * For manual creation of page widget you can use constructor of widget from **tau** namespace:
+ *
+ *        @example
+ *        var pageElement = document.getElementById("page"),
+ *            page = tau.widget.Page(buttonElement);
+ *
+ * Constructor has one require parameter **element** which are base **HTMLElement** to create widget.
+ * We recommend get
+ * this element by method *document.getElementById*.
+ *
+ * ## Multi-page Layout
+ *
+ * You can implement a template containing multiple page containers in the application index.html file.
+ *
+ * In the multi-page layout, the main page is defined with the ui-page-active class.
+ * If no page has the ui-page-active
+ * class, the framework automatically sets up the first page in the source order
+ * as the main page. You can improve the
+ * launch performance by explicitly defining the main page to be displayed first.
+ * If the application has to wait for
+ * the framework to set up the main page, the page is displayed with some delay
+ * only after the framework is fully
+ * loaded.
+ *
+ * You can link to internal pages by referring to the ID of the page. For example, to link to the page with an ID
+ * of
+ * two, the link element needs the href="#two" attribute in the code, as in the following example.
+ *
+ *      @example
+ *         <!--Main page-->
+ *         <div id="one" class="ui-page ui-page-active">
+ *             <header class="ui-header"></header>
+ *             <div class="ui-content"></div>
+ *             <footer class="ui-footer"></footer>
+ *         </div>
+ *
+ *         <!--Secondary page-->
+ *         <div id="two" class="ui-page">
+ *             <header class="ui-header"></header>
+ *             <div class="ui-content"></div>
+ *             <footer class="ui-footer"></footer>
+ *         </div>
+ *
+ * To find the currently active page, use the ui-page-active class.
+ *
+ * ## Changing Pages
+ * ### Go to page in JavaScript
+ * To change page use method *tau.changePage*
+ *
+ *      @example
+ *      tau.changePage("page-two");
+ *
+ * ### Back in JavaScript
+ * To back to previous page use method *tau.back*
+ *
+ *      @example
+ *      tau.back();
+ *
+ * ## Transitions
+ *
+ * When changing the active page, you can use a page transition.
+ *
+ * Tizen Web UI Framework does not apply transitions by default. To set a custom transition effect,
+ * you must add the
+ * data-transition attribute to a link:
+ *
+ *      @example
+ *      <a href="index.html" data-transition="slideup">I\'ll slide up</a>
+ *
+ * To set a default custom transition effect for all pages, use the pageTransition property:
+ *
+ *      @example
+ *      tau.defaults.pageTransition = "slideup";
+ *
+ * ### Transitions list
+ *
+ *  - **none** no transition.
+ *  - **slideup** Makes the content of the next page slide up, appearing to conceal the content of the previous page.
+ *
+ * ## Handling Page Events
+ *
+ * With page widget we have connected many of events.
+ *
+ * To handle page events, use the following code:
+ *
+ *      @example
+ *        <div id="page" class="ui-page">
+ *             <header class="ui-header"></header>
+ *             <div class="ui-content"></div>
+ *         </div>
+ *
+ *         <script>
+ *             var page = document.getElementById("page");
+ *             page.addEventListener("Event", function(event) {
+ *                 // Your code
+ *             });
+ *         </script>
+ *
+ * To bind an event callback on the Back key, use the following code:
+ *
+ * Full list of available events is in [events list section](#events-list).
+ *
+ * To bind an event callback on the Back key, use the following code:
+ *
+ *      @example
+ *         <script>
+ *             window.addEventListener("tizenhwkey", function (event) {
+ *                 if (event.keyName == "back") {
+ *                     // Call window.history.back() to go to previous browser window
+ *                     // Call tizen.application.getCurrentApplication().exit() to exit application
+ *                     // Add script to add another behavior
+ *                 }
+ *             });
+ *         </script>
+ *
+ *
+ * ## Methods
+ *
+ * To call method on widget you can use tau API:
+ *
+ *        @example
+ *        var pageElement = document.getElementById("page"),
+ *            page = tau.widget.Page(buttonElement);
+ *
+ *        page.methodName(methodArgument1, methodArgument2, ...);
+ *
+ * @class ns.widget.core.Page
+ * @extends ns.widget.BaseWidget
+ * @component-selector .ui-page
+ * @component-type container-component
+ * @component-constraint 'popup', 'drawer', 'header', 'bottom-button'
+ * @component-attachable false
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Damian Osipiuk <d.osipiuk@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               /**
+                        * Alias for {@link ns.widget.BaseWidget}
+                        * @property {Object} BaseWidget
+                        * @member ns.widget.core.Page
+                        * @private
+                        * @static
+                        */
+                       var BaseWidget = ns.widget.BaseWidget,
+                               PageContainer = ns.widget.core.PageContainer,
+                               /**
+                                * Alias for {@link ns.util}
+                                * @property {Object} util
+                                * @member ns.widget.core.Page
+                                * @private
+                                * @static
+                                */
+                               util = ns.util,
+                               utilsDOM = util.DOM,
+                               /**
+                                * Alias for {@link ns.util.selectors}
+                                * @property {Object} utilSelectors
+                                * @member ns.widget.core.Page
+                                * @private
+                                * @static
+                                */
+                               utilSelectors = util.selectors,
+                               /**
+                                * Alias for {@link ns.engine}
+                                * @property {Object} engine
+                                * @member ns.widget.core.Page
+                                * @private
+                                * @static
+                                */
+                               engine = ns.engine,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               arrayUtil = ns.util.array,
+
+                               Page = function (element, options) {
+                                       var self = this;
+
+                                       BaseKeyboardSupport.call(self);
+
+                                       /**
+                                        * Callback on resize
+                                        * @property {?Function} _contentFillAfterResizeCallback
+                                        * @private
+                                        * @member ns.widget.core.Page
+                                        */
+                                       self._contentFillAfterResizeCallback = null;
+                                       self._initialContentStyle = {};
+                                       self._lastScrollPosition = 0;
+                                       self._requestToShowGoToTopButton = null;
+                                       /**
+                                        * Options for widget.
+                                        * @property {Object} options
+                                        * @member ns.widget.core.Page
+                                        */
+                                       self.options = options || {};
+
+                                       self._contentStyleAttributes = ["height", "width", "minHeight", "marginTop", "marginBottom"];
+
+                                       self._ui = {};
+                               },
+
+                               /**
+                                * Dictionary for page related event types
+                                * @property {Object} EventType
+                                * @member ns.widget.core.Page
+                                * @static
+                                */
+                               EventType = {
+                                       /**
+                                        * Triggered on the page we are transitioning to,
+                                        * after the transition animation has completed.
+                                        * @event pageshow
+                                        * @member ns.widget.core.Page
+                                        */
+                                       SHOW: "pageshow",
+                                       /**
+                                        * Triggered on the page we are transitioning away from,
+                                        * after the transition animation has completed.
+                                        * @event pagehide
+                                        * @member ns.widget.core.Page
+                                        */
+                                       HIDE: "pagehide",
+                                       /**
+                                        * Triggered when the page has been created in the DOM
+                                        * (for example, through Ajax) but before all widgets
+                                        * have had an opportunity to enhance the contained markup.
+                                        * @event pagecreate
+                                        * @member ns.widget.core.Page
+                                        */
+                                       CREATE: "pagecreate",
+                                       /**
+                                        * Triggered when the page is being initialized,
+                                        * before most plugin auto-initialization occurs.
+                                        * @event pagebeforecreate
+                                        * @member ns.widget.core.Page
+                                        */
+                                       BEFORE_CREATE: "pagebeforecreate",
+                                       /**
+                                        * Triggered on the page we are transitioning to,
+                                        * before the actual transition animation is kicked off.
+                                        * @event pagebeforeshow
+                                        * @member ns.widget.core.Page
+                                        */
+                                       BEFORE_SHOW: "pagebeforeshow",
+                                       /**
+                                        * Triggered on the page we are transitioning away from,
+                                        * before the actual transition animation is kicked off.
+                                        * @event pagebeforehide
+                                        * @member ns.widget.core.Page
+                                        */
+                                       BEFORE_HIDE: "pagebeforehide"
+                               },
+                               /**
+                                * Dictionary for page related css class names
+                                * @property {Object} classes
+                                * @member ns.widget.core.Page
+                                * @static
+                                * @readonly
+                                */
+                               classes = {
+                                       uiPage: "ui-page",
+                                       /**
+                                        * Indicates active page
+                                        * @style ui-page-active
+                                        * @member ns.widget.core.Page
+                                        */
+                                       uiPageActive: "ui-page-active",
+                                       uiSection: "ui-section",
+                                       uiHeader: "ui-header",
+                                       uiMore: "ui-more",
+                                       uiHeaderOnlyMoreButton: "ui-header-has-only-more-button",
+                                       uiFooter: "ui-footer",
+                                       uiContent: "ui-content",
+                                       uiTitle: "ui-title",
+                                       uiPageScroll: "ui-scroll-on",
+                                       uiScroller: "ui-scroller",
+                                       uiArcListview: "ui-arc-listview",
+                                       uiContentUnderPopup: "ui-content-under-popup",
+                                       uiPageFlex: "ui-page-flex",
+                                       //appbar temporary classes
+                                       uiAppbar: "ui-appbar",
+                                       uiAppbarTitle: "ui-appbar-title",
+                                       uiAppbarTitleContainer: "ui-appbar-title-container"
+                               },
+                               HEADER_SELECTOR = "header,[data-role='header'],." + classes.uiHeader,
+                               FOOTER_SELECTOR = "footer,[data-role='footer'],." + classes.uiFooter,
+                               //ui-indexscrollbar is needed as widget ads html markup at the
+                               //same level as content, other wise page content is build on
+                               //indexscrollbar element
+                               CONTENT_SELECTOR = "[data-role='content'],." + classes.uiContent,
+                               ONLY_CHILD_MORE_BUTTON_SELECTOR = "." + classes.uiMore + ":first-child:last-child",
+                               SHOW_GO_TO_TOP_BUTTON_TIMEOUT = 800,
+                               prototype = new BaseWidget();
+
+                       Page.classes = classes;
+                       Page.events = EventType;
+                       Page.selector = "[data-role=page],.ui-page";
+
+                       /**
+                        * Configure default options for widget
+                        * @method _configure
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._configure = function () {
+                               var options = this.options;
+                               /**
+                                * Object with default options
+                                * @property {Object} options
+                                * @property {boolean|string|null} [options.header=false] Sets content of header.
+                                * @property {boolean|string|null} [options.footer=false] Sets content of footer.
+                                * @property {boolean} [options.autoBuildWidgets=false] Automatically build widgets inside page.
+                                * @property {boolean} [options.goToTopButton=false] Shows go to top button at the bottom of the page.
+                                * @property {string} [options.content=null] Sets content of popup.
+                                * @member ns.widget.core.Page
+                                * @static
+                                */
+
+
+                               options.header = null;
+                               options.footer = null;
+                               options.content = null;
+                               options.goToTopButton = ns.getConfig("goToTopButton");
+                               options.enablePageScroll = ns.getConfig("enablePageScroll");
+                               options.autoBuildWidgets = ns.getConfig("autoBuildOnPageChange");
+                               this.options = options;
+                       };
+
+                       /**
+                        * Method return heigh of space available for page content
+                        * @method getContentHeight
+                        * @return {number}
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.getContentHeight = function () {
+                               return this._contentHeight;
+                       };
+
+                       /**
+                        * Setup size of element to 100% of screen
+                        * @method _contentFill
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._contentFill = function () {
+                               var self = this,
+                                       element = self.element,
+                                       screenWidth = window.innerWidth,
+                                       screenHeight = window.innerHeight,
+                                       elementStyle = element.style,
+                                       ui = self._ui,
+                                       content = ui.content,
+                                       contentStyle,
+                                       header = ui.header,
+                                       top = 0,
+                                       bottom = 0,
+                                       footer = ui.footer,
+                                       mainTab = ui.mainTab;
+
+                               // Main Tab widget can be part of screen
+                               if (mainTab) {
+                                       screenHeight = screenHeight - mainTab.getBoundingClientRect().height;
+                               }
+
+                               elementStyle.width = screenWidth + "px";
+                               elementStyle.height = screenHeight + "px";
+
+                               if (footer) {
+                                       bottom += footer.getBoundingClientRect().height;
+                               }
+                               if (header) {
+                                       top = utilsDOM.getElementHeight(header, null, false, true);
+                               }
+                               self._contentHeight = screenHeight - top - bottom;
+
+                               if (content && !element.classList.contains(classes.uiPageFlex)) {
+                                       contentStyle = content.style;
+                                       
+                                       if (footer) {
+                                               contentStyle.marginBottom = bottom + "px";
+                                               contentStyle.paddingBottom = (-bottom) + "px";
+                                       }
+
+                                       if (!self.options.enablePageScroll) {
+                                               contentStyle.height = self._contentHeight + "px";
+                                       }
+                               }
+
+                               if (self.options.model) {
+                                       self._fillContentsFromModel();
+                               }
+                       };
+
+                       prototype._fillContentsFromModel = function () {
+                               var self = this,
+                                       model = self.options.model || {},
+                                       data = model;
+
+                               Object.keys(data).forEach(function (key) {
+                                       [].slice.call(self.element.querySelectorAll("[data-bind='" + key + "']"))
+                                               .forEach(function (elem) {
+                                                       elem.textContent = data[key];
+                                               });
+                               });
+                       }
+
+                       prototype._storeContentStyle = function () {
+                               var self = this,
+                                       initialContentStyle = self._initialContentStyle,
+                                       contentStyleAttributes = self._contentStyleAttributes,
+                                       content = self.element.querySelector("." + classes.uiContent),
+                                       contentStyle = content ? content.style : {};
+
+                               contentStyleAttributes.forEach(function (name) {
+                                       initialContentStyle[name] = contentStyle[name];
+                               });
+                       };
+
+                       /**
+                        * Restore saved styles for content.
+                        * Called on refresh or hide.
+                        * @protected
+                        */
+                       prototype._restoreContentStyle = function () {
+                               var self = this,
+                                       initialContentStyle = self._initialContentStyle,
+                                       contentStyleAttributes = self._contentStyleAttributes,
+                                       content = self.element.querySelector("." + classes.uiContent),
+                                       contentStyle = content ? content.style : {};
+
+                               contentStyleAttributes.forEach(function (name) {
+                                       if (initialContentStyle[name]) {
+                                               contentStyle[name] = initialContentStyle[name];
+                                       }
+                               });
+                       };
+
+                       /**
+                        * Setter for footer option
+                        * @method _setFooter
+                        * @param {HTMLElement} element
+                        * @param {string} value
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._setFooter = function (element, value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       footer = ui.footer;
+
+                               // footer element if footer does not exist and value is true or string
+                               if (!footer && value) {
+                                       footer = document.createElement("footer");
+                                       element.appendChild(footer);
+                                       ui.footer = footer;
+                               }
+                               if (footer) {
+                                       // remove child if footer does not exist and value is set to false
+                                       if (value === false) {
+                                               element.removeChild(footer);
+                                               ui.footer = null;
+                                       } else {
+                                               // if options is set to true, to string or not is set
+                                               // add class
+                                               footer.classList.add(classes.uiFooter);
+                                               // if is string fill content by string value
+                                               if (typeof value === "string") {
+                                                       ui.footer.textContent = value;
+                                               }
+                                       }
+                                       // and remember options
+                                       self.options.footer = value;
+                               }
+                       };
+
+                       /**
+                        * Setter for header option
+                        * @method _setHeader
+                        * @param {HTMLElement} element
+                        * @param {string} value
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._setHeader = function (element, value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       header = ui.header;
+
+                               // header element if header does not exist and value is true or string
+                               if (!header && value) {
+                                       header = document.createElement("header");
+                                       element.appendChild(header);
+                                       ui.header = header;
+                               }
+                               if (header) {
+                                       // remove child if header does not exist and value is set to false
+                                       if (value === false) {
+                                               element.removeChild(header);
+                                               ui.header = null;
+                                       } else {
+                                               // if options is set to true, to string or not is set
+                                               // add class
+                                               header.classList.add(classes.uiHeader);
+                                               // if is string fill content by string value
+                                               if (typeof value === "string") {
+                                                       ui.header.textContent = value;
+                                               }
+
+                                               if (ns.support && ns.support.shape && ns.support.shape.circle) {
+                                                       // patch for backward compability - if header has only more button
+                                                       // (it was common for rectangle devices) header should be marked
+                                                       // and take no place at all.
+                                                       if (header.querySelector(ONLY_CHILD_MORE_BUTTON_SELECTOR) && header.textContent.trim() === "") {
+                                                               header.classList.add(classes.uiHeaderOnlyMoreButton);
+                                                       }
+                                               }
+                                       }
+                                       // and remember options
+                                       self.options.header = value;
+                               }
+                       };
+
+                       /**
+                        * Setter for content option
+                        * @method _setContent
+                        * @param {HTMLElement} element
+                        * @param {string} value
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._setContent = function (element, value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       content = ui.content,
+                                       child = element.firstChild,
+                                       next;
+
+                               if (!content && value) {
+                                       content = document.createElement("div");
+                                       while (child) {
+                                               next = child.nextSibling;
+                                               if (child !== ui.footer && child !== ui.header) {
+                                                       content.appendChild(child);
+                                               }
+                                               child = next;
+                                       }
+                                       element.insertBefore(content, ui.footer);
+                                       ui.content = content;
+                               }
+                               if (content) {
+                                       // remove child if content exist and value is set to false
+                                       if (value === false) {
+                                               element.removeChild(content);
+                                               ui.content = null;
+                                       } else {
+                                               // if options is set to true, to string or not is set
+                                               // add class
+                                               content.classList.add(classes.uiContent);
+                                               // if is string fill content by string value
+                                               if (typeof value === "string") {
+                                                       content.textContent = value;
+                                               }
+                                       }
+                                       // and remember options
+                                       self.options.content = value;
+                               }
+                       };
+
+                       /**
+                        * Method creates empty page header. It also checks for additional
+                        * content to be added in header.
+                        * @method _buildHeader
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._buildHeader = function (element) {
+                               var self = this;
+
+                               self._ui.header = utilSelectors.getChildrenBySelector(element, HEADER_SELECTOR)[0] || null;
+                               if (self.options.header === undefined) {
+                                       self.options.header = !!self._ui.header;
+                               }
+                               self._setHeader(element, self.options.header);
+                       };
+
+                       /**
+                        * Method creates empty page footer.
+                        * @method _buildFooter
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._buildFooter = function (element) {
+                               var self = this;
+
+                               self._ui.footer = utilSelectors.getChildrenBySelector(element, FOOTER_SELECTOR)[0] || null;
+                               if (self.options.footer === undefined) {
+                                       self.options.footer = !!self._ui.footer;
+                               }
+                               self._setFooter(element, self.options.footer);
+                       };
+
+                       /**
+                        * Method creates empty page content.
+                        * @method _buildContent
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._buildContent = function (element) {
+                               var self = this;
+
+                               self._ui.content = utilSelectors.getChildrenBySelector(element, CONTENT_SELECTOR)[0] || null;
+                               if (self.options.content === undefined) {
+                                       self.options.content = !!self._ui.content;
+                               }
+                               self._setContent(element, self.options.content);
+                       };
+
+                       /**
+                        * Method tries to find mainTab
+                        * @method _findMainTab
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._findMainTab = function () {
+                               var self = this,
+                                       pageContainer = utilSelectors.getClosestBySelector(self.element, "." + PageContainer.classes.pageContainer);
+
+                               self._ui.mainTab = self.element.querySelector(".ui-main-tab") || // main tab assigned to page
+                                       pageContainer && pageContainer.querySelector(".ui-main-tab-visible") || // active main tab assigned to page container
+                                       null;
+                       };
+
+                       prototype._buildGoToTopButton = function (element) {
+                               var self = this,
+                                       ui = self._ui;
+
+                               if (self.options.goToTopButton) {
+                                       ui.goToTopButton = document.createElement("div");
+                                       ui.goToTopButton.classList.add("ui-button-go-to-top");
+                                       element.appendChild(ui.goToTopButton);
+                               }
+                       };
+
+                       prototype._showGoToTopButton = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       goToTopButton = ui.goToTopButton;
+
+                               if (!self._requestToShowGoToTopButton) {
+                                       self._requestToShowGoToTopButton = setTimeout(function () {
+                                               goToTopButton.style.display = "block";
+                                               self._requestToShowGoToTopButton = null;
+                                       }, SHOW_GO_TO_TOP_BUTTON_TIMEOUT);
+                               }
+                       };
+
+                       prototype._hideGoToTopButton = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       goToTopButton = ui.goToTopButton;
+
+                               if (self._requestToShowGoToTopButton) {
+                                       clearTimeout(self._requestToShowGoToTopButton);
+                                       self._requestToShowGoToTopButton = null;
+                               }
+                               goToTopButton.style.display = "none";
+                       };
+
+                       prototype._handleGoToTopButtonClick = function () {
+                               var self = this,
+                                       element = self.element,
+                                       scroller = self.getScroller(),
+                                       arcListViewElement = null,
+                                       arcListViewWidget = null;
+
+                               self._hideGoToTopButton();
+
+                               arcListViewElement = element.querySelector("." + classes.uiArcListview);
+                               if (arcListViewElement) {
+                                       arcListViewWidget = ns.engine.getBinding(arcListViewElement);
+                                       if (arcListViewWidget) {
+                                               // FIXME: according to guide, scroll should be made immediately.
+                                               // However, this API does not properly work without animation.
+                                               arcListViewWidget.scrollToPosition(0, false /* do animation */);
+                                       }
+                               } else {
+                                       scroller.scrollTop = 0;
+                               }
+                       };
+
+                       /**
+                        * Set ARIA attributes on page structure
+                        * @method _setAria
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._setAria = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       content = ui.content,
+                                       header = ui.header,
+                                       footer = ui.footer,
+                                       title = ui.title;
+
+                               if (content) {
+                                       content.setAttribute("role", "main");
+                               }
+
+                               if (header) {
+                                       header.setAttribute("role", "header");
+                               }
+
+                               if (footer) {
+                                       footer.setAttribute("role", "footer");
+                               }
+
+                               if (title) {
+                                       title.setAttribute("role", "heading");
+                                       title.setAttribute("aria-level", 1);
+                                       title.setAttribute("aria-label", "title");
+                               }
+                       };
+
+                       /**
+                        * Find title of page
+                        * @param {HTMLElement} element
+                        * @method _setTitle
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._setTitle = function (element) {
+                               var self = this,
+                                       dataPageTitle = utilsDOM.getNSData(element, "title"),
+                                       header = self._ui.header,
+                                       pageTitle = dataPageTitle,
+                                       titleElements,
+                                       mainTitleElement,
+                                       titleContainer;
+
+                               if (header) {
+                                       //TODO: Create another widget for appbar
+                                       header.classList.add(classes.uiAppbar);
+                                       titleContainer = utilSelectors.getChildrenByClass(header, classes.uiAppbarTitleContainer)[0];
+
+                                       if (!titleContainer) {
+                                               titleContainer = document.createElement("div");
+                                               titleContainer.classList.add(classes.uiAppbarTitleContainer);
+                                               header.appendChild(titleContainer);
+                                       }
+
+                                       titleElements = utilSelectors.getChildrenBySelector(header, "h1, h2, h3, h4, h5, h6");
+
+                                       mainTitleElement = titleElements[0];
+
+                                       if (!pageTitle && mainTitleElement) {
+                                               pageTitle = mainTitleElement.innerText;
+                                               self._ui.title = mainTitleElement;
+                                       }
+
+                                       if (!dataPageTitle && pageTitle) {
+                                               utilsDOM.setNSData(element, "title", pageTitle);
+                                       }
+
+                                       arrayUtil.forEach(titleElements, function (titleElement) {
+                                               // TODO: Create another widget for appbar on mobile
+                                               titleElement.classList.add(classes.uiTitle);
+                                               titleElement.classList.add(classes.uiAppbarTitle);
+                                               titleContainer.appendChild(titleElement);
+                                       });
+                               }
+                       };
+
+                       /**
+                        * Build page
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._build = function (element) {
+                               var self = this;
+
+                               element.classList.add(classes.uiPage);
+                               element.classList.add(classes.uiPageFlex);
+                               self._buildHeader(element);
+                               self._buildFooter(element);
+                               self._buildContent(element);
+                               self._buildGoToTopButton(element);
+                               self._setTitle(element);
+                               self._setAria();
+
+                               //it means that we are in wearable profile and we want to make a scrollview on page element (not content)
+                               if (self.options.enablePageScroll === true && !element.querySelector("." + classes.uiScroller)) {
+                                       engine.instanceWidget(element, "Scrollview");
+                               }
+                               return element;
+                       };
+
+
+                       /**
+                        * This method sets page active or inactive.
+                        *
+                        *    @example
+                        *    <div id="myPage"></div>
+                        *    <script type="text/javascript">
+                        *      var page = tau.widget.Page(document.getElementById("myPage"));
+                        *      page.setActive(true);
+                        *    </script>
+                        *
+                        * @method setActive
+                        * @param {boolean} [value=true] If true, then page will be active. Otherwise, page will be inactive.
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.setActive = function (value) {
+                               var elementClassList = this.element.classList;
+
+                               if (value || value === undefined) {
+                                       this.focus();
+                                       elementClassList.add(classes.uiPageActive);
+                               } else {
+                                       this.blur();
+                                       elementClassList.remove(classes.uiPageActive);
+                               }
+                       };
+
+                       /**
+                        * Return current status of page.
+                        * @method isActive
+                        * @member ns.widget.core.Page
+                        * @instance
+                        */
+                       prototype.isActive = function () {
+                               return this.element.classList.contains(classes.uiPageActive);
+                       };
+
+                       /**
+                        * Sets the focus to page
+                        * @method focus
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.focus = function () {
+                               var element = this.element,
+                                       focusable = element.querySelector("[autofocus]") || element;
+
+                               focusable.focus();
+                       };
+
+                       /**
+                        * Removes focus from page and all descendants
+                        * @method blur
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.blur = function () {
+                               var element = this.element,
+                                       focusable = document.activeElement || element;
+
+                               focusable.blur();
+                       };
+
+                       /**
+                        * Bind events to widget
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       element = self.element,
+                                       header = self._ui.header,
+                                       goToTopButton = self._ui.goToTopButton;
+
+                               self._contentFillAfterResizeCallback = self._contentFill.bind(self);
+                               window.addEventListener("resize", self._contentFillAfterResizeCallback, false);
+                               if (header) {
+                                       header.addEventListener("appbarcollapsed", function () {
+                                               var scroller = self.getScroller(),
+                                                       scrollview = ns.engine.getBinding(scroller);
+
+                                               scrollview.enableScrolling();
+                                       }, false);
+
+                                       header.addEventListener("appbarexpanded", function () {
+                                               var scroller = self.getScroller(),
+                                                       scrollview = ns.engine.getBinding(scroller, "Scrollview");
+
+                                               if (scrollview) {
+                                                       scrollview.disableScrolling();
+                                               }
+                                       }, false);
+                               }
+
+                               if (goToTopButton) {
+                                       element.addEventListener("showGoToTopButton", self._showGoToTopButton.bind(self), false);
+                                       element.addEventListener("hideGoToTopButton", self._hideGoToTopButton.bind(self), false);
+                                       goToTopButton.addEventListener("vclick", self._handleGoToTopButtonClick.bind(self), false);
+                               }
+                       };
+
+                       /**
+                        * Refresh widget structure
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._refresh = function () {
+                               this._findMainTab();
+                               this._restoreContentStyle();
+                               this._contentFill();
+                       };
+
+                       /**
+                        * Layouting page structure
+                        * @method layout
+                        * @internal
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.layout = function () {
+                               this._findMainTab();
+                               this._storeContentStyle();
+                               this._contentFill();
+                       };
+
+                       /**
+                        * This method triggers BEFORE_SHOW event.
+                        * @method onBeforeShow
+                        * @internal
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.onBeforeShow = function () {
+                               var self = this,
+                                       scroller = self.getScroller();
+
+                               if (scroller) {
+                                       scroller.scrollTop = self._lastScrollPosition || 0;
+                               }
+
+                               if (typeof self.enableKeyboardSupport === "function") {
+                                       self.enableKeyboardSupport();
+                                       // add keyboard events
+                                       self._bindEventKey();
+                               }
+
+                               self.trigger(EventType.BEFORE_SHOW);
+                       };
+
+                       /**
+                        * This method triggers SHOW event.
+                        * @method onShow
+                        * @internal
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.onShow = function () {
+                                                               this.trigger(EventType.SHOW);
+                       };
+
+                       /**
+                        * This method triggers BEFORE_HIDE event.
+                        * @method onBeforeHide
+                        * @internal
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.onBeforeHide = function () {
+                               var self = this,
+                                       scroller = self.getScroller();
+
+                               if (scroller) {
+                                       self._lastScrollPosition = scroller.scrollTop;
+                               }
+
+                               if (typeof self.disableKeyboardSupport === "function") {
+                                       self.disableKeyboardSupport();
+                                       // remove keyboard events
+                                       self._destroyEventKey();
+                               }
+                               self.trigger(EventType.BEFORE_HIDE);
+                       };
+
+                       /**
+                        * This method triggers HIDE event.
+                        * @method onHide
+                        * @internal
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.onHide = function () {
+                               this._restoreContentStyle();
+                               this.trigger(EventType.HIDE);
+                       };
+
+                       /**
+                        * Destroy widget
+                        * @method _destroy
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Page
+                        */
+                       prototype._destroy = function (element) {
+                               var self = this;
+
+                               element = element || self.element;
+                               
+                               window.removeEventListener("resize", self._contentFillAfterResizeCallback, false);
+                               // destroy widgets on children
+                               engine.destroyAllWidgets(element, true);
+
+                               self._contentFillAfterResizeCallback = null;
+                       };
+
+                       /**
+                        * Return scroller
+                        * @method getScroller
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.getScroller = function () {
+                               var element = this.element,
+                                       scroller = element.querySelector("." + classes.uiScroller);
+
+                               return scroller || element.querySelector("." + classes.uiContent) || element;
+                       };
+
+                       /**
+                        * This method sets scroll position when page is hidden.
+                        * New page scroll position will be restored on "pagebeforeshow"
+                        * @param {number} scrollPosition last scroll position to set
+                        * @method setLastScrollPosition
+                        * @member ns.widget.core.Page
+                        */
+                       prototype.setLastScrollPosition = function (scrollPosition) {
+                               this._lastScrollPosition = scrollPosition;
+                       }
+
+                       Page.prototype = prototype;
+
+                       Page.createEmptyElement = function () {
+                               var div = document.createElement("div");
+
+                               div.classList.add(classes.uiPage);
+                               return div;
+                       };
+
+                       engine.defineWidget(
+                               "Page",
+                               Page.selector,
+                               [
+                                       "focus",
+                                       "blur",
+                                       "setActive"
+                               ],
+                               Page,
+                               // for register in jQuery Mobile space
+                               "mobile"
+                       );
+
+                       ns.widget.core.Page = Page;
+                       }(window.document, ns));
+/**
+ * #Footer
+ *
+ * ## Creating footer
+ *
+ *    @example template
+ *      <footer class="ui-footer"></footer>
+ *
+ * @class ns.widget.core.Footer
+ * @component-selector .ui-page > footer, .ui-page .ui-footer
+ * @component-type layout-component
+ * @extends ns.widget.BaseWidget
+ *
+ */
+
+/**
+ * #Header
+ *
+ *    @example template
+ *      <header class="ui-header"><h2 class="ui-title">Header</h2></header>
+ *
+ * @class ns.widget.core.Header
+ * @component-selector .ui-page > header, .ui-page > .ui-header
+ * @component-type layout-component
+ * @extends ns.widget.BaseWidget
+ */
+/**
+ * Button for menu with icon in header
+ * @style ui-more
+ * @selector .ui-btn
+ * @member ns.widget.core.Header
+ * @wearable
+ * @since 2.3.1
+ */
+/**
+ * Icon style for menu button
+ * @style ui-icon-detail
+ * @selector .ui-btn.ui-more
+ * @member ns.widget.core.Header
+ * @wearable
+ * @since 2.3.1
+ */
+/**
+ * Icon style for menu button
+ * @style ui-icon-overflow
+ * @selector .ui-btn.ui-more
+ * @member ns.widget.core.Header
+ * @wearable
+ * @since 2.3.1
+ */
+/**
+ * Icon style for menu button
+ * @style ui-icon-selectall
+ * @selector .ui-btn.ui-more
+ * @member ns.widget.core.Header
+ * @wearable
+ * @since 2.3.1
+ */
+
+/**
+ * #Content
+ *
+ *    @example template
+ *      <div class="ui-content"></div>
+ *
+ * @class ns.widget.core.Content
+ * @component-selector .ui-content
+ * @component-type container-component
+ * @component-constraint 'bottom-button', 'checkbox', 'listview', 'processing', 'closet-tau-circle-progress', 'radio', 'toggleswitch', 'text', 'closet-image', 'sectionchanger'
+ * @extends ns.widget.BaseWidget
+ */
+/**
+ * Defines the buttons inside column width as 100% of the screen
+ * @style ui-grid-col-1
+ * @selector div:not(.ui-grid-col-1):not(.ui-grid-col-2):not(.ui-grid-col-3):not(.ui-grid-row)
+ * @member ns.widget.core.Content
+ * @wearable
+ * @since 2.3.1
+ */
+/**
+ * Defines the buttons inside column width as 50% of the screen
+ * @style ui-grid-col-2
+ * @selector div:not(.ui-grid-col-1):not(.ui-grid-col-2):not(.ui-grid-col-3):not(.ui-grid-row)
+ * @member ns.widget.core.Content
+ * @wearable
+ * @since 2.3.1
+ */
+/**
+ * Defines the buttons inside column width as 50% of the screen
+ * @style ui-grid-col-3
+ * @selector div:not(.ui-grid-col-1):not(.ui-grid-col-2):not(.ui-grid-col-3):not(.ui-grid-row)
+ * @member ns.widget.core.Content
+ * @wearable
+ * @since 2.3.1
+ */
+/**
+ * Arranges the buttons inside in a row
+ * @style ui-grid-row
+ * @selector div:not(.ui-grid-col-1):not(.ui-grid-col-2):not(.ui-grid-col-3):not(.ui-grid-row)
+ * @member ns.widget.core.Content
+ * @wearable
+ * @since 2.3.1
+ */
+;
+/*global define, ns */
+/*jslint nomen: true, plusplus: true, bitwise: false */
+/*
+ * Copyright (c) 2010 - 2014 Samsung Electronics Co., Ltd.
+ * License : MIT License V2
+ */
+/**
+ * #Template Manager
+ *
+ * Object menage template's engines and renderer HTMLElement by template engine.
+ *
+ * @class ns.template
+ * @since 2.4
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ */
+(function () {
+       "use strict";
+                               var utilPath = ns.util.path,
+                               template,
+                               templateFunctions = {},
+                               globalOptions = {
+                                       "pathPrefix": "",
+                                       "default": ""
+                               };
+
+                       /**
+                        * Function to get global option
+                        *
+                        *      @example
+                        *              tau.template.get("pathPrefix");
+                        *              // -> "/prefix/to/all/paths"
+                        *
+                        * @method get
+                        * @param {string} name param name which will be return
+                        * @return {*} return value of option
+                        * @since 2.4
+                        * @member ns.template
+                        */
+                       function get(name) {
+                               return globalOptions[name];
+                       }
+
+                       /**
+                        * Function to set global option
+                        *
+                        *      @example
+                        *              tau.template.set("pathPrefix", "/views");
+                        *
+                        * @method set
+                        * @param {string} name param name which will be set
+                        * @param {*} value value to set
+                        * @since 2.4
+                        * @member ns.template
+                        */
+                       function set(name, value) {
+                               globalOptions[name] = value;
+                       }
+
+                       /**
+                        * Register new template function
+                        *
+                        * Template function should have 4 arguments:
+                        *
+                        *  - globalOptions - global options of template engine
+                        *  - path - path or id of template content
+                        *  - data - data for template render
+                        *  - callback - callback call on finish
+                        *
+                        * and should call callback on finish with arguments:
+                        *
+                        *  - status - object describing status of render
+                        *  - element - base HTMLElement of template results (on error can be null)
+                        *
+                        * after registration you can use engine in render function.
+                        *
+                        *      @example
+                        *              tau.template.register("inline", function(globalOptions, path, data, callback) {
+                        *                      callback({
+                        *                                              success: true
+                        *                                      },
+                        *                                      document.createElement("div")
+                        *                              );
+                        *              });
+                        *
+                        * @method register
+                        * @param {string} name Engine name
+                        * @param {Function} templateFunction function to renderer template
+                        * @since 2.4
+                        * @member ns.template
+                        */
+                       function register(name, templateFunction) {
+                               templateFunctions[name] = templateFunction;
+                       }
+
+                       /**
+                        * Unregister template function
+                        *
+                        * @method unregister
+                        * @param {string} name Engine name
+                        * @since 2.4
+                        * @member ns.template
+                        */
+                       function unregister(name) {
+                               templateFunctions[name] = null;
+                       }
+
+                       /**
+                        * Return engine with given name
+                        *
+                        * @method engine
+                        * @param {string} name Engine name
+                        * @since 2.4
+                        * @member ns.template
+                        */
+                       function engine(name) {
+                               return templateFunctions[name];
+                       }
+
+                       /**
+                        * Create absolute path for given path.
+                        * If parameter withProfile is true, the returned path will have name of profile
+                        * separated by dots before the last dot.
+                        * @method getAbsUrl
+                        * @param {string} path
+                        * @param {boolean} withProfile Create path with profile's name
+                        * @return {string} changed path
+                        * @since 2.4
+                        */
+                       function getAbsUrl(path, withProfile) {
+                               var profile = ns.info.profile,
+                                       lastDot = path.lastIndexOf(".");
+
+                               if (utilPath.isAbsoluteUrl(path)) {
+                                       return path;
+                               }
+
+                               if (withProfile) {
+                                       path = path.substring(0, lastDot) + "." + profile + path.substring(lastDot);
+                               }
+
+                               return utilPath.makeUrlAbsolute((globalOptions.pathPrefix || "") + path, utilPath.getLocation());
+                       }
+
+                       /**
+                        * Return HTMLElement for given path
+                        *
+                        * When engine name is not given then get default name from global options. If this is not set then get first registered engine.
+                        *
+                        * Result of this method is handed to callback. First parameter of callback is object with status. Second is HTMLElement generated by engine.
+                        *
+                        * Status object contains properties:
+                        *
+                        *  - _boolean_ success - inform about success or error
+                        *  - _string_ description contains details on error
+                        *
+                        *      @example
+                        *              tau.template.render("external/path/to/file.html", {additionalParameter: true}, function(status, element) {
+                        *                      if (status.success) {
+                        *                              document.body.appendChild(element);
+                        *                      } else {
+                        *                              console.error(status.description);
+                        *                      }, "html");
+                        *
+                        * @method render
+                        * @param {string} path Path to file ot other id for template system
+                        * @param {Object} data additional data for template system
+                        * @param {Function} callback function which will be called on finish
+                        * @param {string} [engineName] engine name
+                        * @since 2.4
+                        * @member ns.template
+                        */
+                       function render(path, data, callback, engineName) {
+                               var templateFunction = templateFunctions[engineName || get("default") || ""],
+                                       targetPath,
+                                       targetCallback = function (status, element) {
+                                               // add current patch
+                                               status.absUrl = targetPath;
+                                               callback(status, element);
+                                       },
+                                       templateCallback = function (status, element) {
+                                               if (status.success) {
+                                                       // path was found and callback can be called
+                                                       targetCallback(status, element);
+                                               } else {
+                                                       // try one more time with path without profile
+                                                       targetPath = getAbsUrl(path, false);
+                                                       templateFunction(globalOptions, targetPath, data || {}, targetCallback);
+                                               }
+                                       };
+
+                               // if template engine name and default name is not given then we
+                               // take first registered engine
+                               if (!templateFunction) {
+                                       templateFunction = templateFunctions[Object.keys(templateFunctions).pop()];
+                               }
+
+                               // if template system exists then we go to him
+                               if (templateFunction) {
+                                       targetPath = getAbsUrl(path, ns.getConfig("findProfileFile", false));
+                                       templateFunction(globalOptions, targetPath, data || {}, templateCallback);
+                               } else {
+                                       // else we return error
+                                       callback({
+                                               success: false,
+                                               description: "Can't get engine system"
+                                       }, null);
+                               }
+                       }
+
+                       template = {
+                               get: get,
+                               set: set,
+                               register: register,
+                               unregister: unregister,
+                               engine: engine,
+                               render: render
+                       };
+
+                       ns.template = template;
+                       }());
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* global define, HTMLElement, ns */
+/**
+ * #Router
+ *
+ * Main class to navigate between pages, popups and other widgets which has own rules in all profiles.
+ *
+ * Class communicates with PageContainer which deactivate and activate changed pages.
+ *
+ * Router listening on events triggered by history manager.
+ *
+ * ## Getting instance
+ *
+ * To receive instance of router you should use method _getInstance_
+ *
+ *     @example
+ *             var router = ns.router.Router.getInstance();
+ *
+ * By default TAU create instance of router and getInstance method return this instance.
+ *
+ * ##Connected widgets
+ *
+ * Router cooperate with widgets:
+ *
+ *  - Page
+ *  - Popup
+ *  - Drawer
+ *  - Dialog (mobile)
+ *  - CircularIndexScrollBar (wearable - circle)
+ *
+ * Opening or closing these widgets are possible by create link with correct rel.
+ *
+ * ##Global options used in router
+ *
+ *  - *pageContainer* = document.body - default container element
+ *  - *pageContainerBody* = false - use body instead pageContainer option
+ *  - *autoInitializePage* = true - automatically initialize first page
+ *  - *addPageIfNotExist* = true - automatically add page if doesn't exist
+ *  - *loader* = false - enable loader on change page
+ *  - *disableRouter* = false - disable auto initialize of router
+ *
+ * @class ns.router.Router
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ * @author Hyunkook, Cho <hk0713.cho@samsung.com>
+ * @author Piotr Czajka <p.czajka@samsung.com>
+ * @author Junhyeon Lee <juneh.lee@samsung.com>
+ * @author Michał Szepielak <m.szepielak@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @author Heeju Joo <heeju.joo@samsung.com>
+ */
+(function (window, document) {
+       "use strict";
+                               /**
+                        * Local alias for ns.util
+                        * @property {Object} util Alias for {@link ns.util}
+                        * @member ns.router.Router
+                        * @static
+                        * @private
+                        */
+                       var util = ns.util,
+                               /**
+                                * Local alias for ns.event
+                                * @property {Object} eventUtils Alias for {@link ns.event}
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               eventUtils = ns.event,
+                               /**
+                                * Alias for {@link ns.util.DOM}
+                                * @property {Object} DOM
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               DOM = util.DOM,
+                               /**
+                                * Local alias for ns.util.path
+                                * @property {Object} path Alias for {@link ns.util.path}
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               path = util.path,
+                               /**
+                                * Local alias for ns.util.selectors
+                                * @property {Object} selectors Alias for {@link ns.util.selectors}
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               selectors = util.selectors,
+                               /**
+                                * Local alias for ns.util.object
+                                * @property {Object} object Alias for {@link ns.util.object}
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               object = util.object,
+                               /**
+                                * Local alias for ns.engine
+                                * @property {Object} engine Alias for {@link ns.engine}
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               engine = ns.engine,
+                               /**
+                                * Local alias for ns.router
+                                * @property {Object} router Alias for namespace ns.router
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               router = ns.router,
+                               /**
+                                * Local alias for ns.history
+                                * @property {Object} history Alias for {@link ns.history}
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               history = ns.history,
+                               historyManager = history.manager,
+                               /**
+                                * Local alias for ns.history.manager.events
+                                * @property {Object} historyManagerEvents Alias for (@link ns.history.manager.events}
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               historyManagerEvents = historyManager.events,
+                               /**
+                                * Local alias for ns.router.route
+                                * @property {Object} route Alias for namespace ns.router.route
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               route = router.route,
+                               /**
+                                * Local alias for document body element
+                                * @property {HTMLElement} body
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               body = document.body,
+                               /**
+                                * Alias to Array.slice method
+                                * @method slice
+                                * @member ns.router.Router
+                                * @private
+                                * @static
+                                */
+                               slice = [].slice,
+                               /**
+                                * Local instance of the Router
+                                * @property {Object} routerInstance
+                                * @member ns.router.Router
+                                * @static
+                                * @private
+                                */
+                               _isLock = false,
+
+                               ORDER_NUMBER = {
+                                       1: "page",
+                                       10: "panel",
+                                       100: "popup",
+                                       101: "dialog",
+                                       1000: "drawer",
+                                       2000: "circularindexscrollbar"
+                               },
+
+                               eventType = {
+                                       BEFORE_ROUTER_INIT: "beforerouterinit",
+                                       ROUTER_INIT: "routerinit"
+                               },
+
+                               HASH_REGEXP = /[#|\s]/g,
+
+                               Page = ns.widget.core.Page,
+
+                               routerInstance,
+
+                               template = ns.template,
+
+                               Router = function () {
+                                       var self = this;
+
+                                       /**
+                                        * Instance of widget PageContainer which controls page changing.
+                                        * @property {?ns.widget.core.PageContainer} [container=null]
+                                        * @member ns.router.Router
+                                        */
+                                       self.container = null;
+                                       /**
+                                        * Settings for last call of method open
+                                        * @property {Object} [settings={}]
+                                        * @member ns.router.Router
+                                        */
+                                       self.settings = {};
+
+                                       /**
+                                        * Handler for event "statechange"
+                                        * @property {Function} [_onStateChangeHandler=null]
+                                        * @member ns.router.Router
+                                        * @protected
+                                        * @since 2.4
+                                        */
+                                       self._onStateChangeHandler = null;
+                                       /**
+                                        * Handler for event "hashchange"
+                                        * @property {Function} [_onHashChangeHandler=null]
+                                        * @member ns.router.Router
+                                        * @protected
+                                        * @since 2.4
+                                        */
+                                       self._onHashChangeHandler = null;
+                                       /**
+                                        * Handler for event "controllercontent"
+                                        * @property {Function} [_onControllerContent=null]
+                                        * @member ns.router.Router
+                                        * @protected
+                                        * @since 2.4
+                                        */
+                                       self._onControllerContent = null;
+
+                                       /**
+                                        * Router locking flag
+                                        * @property {boolean} locked=false
+                                        * @member ns.router.Router
+                                        * @since 2.4
+                                        */
+                                       self.locked = false;
+                               };
+
+                       /**
+                        * Default values for router
+                        * @property {Object} defaults
+                        * @property {boolean} [defaults.fromHashChange=false] Sets if will be changed after hashchange.
+                        * @property {boolean} [defaults.reverse=false] Sets the direction of change.
+                        * @property {boolean} [defaults.volatileRecord=false] Sets if the current history entry will be modified or a new one will be created.
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.defaults = {
+                               fromHashChange: false,
+                               reverse: false,
+                               volatileRecord: false
+                       };
+
+                       /**
+                        * Find the closest link for element
+                        * @method findClosestLink
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @private
+                        * @static
+                        * @member ns.router.Router
+                        */
+                       function findClosestLink(element) {
+                               while (element) {
+                                       if (element.nodeType === Node.ELEMENT_NODE && element.nodeName && element.nodeName === "A") {
+                                               break;
+                                       }
+                                       element = element.parentNode;
+                               }
+                               return element;
+                       }
+
+                       /**
+                        * Handle event link click
+                        * @method linkClickHandler
+                        * @param {ns.router.Router} router
+                        * @param {Event} event
+                        * @private
+                        * @static
+                        * @member ns.router.Router
+                        */
+                       function linkClickHandler(router, event) {
+                               var link = findClosestLink(event.target),
+                                       href,
+                                       useDefaultUrlHandling,
+                                       options;
+
+                               if (link && event.which === 1) {
+                                       href = link.getAttribute("href");
+                                       useDefaultUrlHandling = (link.getAttribute("rel") === "external") || link.hasAttribute("target");
+                                       if (!useDefaultUrlHandling) {
+                                               options = DOM.getData(link);
+                                               router.open(href, options, event);
+                                               eventUtils.preventDefault(event);
+                                       }
+                               }
+                       }
+
+                       Router.prototype.linkClick = function (event) {
+                               linkClickHandler(this, event);
+                       };
+
+                       function openUrlFromState(instanceRouter, state) {
+                               var rules = router.route,
+                                       prevState = history.activeState,
+                                       reverse = state && history.getDirection(state) === "back",
+                                       maxOrderNumber,
+                                       orderNumberArray = [],
+                                       ruleKey,
+                                       options,
+                                       url = path.getLocation(),
+                                       isContinue = true,
+                                       transition,
+                                       rule;
+
+                               transition = reverse ? ((prevState && prevState.transition) || "none") : state.transition;
+                               options = object.merge({}, state, {
+                                       reverse: reverse,
+                                       transition: transition,
+                                       fromHashChange: true
+                               });
+
+                               // find rule with max order number
+                               for (ruleKey in rules) {
+                                       if (rules.hasOwnProperty(ruleKey) && rules[ruleKey].active) {
+                                               orderNumberArray.push(rules[ruleKey].orderNumber);
+                                       }
+                               }
+                               maxOrderNumber = Math.max.apply(null, orderNumberArray);
+                               rule = rules[ORDER_NUMBER[maxOrderNumber]];
+
+                               if (rule && rule.onHashChange(url, options, prevState)) {
+                                       if (maxOrderNumber === 10) {
+                                               // rule is panel
+                                               return;
+                                       }
+                                       isContinue = false;
+                               }
+
+                               history.setActive(state);
+                               if (isContinue) {
+                                       instanceRouter.open(state.url, options);
+                               }
+                       }
+
+                       /**
+                        * Detect rel attribute from HTMLElement.
+                        *
+                        * This method tries to match element to each rule filter and return first rule name which match.
+                        *
+                        * If don't match any rule then return null.
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              router.detectRel(document.getElementById("pageId"));
+                        *              // if HTML element will be match to selector of page then return rule for page
+                        *
+                        * @param {HTMLElement} to element to check
+                        * @member ns.router.Router
+                        * @return {?string}
+                        */
+                       Router.prototype.detectRel = function (to) {
+                               var rule,
+                                       i;
+
+                               for (i in route) {
+                                       if (route.hasOwnProperty(i)) {
+                                               rule = route[i];
+                                               if (selectors.matchesSelector(to, rule.filter)) {
+                                                       return i;
+                                               }
+                                       }
+                               }
+
+                               return null;
+                       };
+
+
+                       /**
+                        * Open given page with deferred
+                        * @method _openDeferred
+                        * @param {HTMLElement} to HTMLElement of page
+                        * @param {Object} [options]
+                        * @param {"page"|"popup"|"external"} [options.rel = "page"] Represents kind of link as "page"
+                        * or "popup"
+                        * or "external" for linking to another domain.
+                        * @param {string} [options.transition = "none"] Sets the animation used during change of
+                        * page.
+                        * @param {boolean} [options.reverse = false] Sets the direction of change.
+                        * @param {boolean} [options.fromHashChange = false] Sets if will be changed after hashchange.
+                        * @param {boolean} [options.volatileRecord = false] Sets if the current history entry will
+                        * be modified or
+                        * a new one will be created.
+                        * @param {boolean} [options.dataUrl] Sets if page has url attribute.
+                        * @param {?string} [options.container = null] It is used in RoutePopup as selector for
+                        * container.
+                        * @param {Event} event
+                        * @member ns.router.Router
+                        * @protected
+                        */
+                       Router.prototype._openDeferred = function (to, options, event) {
+                               var self = this,
+                                       rule = route[options.rel],
+                                       deferred = {
+                                               resolve: function (_options, content) {
+                                                       rule.open(content, _options, event);
+                                               },
+                                               reject: function (_options) {
+                                                       eventUtils.trigger(self.container.element, "changefailed", _options);
+                                               }
+                                       };
+
+                               if (typeof to === "string") {
+                                       if (to.replace(HASH_REGEXP, "")) {
+                                               self._loadUrl(to, options, rule, deferred);
+                                       }
+                               } else {
+                                       // execute deferred object immediately
+                                       if (to && selectors.matchesSelector(to, rule.filter)) {
+                                               deferred.resolve(options, to);
+                                       } else {
+                                               deferred.reject(options);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Change page to page given in parameter "to".
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              router.open("pageId");
+                        *              // open page with given id
+                        *              router.open("page.html");
+                        *              // open page from html file
+                        *              router.open("popupId");
+                        *              // open popup with given id
+                        *
+                        * @method open
+                        * @param {string|HTMLElement} to Id of page or file url or HTMLElement of page
+                        * @param {Object} [options]
+                        * @param {"page"|"popup"|"external"} [options.rel="page"] Represents kind of link as "page" or "popup" or "external" for linking to another domain.
+                        * @param {string} [options.transition="none"] Sets the animation used during change of page.
+                        * @param {boolean} [options.reverse=false] Sets the direction of change.
+                        * @param {boolean} [options.fromHashChange=false] Sets if will be changed after hashchange.
+                        * @param {boolean} [options.volatileRecord=false] Sets if the current history entry will be modified or a new one will be created.
+                        * @param {boolean} [options.dataUrl] Sets if page has url attribute.
+                        * @param {?string} [options.container=null] It is used in RoutePopup as selector for container.
+                        * @param {Event} [event] Event object
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.open = function (to, options, event) {
+                               var self = this,
+                                       rel,
+                                       rule;
+
+                               if (!_isLock) {
+                                       to = getHTMLElement(to);
+                                       rel = (options && options.rel) ||
+                                               (to instanceof HTMLElement && self.detectRel(to));
+                                       rel = rel || "page";
+                                       rule = route[rel];
+
+                                       if (rel === "back") {
+                                               history.back();
+                                       } else if (rule) {
+                                               options = object.merge(
+                                                       {
+                                                               rel: rel
+                                                       },
+                                                       self.defaults,
+                                                       rule.option(),
+                                                       options
+                                               );
+                                               self._openDeferred(to, options, event);
+                                       } else {
+                                               throw new Error("Not defined router rule [" + rel + "]");
+                                       }
+                               }
+                       };
+
+
+                       /**
+                        * Init routes defined in router
+                        * @method _initRoutes
+                        * @member ns.router.Router
+                        */
+                       Router.prototype._initRoutes = function () {
+                               var ruleKey,
+                                       rules = router.route;
+
+                               for (ruleKey in rules) {
+                                       if (rules.hasOwnProperty(ruleKey) && rules[ruleKey].init) {
+                                               rules[ruleKey].init();
+                                       }
+                               }
+                       };
+
+                       function removeActivePageClass(containerElement) {
+                               var PageClasses = Page.classes,
+                                       uiPageActiveSelector = "." + PageClasses.uiPageActive,
+                                       activePages = slice.call(containerElement.querySelectorAll(uiPageActiveSelector));
+
+                               activePages.forEach(function (page) {
+                                       page.classList.remove(uiPageActiveSelector);
+                               });
+                       }
+
+                       Router.prototype._autoInitializePage = function (containerElement, pages, pageSelector) {
+                               var self = this,
+                                       page,
+                                       location = window.location,
+                                       uiPageActiveClass = Page.classes.uiPageActive,
+                                       firstPage = containerElement.querySelector("." + uiPageActiveClass);
+
+                               if (!firstPage) {
+                                       firstPage = pages[0];
+                               }
+
+                               if (firstPage) {
+                                       removeActivePageClass(containerElement);
+                               }
+
+                               if (location.hash) {
+                                       //simple check to determine if we should show firstPage or other
+                                       page = document.getElementById(location.hash.replace("#", ""));
+                                       if (page && selectors.matchesSelector(page, pageSelector)) {
+                                               firstPage = page;
+                                       }
+                               }
+
+                               if (!firstPage && ns.getConfig("addPageIfNotExist", true)) {
+                                       firstPage = Page.createEmptyElement();
+                                       while (containerElement.firstChild) {
+                                               firstPage.appendChild(containerElement.firstChild);
+                                       }
+                                       containerElement.appendChild(firstPage);
+                               }
+
+                               if (self.justBuild) {
+                                                                               if (firstPage) {
+                                               self.register(
+                                                       engine.instanceWidget(containerElement, "pagecontainer"),
+                                                       firstPage
+                                               );
+                                       }
+                               }
+
+                               return firstPage;
+                       };
+
+                       /**
+                        * Method initializes page container and builds the first page if flag autoInitializePage is
+                        * set.
+                        * @method init
+                        * @param {boolean} justBuild
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.init = function (justBuild) {
+                               var containerElement,
+                                       firstPage,
+                                       pages,
+                                       pageDefinition = ns.engine.getWidgetDefinition("Page"),
+                                       pageSelector = pageDefinition.selector,
+                                       self = this;
+
+                               eventUtils.trigger(document, eventType.BEFORE_ROUTER_INIT, self, false);
+
+                               body = document.body;
+                               self.justBuild = justBuild;
+
+                               containerElement = ns.getConfig("pageContainer") || body;
+                               pages = slice.call(containerElement.querySelectorAll(pageSelector));
+
+                               if (!ns.getConfig("pageContainerBody", false)) {
+                                       containerElement = pages.length ? pages[0].parentNode : containerElement;
+                               }
+
+                               if (ns.getConfig("autoInitializePage", true)) {
+                                       firstPage = self._autoInitializePage(containerElement, pages, pageSelector);
+                                       if (justBuild) {
+                                               return;
+                                       }
+                               }
+
+                               historyManager.enable();
+
+                               // init router's routes
+                               self._initRoutes();
+
+                               self.register(
+                                       engine.instanceWidget(containerElement, "pagecontainer"),
+                                       firstPage
+                               );
+
+                               eventUtils.trigger(document, eventType.ROUTER_INIT, self, false);
+                       };
+
+                       /**
+                        * Method removes all events listeners set by router.
+                        *
+                        * Also remove singleton instance of router;
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              router.destroy();
+                        *              var router2 = tau.router.Router.getInstance();
+                        *              // router !== router2
+                        *
+                        * @method destroy
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.destroy = function () {
+                               var self = this,
+                                       routePanel = this.getRoute("panel");
+
+                               historyManager.disable();
+
+                               window.removeEventListener("popstate", self.popStateHandler, false);
+                               if (routePanel) {
+                                       window.removeEventListener("tauback", routePanel.tauback, false);
+                               }
+                               if (body) {
+                                       body.removeEventListener("pagebeforechange", self.pagebeforechangeHandler, false);
+                                       body.removeEventListener("vclick", self.linkClickHandler, false);
+                               }
+                               ns.setConfig("pageContainer", null);
+                       };
+
+                       /**
+                        * Method sets instance of PageContainer widget
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              router.setContainer(new ns.widget.PageContainer());
+                        *
+                        * @method setContainer
+                        * @param {ns.widget.core.PageContainer} container
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.setContainer = function (container) {
+                               this.container = container;
+                       };
+
+                       /**
+                        * Method returns instance of PageContainer widget
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              containerWidget = router.getContainer();
+                        *
+                        * @method getContainer
+                        * @return {ns.widget.core.PageContainer}
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.getContainer = function () {
+                               return this.container;
+                       };
+
+                       /**
+                        * Method returns ths first page HTMLElement
+                        * @method getFirstPage
+                        * @return {HTMLElement}
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.getFirstPage = function () {
+                               return this.getRoute("page").getFirstElement();
+                       };
+
+
+                       /**
+                        * Callback for event "historyhashchange" which is triggered by history manager after hash is changed
+                        * @param {ns.router.Router} router
+                        * @param {Event} event
+                        */
+                       function onHistoryHashChange(router, event) {
+                                                               openUrlFromState(router, event.detail);
+                       }
+
+                       /**
+                        * Callback for event "historystatechange" which is triggered by history manager after hash is changed
+                        * @param {ns.router.Router} router
+                        * @param {Event} event
+                        */
+                       function onHistoryStateChange(router, event) {
+                               var options = event.detail,
+                                       //
+                                       url = options.reverse ? options.url : (options.href || options.url);
+
+                               delete options.event;
+                               router.open(url, options);
+                               // prevent current event
+                               eventUtils.preventDefault(event);
+                               eventUtils.stopImmediatePropagation(event);
+                       }
+
+                       /**
+                        * Convert HTML string to HTMLElement
+                        * @param {string|HTMLElement} content
+                        * @param {string} title
+                        * @return {?HTMLElement}
+                        */
+                       function convertToNode(content, title) {
+                               var contentNode = null,
+                                       externalDocument = document.implementation.createHTMLDocument(title),
+                                       externalBody = externalDocument.body;
+
+                               if (content instanceof HTMLElement) {
+                                       // if content is HTMLElement just set to contentNode
+                                       contentNode = content;
+                               } else {
+                                       // otherwise convert string to HTMLElement
+                                       try {
+                                               externalBody.insertAdjacentHTML("beforeend", content);
+                                               contentNode = externalBody.firstChild;
+                                       } catch (e) {
+                                               ns.error("Failed to inject element", e);
+                                       }
+                               }
+                               return contentNode;
+                       }
+
+                       /**
+                        * Set data-url on HTMLElement if not exists
+                        * @param {HTMLElement} contentNode
+                        * @param {string} url
+                        */
+                       function setURLonElement(contentNode, url) {
+                               if (url) {
+                                       if (contentNode instanceof HTMLElement && !DOM.hasNSData(contentNode, "url")) {
+                                               // if url is missing we need set data-url attribute for good finding by method open in router
+                                               url = url.replace(/^#/, "");
+                                               DOM.setNSData(contentNode, "url", url);
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Callback for event "controller-content-available" which is triggered by controller after application handle hash change
+                        * @param {ns.router.Router} router
+                        * @param {Event} event
+                        */
+                       function onControllerContent(router, event) {
+                               var data = event.detail,
+                                       content = data.content,
+                                       options = data.options,
+                                       contentNode,
+                                       url = (options.href || options.url);
+
+                               // if controller give content
+                               if (content) {
+                                       // convert to node if content is string
+                                       contentNode = convertToNode(content, options.title);
+
+                                       // set data-url on node
+                                       setURLonElement(contentNode, url);
+
+                                       // calling open method
+                                       router.open(contentNode, options);
+
+                                       //prevent event
+                                       eventUtils.preventDefault(event);
+                               }
+                       }
+
+
+                       /**
+                        * Method registers page container and the first page.
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              router.register(new ns.widget.PageContainer(), document.getElementById("firstPage"));
+                        *
+                        * @method register
+                        * @param {ns.widget.core.PageContainer} container
+                        * @param {HTMLElement} firstPage
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.register = function (container, firstPage) {
+                               var self = this,
+                                       routePopup = this.getRoute("popup");
+
+                               // sets instance of PageContainer widget
+                               self.container = container;
+
+                               // sets first page HTMLElement
+                               self.getRoute("page").setFirstElement(firstPage);
+
+                               eventUtils.trigger(document, "themeinit", self);
+
+                               // sets events handlers
+                               if (!self._onHashChangeHandler) {
+                                       self._onHashChangeHandler = onHistoryHashChange.bind(null, self);
+                                       window.addEventListener(historyManagerEvents.HASHCHANGE, self._onHashChangeHandler, false);
+                               }
+                               if (!self._onStateChangeHandler) {
+                                       self._onStateChangeHandler = onHistoryStateChange.bind(null, self);
+                                       window.addEventListener(historyManagerEvents.STATECHANGE, self._onStateChangeHandler, false);
+                               }
+                               if (!self._onControllerContent) {
+                                       self._onControllerContent = onControllerContent.bind(null, self);
+                                       window.addEventListener("controller-content-available", self._onControllerContent, false);
+                               }
+
+                               // if loader config is set then create loader widget
+                               if (ns.getConfig("loader", false)) {
+                                       container.element.appendChild(self.getLoader().element);
+                               }
+
+                               // set history support
+                               history.enableVolatileMode();
+
+                               // if first page exist open this page without transition
+                               if (firstPage) {
+                                       self.open(firstPage, {transition: "none"});
+                               }
+
+                               if (routePopup) {
+                                       routePopup.setActive(null);
+                               }
+                       };
+
+                       /**
+                        * Convert string id to HTMLElement or return HTMLElement if is given
+                        * @param {string|HTMLElement} idOrElement
+                        * @return {HTMLElement|string}
+                        */
+                       function getHTMLElement(idOrElement) {
+                               var stringId,
+                                       toElement;
+
+                               // if given argument is string then
+                               if (typeof idOrElement === "string") {
+                                       if (idOrElement[0] === "#") {
+                                               // trim first char if it is #
+                                               stringId = idOrElement.substr(1);
+                                       } else {
+                                               stringId = idOrElement;
+                                       }
+                                       // find element by id
+                                       toElement = document.getElementById(stringId);
+
+                                       if (toElement) {
+                                               // is exists element by id then return it
+                                               idOrElement = toElement;
+                                       }
+                                       // otherwise return string
+                               }
+                               return idOrElement;
+                       }
+
+                       /**
+                        * Method close route element, eg page or popup.
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              router.close("popupId", {transition: "none"});
+                        *
+                        * @method close
+                        * @param {string|HTMLElement} to Id of page or file url or HTMLElement of page
+                        * @param {Object} [options]
+                        * @param {"page"|"popup"|"external"} [options.rel="page"] Represents kind of link as "page" or "popup" or "external" for linking to another domain
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.close = function (to, options) {
+                               var rel = "back",
+                                       closingWidget = getHTMLElement(to),
+                                       rule;
+
+                               if (options && options.rel) {
+                                       rel = options.rel;
+                               } else if (closingWidget) {
+                                       rel = this.detectRel(closingWidget);
+                               }
+
+                               rule = route[rel];
+
+                               // if router is not locked
+                               if (!this.locked) {
+                                       // if rel is back then call back method
+                                       if (rel === "back") {
+                                               history.back();
+                                       } else {
+                                               // otherwise if rule exists
+                                               if (rule) {
+                                                       // call close on rule
+                                                       rule.close(closingWidget, options);
+                                               } else {
+                                                       throw new Error("Not defined router rule [" + rel + "]");
+                                               }
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Method back to previous state.
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              router.back();
+                        *
+                        * @method close
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.back = function () {
+
+                               // if router is not locked
+                               if (!this.locked) {
+                                       history.back();
+                               }
+                       };
+
+                       /**
+                        * Method opens popup.
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              router.openPopup("popupId", {transition: "none"});
+                        *
+                        * @method openPopup
+                        * @param {HTMLElement|string} to Id or HTMLElement of popup.
+                        * @param {Object} [options]
+                        * @param {string} [options.transition="none"] Sets the animation used during change of page.
+                        * @param {boolean} [options.reverse=false] Sets the direction of change.
+                        * @param {boolean} [options.fromHashChange=false] Sets if will be changed after hashchange.
+                        * @param {boolean} [options.volatileRecord=false] Sets if the current history entry will be modified or a new one will be created.
+                        * @param {boolean} [options.dataUrl] Sets if page has url attribute.
+                        * @param {?string} [options.container=null] It is used in RoutePopup as selector for container.
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.openPopup = function (to, options) {
+                               // call method open with overwrite rel option
+                               this.open(to, object.fastMerge({rel: "popup"}, options));
+                       };
+
+                       /**
+                        * Method closes popup.
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance();
+                        *              router.closePopup();
+                        *
+                        * @method closePopup
+                        * @param {Object} options
+                        * @param {string=} [options.transition]
+                        * @param {string=} [options.ext="in ui-pre-in"] options.ext
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.closePopup = function (options) {
+                               var popupRoute = this.getRoute("popup");
+
+                               if (popupRoute) {
+                                       popupRoute.close(null, options);
+                               }
+                       };
+
+                       /**
+                        * Lock router
+                        * @method lock
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.lock = function () {
+                               this.locked = true;
+                       };
+
+                       /**
+                        * Unlock router and history manager
+                        * @method unlock
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.unlock = function () {
+                               this.locked = false;
+                       };
+
+                       /**
+                        * Load content from url.
+                        *
+                        * Method prepare url and call template function to load external file.
+                        *
+                        * If option showLoadMsg is ste to tru open loader widget before start loading.
+                        *
+                        * @method _loadUrl
+                        * @param {string} url full URL to load
+                        * @param {Object} options options for this and next methods in chain
+                        * @param {boolean} [options.data] Sets if page has url attribute.
+                        * @param {Object} rule rule which support given call
+                        * @param {Object} deferred object with callbacks
+                        * @param {Function} deferred.reject callback on error
+                        * @param {Function} deferred.resolve callback on success
+                        * @member ns.router.Router
+                        * @protected
+                        */
+                       Router.prototype._loadUrl = function (url, options, rule, deferred) {
+                               var absUrl = path.makeUrlAbsolute(url, path.getLocation()),
+                                       content,
+                                       self = this,
+                                       data = options.data || {};
+
+                               // check if content is loaded in current document
+                               content = rule.find(absUrl);
+
+                               // if content doesn't find and url is embedded url
+                               if (!content && path.isEmbedded(absUrl)) {
+                                       // reject
+                                       deferred.reject({});
+                               } else {
+                                       // If the content we are interested in is already in the DOM,
+                                       // and the caller did not indicate that we should force a
+                                       // reload of the file, we are done. Resolve the deferred so that
+                                       // users can bind to .done on the promise
+                                       if (content) {
+                                               // content was found and we resolve
+                                               deferred.resolve(object.fastMerge({absUrl: absUrl}, options), content);
+                                       } else {
+
+                                               // Load the new content.
+                                               eventUtils.trigger(self.getContainer().element, options.rel + "beforeload");
+
+                                               // force return full document from template system
+                                               data.fullDocument = true;
+                                               // we put url, not the whole path to function render,
+                                               // because this path can be modified by template's module
+                                               template.render(url, data, function (status, element) {
+                                                       // if template loaded successful
+                                                       if (status.success) {
+                                                               self._loadSuccess(status.absUrl, options, rule, deferred, element);
+                                                               eventUtils.trigger(self.getContainer().element, options.rel + "load");
+                                                       } else {
+                                                               self._loadError(status.absUrl, options, deferred);
+                                                       }
+                                               });
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Error handler for loading content by AJAX
+                        * @method _loadError
+                        * @param {string} absUrl full URL to load
+                        * @param {Object} options options for this and next methods in chain
+                        * @param {boolean} [options.showLoadMsg=true] Sets if message will be shown during loading.
+                        * @param {Object} deferred object with callbacks
+                        * @param {Function} deferred.reject callback on error
+                        * @member ns.router.Router
+                        * @protected
+                        */
+                       Router.prototype._loadError = function (absUrl, options, deferred) {
+                               var detail = object.fastMerge({url: absUrl}, options),
+                                       self = this;
+
+                               ns.error("load error, file: ", absUrl);
+
+                               self.container.trigger("loadfailed", detail);
+                               deferred.reject(detail);
+                       };
+
+                       // TODO it would be nice to split this up more but everything appears to be "one off"
+                       //      or require ordering such that other bits are sprinkled in between parts that
+                       //      could be abstracted out as a group
+                       /**
+                        * Success handler for loading content by AJAX
+                        * @method _loadSuccess
+                        * @param {string} absUrl full URL to load
+                        * @param {Object} options options for this and next methods in chain
+                        * @param {boolean} [options.showLoadMsg=true] Sets if message will be shown during loading.
+                        * @param {Object} rule rule which support given call
+                        * @param {Object} deferred object with callbacks
+                        * @param {Function} deferred.reject callback on error
+                        * @param {Function} deferred.resolve callback on success
+                        * @param {string} html
+                        * @member ns.router.Router
+                        * @protected
+                        */
+                       Router.prototype._loadSuccess = function (absUrl, options, rule, deferred, html) {
+                               var detail = object.fastMerge({url: absUrl}, options),
+                                       // find element with given id in returned html
+                                       content = rule.parse(html, absUrl);
+
+                               if (content) {
+                                       deferred.resolve(detail, content);
+                               } else {
+                                       deferred.reject(detail);
+                               }
+                       };
+
+                       // TODO the first page should be a property set during _create using the logic
+                       //      that currently resides in init
+                       /**
+                        * Get initial content
+                        * @method _getInitialContent
+                        * @member ns.router.Router
+                        * @return {HTMLElement} the first page
+                        * @protected
+                        */
+                       Router.prototype._getInitialContent = function () {
+                               return this.getRoute("page").getFirstElement();
+                       };
+
+                       /**
+                        * Report an error loading
+                        * @method _showError
+                        * @param {string} absUrl
+                        * @member ns.router.Router
+                        * @protected
+                        */
+                       Router.prototype._showError = function (absUrl) {
+                               ns.error("load error, file: ", absUrl);
+                       };
+
+                       /**
+                        * Returns Page or Popup widget
+                        * @param {string} [routeName="page"] in default page or popup
+                        * @method getActive
+                        * @return {ns.widget.BaseWidget}
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.getActive = function (routeName) {
+                               var route = this.getRoute(routeName || "page");
+
+                               return route && route.getActive();
+                       };
+
+                       /**
+                        * Returns true if element in given route is active.
+                        * @param {string} [routeName="page"] in default page or popup
+                        * @method hasActive
+                        * @return {boolean}
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.hasActive = function (routeName) {
+                               var route = this.getRoute(routeName || "page");
+
+                               return !!(route && route.hasActive());
+                       };
+
+                       /**
+                        * Returns true if any popup is active.
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance(),
+                        *                      hasActivePopup = router.hasActivePopup();
+                        *                      // -> true | false
+                        *
+                        * @method hasActivePopup
+                        * @return {boolean}
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.hasActivePopup = function () {
+                               return this.hasActive("popup");
+                       };
+
+                       /**
+                        * This function returns proper route.
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance(),
+                        *                      route = router.getRoute("page"),
+                        *                      // -> Object with pages support
+                        *                      activePage = route.getActive();
+                        *                      // instance of Page widget
+                        *
+                        * @method getRoute
+                        * @param {string} type Type of route
+                        * @return {?ns.router.route.interface}
+                        * @member ns.router.Router
+                        */
+                       Router.prototype.getRoute = function (type) {
+                               return route[type];
+                       };
+
+                       /**
+                        * Returns instance of loader widget.
+                        *
+                        * If loader not exist then is created on first element matched to selector
+                        * or is created new element.
+                        *
+                        *      @example
+                        *              var loader = router.getLoader();
+                        *              // get or create loader
+                        *              loader.show();
+                        *              // show loader
+                        *
+                        * @return {?ns.widget.mobile.Loader}
+                        * @member ns.router.Page
+                        * @method getLoader
+                        */
+                       Router.prototype.getLoader = function () {
+                               var loaderDefinition = engine.getWidgetDefinition("Loader"),
+                                       loaderSelector = loaderDefinition.selector,
+                                       loaderElement;
+
+                               if (loaderDefinition) {
+                                       loaderElement = document.querySelector(loaderSelector);
+                                       return engine.instanceWidget(loaderElement, "Loader");
+                               }
+                               return null;
+                       };
+
+                       /**
+                        * Creates a new instance of the router and returns it
+                        *
+                        *      @example
+                        *              var router = Router.newInstance();
+                        *
+                        * @method newInstance
+                        * @member ns.router.Router
+                        * @static
+                        * @return {ns.router.Router}
+                        * @since 2.4
+                        */
+                       Router.newInstance = function () {
+                               return (routerInstance = new Router());
+                       };
+
+                       /**
+                        * Returns a instance of the router, creates a new if does not exist
+                        *
+                        *      @example
+                        *              var router = tau.router.Router.getInstance(),
+                        *                      // if router not exists create new instance and return
+                        *                      router2 = tau.router.Router.getInstance();
+                        *                      // only return router from first step
+                        *                      // router === router2
+                        *
+                        * @method getInstance
+                        * @member ns.router.Router
+                        * @return {ns.router.Router}
+                        * @since 2.4
+                        * @static
+                        */
+                       Router.getInstance = function () {
+                               if (!routerInstance) {
+                                       return this.newInstance();
+                               }
+                               return routerInstance;
+                       };
+
+                       router.Router = Router;
+
+                       Router.eventType = eventType;
+
+                       /**
+                        * Returns router instance
+                        * @deprecated 2,4
+                        * @return {ns.router.Router}
+                        */
+                       engine.getRouter = function () { //@TODO FIX HACK old API
+                               //@TODO this is suppressed since the tests are unreadable
+                               // tests need fixes
+                               ns.warn("getRouter() method is deprecated! Use tau.router.Router.getInstance() instead");
+                               return Router.getInstance();
+                       };
+
+                       if (!ns.getConfig("disableRouter", false)) {
+                               document.addEventListener(engine.eventType.READY, function () {
+                                       Router.getInstance().init();
+                               }, false);
+                               document.addEventListener(engine.eventType.DESTROY, function () {
+                                       Router.getInstance().destroy();
+                               }, false);
+                               document.addEventListener(engine.eventType.STOP_ROUTING, function () {
+                                       Router.getInstance().destroy();
+                               }, false);
+                       }
+
+                       //engine.initRouter(Router);
+                       }(window, window.document));
+
+/*global window, ns, define, HTMLElement */
+/*jslint plusplus: true, nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #jQuery Mobile mapping router
+ * Object maps router from TAU namespace to jQuery Mobile namespace.
+ * @class ns.jqm.router
+ */
+(function (window, document) {
+       "use strict";
+       
+                       var engine = ns.engine,
+                               $ = ns.jqm.jQuery,
+                               eventType = ns.router.Router.eventType,
+                               jqmRouter = {
+                                       /**
+                                        * Enables support jQM before router init.
+                                        * @method beforeinit
+                                        * @member ns.jqm.router
+                                        */
+                                       beforeinit: function () {
+                                               var container,
+                                                       router = ns.router.Router.getInstance();
+
+                                               if ($) {
+                                                       if ($.mobile) {
+                                                               if ($.mobile.pageContainer) {
+                                                                       container = $.mobile.pageContainer;
+                                                                       if (container instanceof $) {
+                                                                               container = container[0];
+                                                                       }
+                                                                       if (!(container instanceof HTMLElement)) {
+                                                                               container = document.body;
+                                                                       }
+                                                                       ns.setConfig("pageContainer", container);
+                                                                       $.mobile.pageContainer = $(container);
+                                                               }
+                                                               if ($.mobile.autoInitializePage !== undefined) {
+                                                                       ns.setConfig("autoInitializePage", $.mobile.autoInitializePage);
+                                                               }
+                                                               if ($.mobile._bindPageRemove !== undefined) {
+                                                                       ns.setConfig("_bindPageRemove", $.mobile._bindPageRemove);
+                                                               }
+                                                               $.mobile.changePage = function (toPage, options) {
+                                                                       var htmlElementToPage;
+
+                                                                       if (toPage instanceof $) {
+                                                                               htmlElementToPage = $(toPage).get(0);
+                                                                               return router.open(htmlElementToPage, options);
+                                                                       }
+                                                                       return router.open(toPage, options);
+                                                               };
+                                                               document.addEventListener("pagechange", function () {
+                                                                       var route = router.getRoute("page"),
+                                                                               activePage = route && route.getActive(),
+                                                                               target = activePage && activePage.element;
+
+                                                                       $.mobile.activePage = $(target);
+                                                               }, true);
+                                                               $.mobile.activePage = $();
+                                                               $.mobile.firstPage = $(router.getRoute("page").getFirstElement());
+                                                               $.mobile.pageContainer = $();
+                                                               $.mobile.subPageUrlKey = ns.widget.core.Page.classes.uiPage;
+                                                               $.mobile.ajaxEnabled = true;
+                                                               $.mobile.hashListeningEnabled = true;
+                                                               $.mobile.linkBindingEnabled = true;
+                                                               $.mobile.maxTransitionWidth = false;
+                                                               $.mobile.minScrollBack = 250;
+                                                               $.mobile.touchOverflowEnabled = false;
+                                                               $.mobile.defaultDialogTransition = "pop";
+                                                               $.mobile.pageLoadErrorMessage = "Error Loading Page";
+                                                               $.mobile.pageLoadErrorMessageTheme = "e";
+                                                               $.mobile.phonegapNavigationEnabled = false;
+                                                               $.mobile.autoInitializePage = false;
+                                                               $.mobile.pushStateEnabled = true;
+                                                               $.mobile.ignoreContentEnabled = false;
+                                                               $.mobile.orientationChangeEnabled = true;
+                                                               $.mobile.ajaxBlacklist = false;
+                                                               $.mobile.defaultTransitionHandler = null;
+                                                               $.mobile.transitionHandlers = {};
+                                                               $.mobile.transitionFallbacks = {};
+                                                               $.mobile._maybeDegradeTransition = null;
+                                                               $.mobile.focusPage = null;
+                                                               //$.mobile.urlHistory = ns.router.urlHistory;
+                                                               $.mobile.dialogHashKey = "&ui-state=dialog";
+                                                               $.mobile.allowCrossDomainPages = false;
+                                                               $.mobile.getDocumentUrl = ns.util.path.getDocumentUrl;
+                                                               $.mobile.getDocumentBase = ns.util.path.getDocumentBase;
+                                                               $.mobile._bindPageRemove = null;
+                                                               $.mobile.loadPage = router.loadPage === undefined ? ns.error.bind(null, "router PageExternal is not loaded") : router.loadPage.bind(router);
+                                                               $.mobile.navreadyDeferred = router.navreadyDeferred;
+                                                               $.mobile.initializePage = null;
+                                                               $.mobile._handleHashChange = router._hashChangeHandler;
+                                                       } else {
+                                                               $.mobile = {};
+                                                       }
+                                               }
+                                       },
+                                       /**
+                                        * Enables support jQM after router init.
+                                        * @method init
+                                        * @member ns.jqm.router
+                                        */
+                                       init: function () {
+                                               var transitions,
+                                                       name,
+                                                       router = ns.router.Router.getInstance(),
+                                                       containerWidget;
+
+                                               if ($) {
+                                                       $.mobile.defaultPageTransition = "none";
+
+                                                       if (router.getTransitions) {
+                                                               transitions = router.getTransitions();
+                                                               for (name in transitions) {
+                                                                       if (transitions.hasOwnProperty(name)) {
+                                                                               if (transitions[name].fallback !== undefined) {
+                                                                                       $.mobile.transitionFallbacks[name] = transitions[name].fallback;
+                                                                               }
+                                                                               if (transitions[name].handler !== undefined) {
+                                                                                       $.mobile.transitionHandlers[name] = transitions[name].handler;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               $.mobile.defaultTransitionHandler = transitions.sequential.handler;
+                                                               $.mobile._maybeDegradeTransition = router._maybeDegradeTransition.bind(router);
+                                                               $.mobile.getMaxScrollForTransition = router.getMaxScrollForTransition.bind(router);
+                                                       }
+
+                                                       $.mobile.focusPage = function (toPage) {
+                                                               var page = $(toPage)[0],
+                                                                       pageWidget = engine.getBinding(page);
+
+                                                               pageWidget.focus();
+                                                       };
+
+                                                       $.mobile.initializePage = router.init.bind(router);
+                                                       containerWidget = router.getContainer();
+                                                       if (containerWidget) {
+                                                               $.mobile.pageContainer = $(containerWidget.element);
+                                                       }
+                                               }
+                                       },
+                                       destroy: function () {
+                                               document.removeEventListener(eventType.ROUTER_INIT, jqmRouter.init, false);
+                                               document.removeEventListener(eventType.BEFORE_ROUTER_INIT, jqmRouter.beforeinit, false);
+                                               document.removeEventListener(eventType.DESTROY, jqmRouter.destroy, false);
+                                       }
+                               };
+
+                       document.addEventListener(eventType.ROUTER_INIT, jqmRouter.init, false);
+                       document.addEventListener(eventType.BEFORE_ROUTER_INIT, jqmRouter.beforeinit, false);
+                       document.addEventListener(eventType.DESTROY, jqmRouter.destroy, false);
+
+                       ns.jqm.router = jqmRouter;
+                       }(window, window.document));
+
+/*global window, ns, define */
+/*jslint plusplus: true, nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #jQuery Mobile mapping support
+ * Object maps support object from TAU namespace to jQuery Mobile namespace.
+ * @class ns.jqm.support
+ */
+(function (window, document) {
+       "use strict";
+                               var support = ns.support,
+                               $ = ns.jqm.jQuery,
+                               object = ns.util.object,
+                               eventType = ns.engine.eventType,
+                               jqmSupport = {
+                                       /**
+                                        * Touch support flag
+                                        * @property {boolean} touch
+                                        * @member ns.jqm.support
+                                        */
+                                       touch: document.ontouchend !== undefined,
+                                       /**
+                                        * Enables support in jQM after TAU init
+                                        * @method init
+                                        * @member ns.jqm.support
+                                        */
+                                       init: function () {
+                                               var router = ns.router.Router.getInstance();
+
+                                               if ($) {
+                                                       ns.support = object.merge($.support, support);
+                                                       $.mobile = $.mobile || {};
+                                                       $.mobile.support = $.mobile.support || {};
+                                                       $.mobile.support.touch = support.touch;
+                                                       $.mobile.base = support.dynamicBaseTag && {
+                                                               element: router.resetBase === undefined ? ns.error.bind(null, "router PageExternal is not loaded") : router.resetBase(),
+                                                               set: router.setBase === undefined ? ns.error.bind(null, "router PageExternal is not loaded") : router.setBase.bind(router),
+                                                               reset: router.resetBase === undefined ? ns.error.bind(null, "router PageExternal is not loaded") : router.resetBase.bind(router)
+                                                       };
+                                                       $.mobile.gradeA = ns.support.gradeA.bind(ns.support);
+                                                       $.mobile.browser = ns.support.browser;
+                                               }
+                                       },
+                                       /**
+                                        * Removes events listeners on framework destroy
+                                        */
+                                       destroy: function () {
+                                               document.removeEventListener(eventType.INIT, jqmSupport.init, false);
+                                               document.removeEventListener(eventType.DESTROY, jqmSupport.destroy, false);
+                                       }
+                               };
+
+                       // Listen when framework is ready
+                       document.addEventListener(eventType.INIT, jqmSupport.init, false);
+                       document.addEventListener(eventType.DESTROY, jqmSupport.destroy, false);
+
+                       ns.jqm.support = jqmSupport;
+                       }(window, window.document));
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Colors Utility
+ * Class supports converting between color formats
+ * @class ns.util.colors
+ */
+
+(function (window, document, ns) {
+       "use strict";
+                               ns.util.colors = {
+                               /**
+                                * Round to the nearest Integer
+                                * @method nearestInt
+                                * @param {number} val
+                                * @return {number}
+                                * @member ns.util.colors
+                                * @static
+                                */
+                               nearestInt: function (val) {
+                                       var theFloor = Math.floor(val);
+
+                                       return (((val - theFloor) > 0.5) ? (theFloor + 1) : theFloor);
+                               },
+
+                               /**
+                                * Converts html color string to rgb array.
+                                * @method HTMLToRGB
+                                * @param {string} clrStr is of the form "#aabbcc"
+                                * @return {number[]} Returns: [ r, g, b ], where
+                                * r is in [0, 1]
+                                * g is in [0, 1]
+                                * b is in [0, 1]
+                                * @member ns.util.colors
+                                * @static
+                                */
+                               HTMLToRGB: function (clrStr) {
+                                       clrStr = (("#" === clrStr.charAt(0)) ? clrStr.substring(1) : clrStr);
+                                       return ([
+                                               clrStr.substring(0, 2),
+                                               clrStr.substring(2, 4),
+                                               clrStr.substring(4, 6)
+                                       ].map(function (val) {
+                                               return parseInt(val, 16) / 255.0;
+                                       }));
+                               },
+
+                               /**
+                                * Converts rgb array to html color string.
+                                * @method RGBToHTML
+                                * @param {number[]} rgb Input: [ r, g, b ], where
+                                * r is in [0, 1]
+                                * g is in [0, 1]
+                                * b is in [0, 1]
+                                * @return {string} Returns string of the form "#aabbcc"
+                                * @member ns.util.colors
+                                * @static
+                                */
+                               RGBToHTML: function (rgb) {
+                                       return ("#" +
+                                       rgb.map(function (val) {
+                                               var ret = val * 255,
+                                                       theFloor = Math.floor(ret);
+
+                                               ret = ((ret - theFloor > 0.5) ? (theFloor + 1) : theFloor);
+                                               ret = (((ret < 16) ? "0" : "") + (ret & 0xff).toString(16));
+                                               return ret;
+                                       })
+                                               .join(""));
+                               },
+
+                               /**
+                                * Converts hsl to rgb.
+                                * @method HSLToRGB
+                                * @param {number[]} hsl Input: [ h, s, l ], where
+                                * h is in [0, 360]
+                                * s is in [0,   1]
+                                * l is in [0,   1]
+                                * @return {number[]} Returns: [ r, g, b ], where
+                                * r is in [0, 1]
+                                * g is in [0, 1]
+                                * b is in [0, 1]
+                                * @member ns.util.colors
+                                * @static
+                                */
+                               HSLToRGB: function (hsl) {
+                                       var h = hsl[0] / 360.0,
+                                               s = hsl[1],
+                                               l = hsl[2],
+                                               temp1,
+                                               temp2,
+                                               temp3,
+                                               ret;
+
+                                       if (0 === s) {
+                                               ret = [l, l, l];
+                                       } else {
+                                               temp2 = ((l < 0.5) ? l * (1.0 + s) : l + s - l * s);
+                                               temp1 = 2.0 * l - temp2;
+                                               temp3 = {
+                                                       r: h + 1.0 / 3.0,
+                                                       g: h,
+                                                       b: h - 1.0 / 3.0
+                                               };
+
+                                               temp3.r = ((temp3.r < 0) ? (temp3.r + 1.0) : ((temp3.r > 1) ? (temp3.r - 1.0) : temp3.r));
+                                               temp3.g = ((temp3.g < 0) ? (temp3.g + 1.0) : ((temp3.g > 1) ? (temp3.g - 1.0) : temp3.g));
+                                               temp3.b = ((temp3.b < 0) ? (temp3.b + 1.0) : ((temp3.b > 1) ? (temp3.b - 1.0) : temp3.b));
+
+                                               ret = [
+                                                       (((6.0 * temp3.r) < 1) ? (temp1 + (temp2 - temp1) * 6.0 * temp3.r) :
+                                                               (((2.0 * temp3.r) < 1) ? temp2 :
+                                                                       (((3.0 * temp3.r) < 2) ? (temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp3.r) * 6.0) :
+                                                                               temp1))),
+                                                       (((6.0 * temp3.g) < 1) ? (temp1 + (temp2 - temp1) * 6.0 * temp3.g) :
+                                                               (((2.0 * temp3.g) < 1) ? temp2 :
+                                                                       (((3.0 * temp3.g) < 2) ? (temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp3.g) * 6.0) :
+                                                                               temp1))),
+                                                       (((6.0 * temp3.b) < 1) ? (temp1 + (temp2 - temp1) * 6.0 * temp3.b) :
+                                                               (((2.0 * temp3.b) < 1) ? temp2 :
+                                                                       (((3.0 * temp3.b) < 2) ? (temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp3.b) * 6.0) :
+                                                                               temp1)))
+                                               ];
+                                       }
+
+                                       return ret;
+                               },
+
+                               /**
+                                * Converts hsv to rgb.
+                                * @method HSVToRGB
+                                * @param {number[]} hsv Input: [ h, s, v ], where
+                                * h is in [0, 360]
+                                * s is in [0,   1]
+                                * v is in [0,   1]
+                                * @return {number[]} Returns: [ r, g, b ], where
+                                * r is in [0, 1]
+                                * g is in [0, 1]
+                                * b is in [0, 1]
+                                * @member ns.util.colors
+                                */
+                               HSVToRGB: function (hsv) {
+                                       return this.HSLToRGB(this.HSVToHSL(hsv));
+                               },
+
+                               /**
+                                * Converts rgb to hsv.
+                                * @method HSVToRGB
+                                * @param {number[]} rgb Input: [ r, g, b ], where
+                                * r is in [0,   1]
+                                * g is in [0,   1]
+                                * b is in [0,   1]
+                                * @return {number[]} Returns: [ h, s, v ], where
+                                * h is in [0, 360]
+                                * s is in [0,   1]
+                                * v is in [0,   1]
+                                * @member ns.util.colors
+                                * @static
+                                */
+                               RGBToHSV: function (rgb) {
+                                       var min,
+                                               max,
+                                               delta,
+                                               h,
+                                               s,
+                                               v,
+                                               r = rgb[0],
+                                               g = rgb[1],
+                                               b = rgb[2];
+
+                                       min = Math.min(r, Math.min(g, b));
+                                       max = Math.max(r, Math.max(g, b));
+                                       delta = max - min;
+
+                                       h = 0;
+                                       s = 0;
+                                       v = max;
+
+                                       if (delta > 0.00001) {
+                                               s = delta / max;
+
+                                               if (r === max) {
+                                                       h = (g - b) / delta;
+                                               } else {
+                                                       if (g === max) {
+                                                               h = 2 + (b - r) / delta;
+                                                       } else {
+                                                               h = 4 + (r - g) / delta;
+                                                       }
+                                               }
+
+                                               h *= 60;
+
+                                               if (h < 0) {
+                                                       h += 360;
+                                               }
+                                       }
+
+                                       return [h, s, v];
+                               },
+
+                               /**
+                                * Converts Converts hsv to hsl.
+                                * @method HSVToHSL
+                                * @param {number[]} hsv Input: [ h, s, v ], where
+                                * h is in [0, 360]
+                                * s is in [0,   1]
+                                * v is in [0,   1]
+                                * @return {number[]} Returns: [ h, s, l ], where
+                                * h is in [0, 360]
+                                * s is in [0,   1]
+                                * l is in [0,   1]
+                                * @member ns.util.colors
+                                * @static
+                                */
+                               HSVToHSL: function (hsv) {
+                                       var max = hsv[2],
+                                               delta = hsv[1] * max,
+                                               min = max - delta,
+                                               sum = max + min,
+                                               halfSum = sum / 2,
+                                               sDivisor = ((halfSum < 0.5) ? sum : (2 - max - min));
+
+                                       return [hsv[0], ((0 === sDivisor) ? 0 : (delta / sDivisor)), halfSum];
+                               },
+
+                               /**
+                                * Converts rgb to hsl
+                                * @method RGBToHSL
+                                * @param {number[]} rgb Input: [ r, g, b ], where
+                                * r is in [0,   1]
+                                * g is in [0,   1]
+                                * b is in [0,   1]
+                                * @return {number[]} Returns: [ h, s, l ], where
+                                * h is in [0, 360]
+                                * s is in [0,   1]
+                                * l is in [0,   1]
+                                * @member ns.util.colors
+                                */
+                               RGBToHSL: function (rgb) {
+                                       return this.HSVToHSL(this.RGBToHSV(rgb));
+                               }
+                       };
+                       }(window, window.document, ns));
+
+/*global window, ns, define */
+/*jslint plusplus: true, nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #jQuery Mobile mapping colors
+ * Object maps color support object from TAU namespace to
+ * jQuery Mobile namespace.
+ * @class ns.jqm.colors
+ */
+(function (document) {
+       "use strict";
+                               var eventType = ns.engine.eventType,
+                               $ = ns.jqm.jQuery,
+                               colors = {
+                                       /**
+                                        * Initializes colors util in jQueryMobile namespace
+                                        */
+                                       init: function () {
+                                               if ($) {
+                                                       $.mobile.tizen.clrlib = colors;
+                                               }
+                                       },
+
+                                       /**
+                                        * Destroys colors util in jQueryMobile namespace
+                                        */
+                                       destroy: function () {
+                                               document.removeEventListener(eventType.INIT, colors.init, false);
+                                               document.removeEventListener(eventType.DESTROY, colors.destroy, false);
+                                               if ($) {
+                                                       delete $.mobile.tizen.clrlib;
+                                               }
+                                               window.ns = null;
+                                               $ = null;
+                                               eventType = null;
+                                               colors = null;
+                                       }
+                               };
+
+                       // Listen when framework is ready
+                       document.addEventListener(eventType.INIT, colors.init, false);
+                       document.addEventListener(eventType.DESTROY, colors.destroy, false);
+
+                       }(window.document));
+
+/*global define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Anchor Highlight Utility
+ *
+ * Utility enables highlight on clickable components.
+ * @class ns.util.anchorHighlight
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Damian Osipiuk <d.osipiuk@samsung.com>
+ * @author Konrad Lipner <k.lipner@samsung.com>
+ */
+(function (document, window, ns) {
+       "use strict";
+                               /* anchorHighlightController.js
+                        To prevent performance regression when scrolling,
+                        do not apply hover class in anchor.
+                        Instead, this code checks scrolling for time threshold and
+                        decide how to handle the color.
+                        When scrolling with anchor, it checks flag and decide to highlight anchor.
+                        While it helps to improve scroll performance,
+                        it lowers responsiveness of the element for 50msec.
+                        */
+
+                       /**
+                        * Touch start x
+                        * @property {number} startX
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       var startX = 0,
+                               /**
+                                * Touch start y
+                                * @property {number} startY
+                                * @member ns.util.anchorHighlight
+                                * @private
+                                * @static
+                                */
+                               startY = 0,
+                               /**
+                                * Touch target element
+                                * @property {HTMLElement} target
+                                * @member ns.util.anchorHighlight
+                                * @private
+                                * @static
+                                */
+                               classes = {
+                                       /**
+                                        * Class used to mark element as active
+                                        * @property {string} [classes.ACTIVE_LI="ui-li-active"]
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       ACTIVE_LI: "ui-li-active",
+                                       /**
+                                        * Class used to mark button as active
+                                        * @property {string} [classes.ACTIVE_BTN="ui-btn-active"]
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       ACTIVE_BTN: "ui-btn-active",
+                                       /**
+                                        * Class used to mark button as inactive
+                                        * @property {string} [classes.INACTIVE_BTN="ui-btn-inactive"]
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       INACTIVE_BTN: "ui-btn-inactive",
+                                       /**
+                                        * Class used to select button
+                                        * @property {string} [classes.BUTTON="ui-btn"] btn
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       BUTTON: "ui-btn",
+                                       /**
+                                        * Class used to select button in header (old notation)
+                                        * @property {string} [classes.HEADER_BUTTON="ui-header-btn"] btn
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       HEADER_BUTTON: "ui-header-btn",
+                                       /**
+                                        * Class used to select anchor in sub-tab widget
+                                        * @property {string} [classes.SUBTAB_ANCHOR="ui-sub-tab-anchor"] anchor
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       SUBTAB_ANCHOR: "ui-sub-tab-anchor",
+                                       /**
+                                        * Class used to select navigation item
+                                        * @property {string} [classes.NAVIGATION_BUTTON="ui-navigation-item"] btn
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       NAVIGATION_BUTTON: "ui-navigation-item"
+                               },
+                               events = {
+                                       ACTIVE_LI: "anchorhighlightactiveli"
+                               },
+                               /**
+                                * Alias for class {@link ns.util.selectors}
+                                * @property {Object} selectors
+                                * @member ns.util.anchorHighlight
+                                * @private
+                                * @static
+                                */
+                               selectors = ns.util.selectors,
+                               /**
+                                * Alias for class {@link ns.event}
+                                * @property {Object} event
+                                * @member ns.util.anchorHighlight
+                                * @private
+                                * @static
+                                */
+                               eventUtil = ns.event,
+
+                               // cache function
+                               abs = Math.abs,
+
+                               /**
+                                * Get closest li element
+                                * @method detectLiElement
+                                * @param {HTMLElement} target
+                                * @return {HTMLElement}
+                                * @member ns.util.anchorHighlight
+                                * @private
+                                * @static
+                                */
+                               detectLiElement = function (target) {
+                                       return selectors.getClosestByTag(target, "li");
+                               },
+
+                               anchorHighlight = {
+                                       /**
+                                        * Object with default options
+                                        * @property {Object} options
+                                        * Threshold after which didScroll will be set
+                                        * @property {number} [options.scrollThreshold=10]
+                                        * Time to wait before adding activeClass
+                                        * @property {number} [options.addActiveClassDelay=50]
+                                        * Time to stay activeClass after touch end
+                                        * @property {number} [options.keepActiveClassDelay=100]
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       options: {
+                                               scrollThreshold: 10,
+                                               addActiveClassDelay: 50,
+                                               keepActiveClassDelay: 100
+                                       },
+                                       _startTime: 0,
+                                       _startRemoveTime: 0,
+                                       // inform that touch was ended
+                                       _touchEnd: false,
+                                       _liTarget: null,
+
+                                       /**
+                                        * Touch button target element
+                                        * @property {HTMLElement} buttonTarget
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       _target: null,
+                                       /**
+                                        * Did page scrolled
+                                        * @property {boolean} didScroll
+                                        * @member ns.util.anchorHighlight
+                                        * @private
+                                        * @static
+                                        */
+                                       _didScroll: false,
+                                       _buttonTarget: null,
+                                       // inform that animation of button's activation was ended
+                                       _activeAnimationFinished: false,
+                                       //cache function
+                                       _requestAnimationFrame: ns.util.windowRequestAnimationFrame
+                               },
+
+                               // cache function
+                               slice = Array.prototype.slice;
+
+
+                       /**
+                        * Get closest highlightable element
+                        * @method detectHighlightTarget
+                        * @param {HTMLElement} target
+                        * @return {HTMLElement}
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function detectHighlightTarget(target) {
+                               return selectors.getClosestBySelector(target, "a, label");
+                       }
+
+                       /**
+                        * Get closest button element
+                        * @method detectBtnElement
+                        * @param {HTMLElement} target
+                        * @return {HTMLElement}
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function detectBtnElement(target) {
+                               return selectors.getClosestByClass(target, classes.BUTTON) ||
+                                       selectors.getClosestByClass(target, classes.HEADER_BUTTON) ||
+                                       selectors.getClosestByClass(target, classes.NAVIGATION_BUTTON) ||
+                                       selectors.getClosestByClass(target, classes.SUBTAB_ANCHOR);
+                       }
+
+                       /**
+                        * Clear active class on button
+                        * @method clearBtnActiveClass
+                        * @param {Event} event
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function clearBtnActiveClass(event) {
+                               var target = event.target,
+                                       classList = target.classList;
+                               // if this is callback of activate animation and
+
+                               if (classList.contains(classes.ACTIVE_BTN) && !classList.contains(classes.INACTIVE_BTN)) {
+                                       // set that animation was ended (used in touch end)
+                                       anchorHighlight._activeAnimationFinished = true;
+
+                                       // if touch end previously
+                                       if (anchorHighlight._touchEnd || target !== anchorHighlight._buttonTarget) {
+                                               // start inactivate animation
+                                               classList.add(classes.INACTIVE_BTN);
+                                       }
+                               } else {
+                                       //when target of animationend event is child of active element instead of active element
+                                       // itself
+                                       if (!classList.contains(classes.ACTIVE_BTN) &&
+                                               !classList.contains(classes.INACTIVE_BTN)) {
+                                               target.parentNode.classList.remove(classes.ACTIVE_BTN);
+                                               target.parentNode.classList.remove(classes.INACTIVE_BTN);
+                                       }
+                                       // this is callback for inactive animation end
+                                       classList.remove(classes.INACTIVE_BTN);
+                                       classList.remove(classes.ACTIVE_BTN);
+                               }
+                       }
+
+                       /**
+                        * Add inactive class on touch end
+                        * @method addButtonInactiveClass
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function addButtonInactiveClass() {
+                               if (anchorHighlight._buttonTarget) {
+                                       anchorHighlight._buttonTarget.classList.add(classes.INACTIVE_BTN);
+                                       anchorHighlight._buttonTarget.classList.remove(classes.ACTIVE_BTN);
+                               }
+                       }
+
+                       /**
+                        * Add active class on touch end
+                        * @method addButtonActiveClass
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function addButtonActiveClass() {
+                               anchorHighlight._buttonTarget.classList.add(classes.ACTIVE_BTN);
+                               anchorHighlight._activeAnimationFinished = false;
+                       }
+
+                       /**
+                        * Clear classes on page or popup hide
+                        * @method hideClear
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function hideClear() {
+                               var btnTarget = anchorHighlight._buttonTarget;
+
+                               if (btnTarget) {
+                                       btnTarget.classList.remove(classes.ACTIVE_BTN);
+                                       btnTarget.classList.remove(classes.INACTIVE_BTN);
+                               }
+                               if (anchorHighlight._target) {
+                                       anchorHighlight._target.classList.remove(classes.ACTIVE_LI);
+                               }
+                       }
+
+                       /**
+                        * Add active class to touched element
+                        * @method addActiveClass
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function addActiveClass() {
+                               var btnTargetClassList,
+                                       dTime;
+
+                               if (anchorHighlight._startTime) {
+                                       dTime = Date.now() - anchorHighlight._startTime;
+
+                                       if (dTime > anchorHighlight.options.addActiveClassDelay) {
+                                               anchorHighlight._startTime = 0;
+                                               anchorHighlight._buttonTarget = detectBtnElement(anchorHighlight._target);
+                                               anchorHighlight._target = detectHighlightTarget(anchorHighlight._target);
+                                               if (!anchorHighlight._didScroll) {
+                                                       anchorHighlight._liTarget = anchorHighlight._detectLiElement(anchorHighlight._target);
+                                                       if (!anchorHighlight._buttonTarget) {
+                                                               // add press effect to LI element
+                                                               if (anchorHighlight._liTarget) {
+                                                                       anchorHighlight._liTarget.classList.add(classes.ACTIVE_LI);
+                                                                       eventUtil.trigger(anchorHighlight._liTarget, events.ACTIVE_LI, {});
+                                                               }
+                                                       } else {
+                                                               // add press effect to button
+                                                               btnTargetClassList = anchorHighlight._buttonTarget.classList;
+                                                               btnTargetClassList.remove(classes.ACTIVE_BTN);
+                                                               btnTargetClassList.remove(classes.INACTIVE_BTN);
+                                                               anchorHighlight._requestAnimationFrame(addButtonActiveClass);
+                                                       }
+                                               }
+                                       } else {
+                                               anchorHighlight._requestAnimationFrame(addActiveClass);
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Get all active elements
+                        * @method getActiveElements
+                        * @return {Array}
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function getActiveElements() {
+                               return slice.call(document.getElementsByClassName(classes.ACTIVE_LI));
+                       }
+
+                       /**
+                        * Remove active class from current active objects
+                        * @method clearActiveClass
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function clearActiveClass() {
+                               var activeA = getActiveElements(),
+                                       activeALength = activeA.length,
+                                       i = 0;
+
+                               for (; i < activeALength; i++) {
+                                       activeA[i].classList.remove(classes.ACTIVE_LI);
+                               }
+                       }
+
+                       /**
+                        * Remove active class from active elements
+                        * @method removeActiveClass
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function removeActiveClassLoop() {
+                               var dTime = Date.now() - anchorHighlight._startRemoveTime;
+
+                               if (dTime > anchorHighlight.options.keepActiveClassDelay) {
+                                       // after touchend
+                                       clearActiveClass();
+                               } else {
+                                       anchorHighlight._requestAnimationFrame(removeActiveClassLoop);
+                               }
+                       }
+
+                       /**
+                        * Function invoked during touch move (and mouse)
+                        * @method touchmoveHandler
+                        * @param {Event} event
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function touchmoveHandler(event) {
+                               var touch = event.touches[0],
+                                       scrollThreshold = anchorHighlight.options.scrollThreshold;
+
+                               // if move looks like scroll
+                               if (!anchorHighlight._didScroll &&
+                                       // if move is bigger then threshold
+                                       (abs(touch.clientX - startX) > scrollThreshold ||
+                                       abs(touch.clientY - startY) > scrollThreshold)) {
+                                       anchorHighlight._startTime = 0;
+                                       // we clear active classes
+                                       anchorHighlight._requestAnimationFrame(clearActiveClass);
+                                       anchorHighlight._didScroll = true;
+                               }
+                       }
+
+                       /**
+                        * Function invoked after touch start (and mouse)
+                        * @method touchstartHandler
+                        * @param {Event} event
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function touchstartHandler(event) {
+                               var touches = event.touches,
+                                       pointer = (!touches) ? event : // mouse event
+                                               (touches.length === 1) ? touches[0] : null; // touch event
+
+                               if (pointer) {
+                                       anchorHighlight._didScroll = false;
+                                       startX = pointer.clientX;
+                                       startY = pointer.clientY;
+                                       anchorHighlight._target = event.target;
+                                       anchorHighlight._startTime = Date.now();
+                                       anchorHighlight._startRemoveTime = 0;
+                                       anchorHighlight._requestAnimationFrame(addActiveClass);
+                                       anchorHighlight._touchEnd = false;
+                               }
+                       }
+
+
+                       /**
+                        * Function invoked after touch (and mouse)
+                        * @method touchendHandler
+                        * @param {Event} event
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function touchendHandler(event) {
+                               anchorHighlight._startRemoveTime = event.timeStamp;
+
+                               if (!event.touches || event.touches && event.touches.length === 0) {
+                                       if (!anchorHighlight._didScroll) {
+                                               anchorHighlight._startTime = 0;
+                                               anchorHighlight._requestAnimationFrame(removeActiveClassLoop);
+                                       }
+                                       // if we finished activate animation then start inactive animation
+                                       if (anchorHighlight._activeAnimationFinished) {
+                                               anchorHighlight._requestAnimationFrame(addButtonInactiveClass);
+                                       }
+                                       anchorHighlight._didScroll = false;
+                                       anchorHighlight._touchEnd = true;
+                               }
+                       }
+
+                       /**
+                        * Function invoked after visibilitychange event
+                        * @method checkPageVisibility
+                        * @member ns.util.anchorHighlight
+                        * @private
+                        * @static
+                        */
+                       function checkPageVisibility() {
+                               /* istanbul ignore if  */
+                               if (document.visibilityState === "hidden") {
+                                       anchorHighlight._removeActiveClassLoop();
+                               }
+                       }
+
+                       ns.util.anchorHighlight = anchorHighlight;
+                       anchorHighlight.enable = enable;
+                       anchorHighlight.disable = disable;
+                       anchorHighlight._clearActiveClass = clearActiveClass;
+                       anchorHighlight._detectHighlightTarget = detectHighlightTarget;
+                       anchorHighlight._detectBtnElement = detectBtnElement;
+                       anchorHighlight._removeActiveClassLoop = removeActiveClassLoop;
+                       anchorHighlight._addButtonInactiveClass = addButtonInactiveClass;
+                       anchorHighlight._addButtonActiveClass = addButtonActiveClass;
+                       anchorHighlight._addActiveClass = addActiveClass;
+                       anchorHighlight._detectLiElement = detectLiElement;
+                       anchorHighlight._touchmoveHandler = touchmoveHandler;
+                       anchorHighlight._touchendHandler = touchendHandler;
+                       anchorHighlight._touchstartHandler = touchstartHandler;
+                       anchorHighlight._checkPageVisibility = checkPageVisibility;
+                       anchorHighlight._hideClear = hideClear;
+                       anchorHighlight._clearBtnActiveClass = clearBtnActiveClass;
+
+                       /**
+                        * Bind events to document
+                        * @method enable
+                        * @member ns.util.anchorHighlight
+                        * @static
+                        */
+                       function enable() {
+                               document.addEventListener("touchstart", anchorHighlight._touchstartHandler, false);
+                               document.addEventListener("touchend", anchorHighlight._touchendHandler, false);
+                               document.addEventListener("touchmove", anchorHighlight._touchmoveHandler, false);
+                               // for TAU in browser
+                               document.addEventListener("mousedown", anchorHighlight._touchstartHandler, false);
+                               document.addEventListener("mouseup", anchorHighlight._touchendHandler, false);
+
+                               document.addEventListener("visibilitychange", anchorHighlight._checkPageVisibility, false);
+                               document.addEventListener("pagehide", anchorHighlight._hideClear, false);
+                               document.addEventListener("popuphide", anchorHighlight._hideClear, false);
+                               document.addEventListener("animationend", anchorHighlight._clearBtnActiveClass, false);
+                               document.addEventListener("animationEnd", anchorHighlight._clearBtnActiveClass, false);
+                               document.addEventListener("webkitAnimationEnd", anchorHighlight._clearBtnActiveClass,
+                                       false);
+                       }
+
+                       /**
+                        * Unbinds events from document.
+                        * @method disable
+                        * @member ns.util.anchorHighlight
+                        * @static
+                        */
+                       function disable() {
+                               document.removeEventListener("touchstart", anchorHighlight._touchstartHandler, false);
+                               document.removeEventListener("touchend", anchorHighlight._touchendHandler, false);
+                               document.removeEventListener("touchmove", anchorHighlight._touchmoveHandler, false);
+                               // for TAU in browser
+                               document.removeEventListener("mousedown", anchorHighlight._touchstartHandler, false);
+                               document.removeEventListener("mouseup", anchorHighlight._touchendHandler, false);
+
+                               document.removeEventListener("visibilitychange", anchorHighlight._checkPageVisibility,
+                                       false);
+                               document.removeEventListener("pagehide", anchorHighlight._hideClear, false);
+                               document.removeEventListener("popuphide", anchorHighlight._hideClear, false);
+                               document.removeEventListener("animationend", anchorHighlight._clearBtnActiveClass, false);
+                               document.removeEventListener("animationEnd", anchorHighlight._clearBtnActiveClass, false);
+                               document.removeEventListener("webkitAnimationEnd", anchorHighlight._clearBtnActiveClass,
+                                       false);
+                       }
+
+                       enable();
+
+                       }(document, window, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Grid Utility
+ * Object helps creating grids.
+ * @class ns.util.grid
+ */
+(function (ns) {
+       "use strict";
+                               /**
+                        * Local alias for ns.util.selectors
+                        * @property {Object} selectors Alias for {@link ns.util.selectors}
+                        * @member ns.util.grid
+                        * @static
+                        * @private
+                        */
+                       var selectors = ns.util.selectors,
+                               /**
+                                * Alias to Array.slice method
+                                * @method slice
+                                * @member ns.util.grid
+                                * @private
+                                * @static
+                                */
+                               slice = [].slice,
+                               /**
+                                * grid types
+                                * @property {Array} gridTypes
+                                * @member ns.util.grid
+                                * @static
+                                * @private
+                                */
+                               gridTypes = [
+                                       null,
+                                       "solo", //1
+                                       "a",    //2
+                                       "b",    //3
+                                       "c",    //4
+                                       "d"     //5
+                               ];
+
+                       /**
+                        * Add classes on the matched elements
+                        * @method setClassOnMatches
+                        * @param {HTMLElementCollection} elements
+                        * @param {string} selector
+                        * @param {string} className
+                        * @private
+                        * @member ns.util.grid
+                        * @static
+                        */
+                       function setClassOnMatches(elements, selector, className) {
+                               elements.forEach(function (item) {
+                                       if (selectors.matchesSelector(item, selector)) {
+                                               item.classList.add(className);
+                                       }
+                               });
+                       }
+
+                       ns.util.grid = {
+                               /**
+                                * make css grid
+                                * @method makeGrid
+                                * @param {HTMLElement} element
+                                * @param {?string} [gridType="a"]
+                                * @static
+                                * @member ns.util.grid
+                                */
+                               makeGrid: function (element, gridType) {
+                                       var gridClassList = element.classList,
+                                               kids = slice.call(element.children),
+                                               iterator;
+
+                                       if (!gridType) {
+                                               gridType = gridTypes[kids.length];
+                                               if (!gridType) {
+                                                       //if gridType is not defined in gritTypes
+                                                       //make it grid type "a""
+                                                       gridType = "a";
+                                                       iterator = 2;
+                                                       gridClassList.add("ui-grid-duo");
+                                               }
+                                       }
+                                       if (!iterator) {
+                                               //jquery grid doesn't care if someone gives non-existing gridType
+                                               iterator = gridTypes.indexOf(gridType);
+                                       }
+
+                                       gridClassList.add("ui-grid-" + gridType);
+
+                                       setClassOnMatches(kids, ":nth-child(" + iterator + "n+1)", "ui-block-a");
+
+                                       if (iterator > 1) {
+                                               setClassOnMatches(kids, ":nth-child(" + iterator + "n+2)", "ui-block-b");
+                                       }
+                                       if (iterator > 2) {
+                                               setClassOnMatches(kids, ":nth-child(" + iterator + "n+3)", "ui-block-c");
+                                       }
+                                       if (iterator > 3) {
+                                               setClassOnMatches(kids, ":nth-child(" + iterator + "n+4)", "ui-block-d");
+                                       }
+                                       if (iterator > 4) {
+                                               setClassOnMatches(kids, ":nth-child(" + iterator + "n+5)", "ui-block-e");
+                                       }
+                               }
+                       };
+                       }(ns));
+
+/*global window, ns, define, Object, Element, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Data Attributes Utility
+ * Object menages data attributes
+ * @class ns.util.data
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var hashMap = {},
+                               eventUtils = ns.event,
+                               objectUtils = ns.util.object,
+                               body = document.body,
+                               /**
+                                * Return hash for object
+                                * @method fetchDom
+                                * @param {HTMLElement} element
+                                * @param {string} key
+                                * @return {?Object}
+                                * @member ns.util.data
+                                * @static
+                                * @private
+                                */
+                               fetchDom = function (element, key) {
+                                       var dataKey = "data-" + key,
+                                               data,
+                                               result;
+
+                                       if (element.hasAttribute(dataKey)) {
+                                               data = element.getAttribute(dataKey);
+                                               try {
+                                                       result = JSON.parse(data);
+                                               } catch (ignore) {
+                                               }
+                                       }
+                                       return result;
+                               },
+                               /**
+                                * Remove attribute from element
+                                * @method removeDom
+                                * @param {HTMLElement} element
+                                * @param {string} key
+                                * @member ns.util.data
+                                * @static
+                                * @private
+                                */
+                               removeDom = function (element, key) {
+                                       var dataKey = "data-" + key;
+
+                                       if (element.hasAttribute(dataKey)) {
+                                               element.removeAttribute(dataKey);
+                                       }
+                               },
+                               /**
+                                * Return hash for object
+                                * @method hashObject
+                                * @param {*} value
+                                * @return {string}
+                                * @member ns.util.data
+                                * @static
+                                * @private
+                                */
+                               hashObject = function (value) {
+                                       var hash;
+
+                                       if (value === undefined ||
+                                               value === null ||
+                                               value === false) {
+                                               throw "Hashed object/primitive can not be undefined, null or false";
+                                       }
+
+                                       if (value instanceof Element && value.hasAttribute("data-ns-hash")) {
+                                               return value.getAttribute("data-ns-hash");
+                                       }
+
+                                       if (value instanceof Object) {
+                                               value.__tauHash = value.__tauHash || ns.getUniqueId();
+                                       }
+                                       hash = (typeof value) + "-" + (value instanceof Object ?
+                                               value.__tauHash : value.toString());
+
+                                       if (value instanceof Element) {
+                                               value.setAttribute("data-ns-hash", hash);
+                                       }
+                                       return hash;
+                               };
+
+                       ns.util.data = {
+                               /**
+                                * Set value for element
+                                * @method set
+                                * @param {HTMLElement} element
+                                * @param {string} key
+                                * @param {*} value
+                                * @return {*}
+                                * @member ns.util.data
+                                * @static
+                                */
+                               set: function (element, key, value) {
+                                       var hash = hashObject(element);
+
+                                       if (!hash) {
+                                               return false;
+                                       }
+
+                                       if (!hashMap[hash]) {
+                                               hashMap[hash] = {};
+                                       }
+
+                                       hashMap[hash][key] = value;
+
+                                       if (element instanceof Element) {
+                                               eventUtils.trigger(element, "setData", {
+                                                       "key": key,
+                                                       "value": value
+                                               });
+                                       }
+                                       eventUtils.trigger(body, "globalSetData", {
+                                               "element": element,
+                                               "key": key,
+                                               "value": value
+                                       });
+
+                                       return value;
+                               },
+
+                               /**
+                                * Get value for element
+                                * @method get
+                                * @param {HTMLElement} element
+                                * @param {string} key
+                                * @param {?*} defaultValue
+                                * @return {Mixed}
+                                * @member ns.util.data
+                                * @static
+                                */
+                               get: function (element, key, defaultValue) {
+                                       var hash = hashObject(element),
+                                               value;
+
+                                       if (hash) {
+                                               if (hashMap[hash] && hashMap[hash][key] !== undefined) {
+                                                       value = hashMap[hash][key];
+                                               }
+
+                                               if (element instanceof Element) {
+                                                       if (value === undefined) {
+                                                               value = fetchDom(element, key);
+                                                               // pass it to memory HashMap
+                                                               hashMap[hash] = hashMap[hash] || {};
+                                                               hashMap[hash][key] = hashMap[hash][key] || value;
+                                                       }
+                                                       eventUtils.trigger(element, "getData", {
+                                                               "key": key,
+                                                               "value": value
+                                                       });
+                                               }
+                                               eventUtils.trigger(body, "globalGetData", {
+                                                       "element": element,
+                                                       "key": key,
+                                                       "value": value
+                                               });
+
+                                               return value;
+                                       }
+
+                                       return defaultValue;
+                               },
+
+                               /**
+                                * remove value for element
+                                * @method remove
+                                * @param {HTMLElement} element
+                                * @param {string} key
+                                * @return {boolean}
+                                * @member ns.util.data
+                                * @static
+                                */
+                               remove: function (element, key) {
+                                       var hash = hashObject(element),
+                                               value;
+
+                                       if (hash && hashMap[hash] && hashMap[hash][key] !== undefined) {
+                                               value = hashMap[hash][key];
+
+                                               // Delete keyword has a performance impact on the execution, that's why we assign
+                                               // undefined
+                                               hashMap[hash][key] = undefined;
+
+                                               // If any property is defined we cannot clear the hashMap[hash]
+                                               if (objectUtils.hasPropertiesOfValue(hashMap[hash], undefined)) {
+                                                       hashMap[hash] = undefined;
+                                               }
+
+                                               if (element instanceof Element) {
+                                                       removeDom(element, key);
+                                                       eventUtils.trigger(element, "removeData", {
+                                                               "key": key,
+                                                               "value": value
+                                                       });
+                                               }
+                                               eventUtils.trigger(body, "globalRemoveData", {
+                                                       "element": element,
+                                                       "key": key,
+                                                       "value": value
+                                               });
+
+                                               return true;
+                                       }
+                                       return false;
+                               }
+                       };
+                       }(window, window.document, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, define, ns */
+/**
+ * #Date Utility
+ * Object supports work with date and time
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @class ns.util.date
+ */
+(function (ns) {
+       "use strict";
+                               var timeRegex = /([\-0-9.]*)(ms|s)?/i,
+                               date = {
+                                       /**
+                                        * Convert string time length to miliseconds
+                                        * Note: this was implemented only for animation package
+                                        * and the string input should be conforming to css <time>
+                                        * unit definition (ref: https://developer.mozilla.org/en-US/docs/Web/CSS/time)
+                                        * If a different format or more functionality needs to be implemented, please
+                                        * change this function and usage cases in animation package accordingly
+                                        * @method convertToMiliseconds
+                                        * @param {string} string
+                                        * @return {number}
+                                        * @static
+                                        * @member ns.util.date
+                                        */
+                                       convertToMiliseconds: function (string) {
+                                               var parsed = string.match(timeRegex),
+                                                       miliseconds = 0,
+                                                       parsedNumber;
+
+                                               if (parsed.length === 3) {
+                                                       parsedNumber = parseFloat(parsed[1]) || 0;
+                                                       if (parsed[2] === "ms") {
+                                                               miliseconds = parsedNumber;
+                                                       } else if (parsed[2] === "s") {
+                                                               miliseconds = parsedNumber * 1000;
+                                                       }
+                                               }
+                                               return miliseconds;
+                                       }
+                               };
+
+                       ns.util.date = date;
+                       }(ns));
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Deferred When Utility
+ * Class groups many deferred object to one.
+ * @class ns.util.deferredWhen
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var when = function (subordinate /* , ..., subordinateN */) {
+                               var i = 0,
+                                       resolveValues = [].slice.call(arguments),
+                                       length = resolveValues.length,
+                                       progressValues,
+                                       progressContexts,
+                                       resolveContexts,
+
+                                       /**
+                                        * The count of uncompleted subordinates
+                                        * @property {number} remaining
+                                        * @member ns.util.deferredWhen
+                                        * @private
+                                        */
+                                       remaining = length !== 1 || (subordinate && (typeof subordinate.promise === "function")) ? length : 0,
+
+                                       /**
+                                        * The master Deferred. If resolveValues consist of only
+                                        * a single Deferred, just use that.
+                                        * @property {ns.util.deferred} deferred
+                                        * @member ns.util.deferredWhen
+                                        * @private
+                                        */
+                                       deferred = remaining === 1 ? subordinate : new ns.util.deferred(),
+
+                                       /**
+                                        * Update function for both resolve and progress values
+                                        * @method updateFunc
+                                        * @param {number} i
+                                        * @param {Array} contexts
+                                        * @param {Array} values
+                                        * @return {Function} representing the current state
+                                        * "pending" | "resolved" | "rejected"
+                                        * @member ns.util.deferredWhen
+                                        * @private
+                                        */
+                                       updateFunc = function (i, contexts, values) {
+                                               return function (value) {
+                                                       contexts[i] = this;
+                                                       values[i] = arguments.length > 1 ? [].slice.call(arguments) : value;
+                                                       if (values === progressValues) {
+                                                               deferred.notifyWith(contexts, values);
+
+                                                       } else if (!(--remaining)) {
+                                                               deferred.resolveWith(contexts, values);
+                                                       }
+                                               };
+                                       };
+
+                               // add listeners to Deferred subordinates; treat others as resolved
+                               if (length > 1) {
+                                       progressValues = [];
+                                       progressValues.length = length;
+                                       progressContexts = [];
+                                       progressContexts.length = length;
+                                       resolveContexts = [];
+                                       resolveContexts.length = length;
+                                       for (; i < length; i++) {
+                                               if (resolveValues[i] && (typeof resolveValues[i].promise === "function")) {
+                                                       resolveValues[i].promise()
+                                                               .done(updateFunc(i, resolveContexts, resolveValues))
+                                                               .fail(deferred.reject)
+                                                               .progress(updateFunc(i, progressContexts, progressValues));
+                                               } else {
+                                                       --remaining;
+                                               }
+                                       }
+                               }
+
+                               // if we're not waiting on anything, resolve the master
+                               if (!remaining) {
+                                       deferred.resolveWith(resolveContexts, resolveValues);
+                               }
+
+                               return deferred.promise();
+                       };
+
+                       ns.util.deferredWhen = when;
+
+                       }(window, window.document, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window: false, define: false, Math: false, ns */
+/**
+ * #Bezier Curves Utility
+ * Class supports calculating Bezier Curves.
+ * @class ns.util.bezierCurve
+ */
+(function (ns) {
+       "use strict";
+                       /**
+                * Store constant value for half PI
+                * @property {number} HALF_PI
+                * @member ns.util.bezierCurve
+                * @private
+                * @static
+                */
+               var HALF_PI = Math.PI / 2,
+                       /**
+                        * Store constant value for DEFAULT_STEP
+                        * @property {number} DEFAULT_STEP
+                        * @member ns.util.bezierCurve
+                        * @private
+                        * @static
+                        */
+                       DEFAULT_STEP = 0.001,
+                       BezierCurve,
+                       /**
+                        * Calculates the arc length
+                        * @method arcLength3d
+                        * @param {Array} p0
+                        * @param {Array} p1
+                        * @return {number}
+                        * @member ns.util.bezierCurve
+                        * @private
+                        * @static
+                        */
+                       arcLength3d = function (p0, p1) {
+                               var d = [p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2]];
+
+                               return Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
+                       };
+
+               BezierCurve = function () {
+                       return this;
+               };
+               BezierCurve.prototype = {
+                       points: [],
+                       step: DEFAULT_STEP,
+                       length: 0,
+                       levels: [],
+                       /**
+                        * Init BezierCurve
+                        * @method init
+                        * @param {Object} data
+                        * @return {ns.util.BezierCurve} self
+                        * @member ns.util.bezierCurve
+                        */
+                       init: function (data) {
+                               this.points = data.points;
+                               this.step = data.step || DEFAULT_STEP;
+                               this.length = this.calculateTotalLength();
+                               this.levels = this.calculateLevel(data.maxLevel) || [];
+                               return this;
+                       },
+                       /**
+                        * Calculate levels
+                        * @method calculateLevel
+                        * @param {?number} [maxLevel=null]
+                        * @return {?Array} levels
+                        * @member ns.util.bezierCurve
+                        */
+                       calculateLevel: function (maxLevel) {
+                               var totalLength = this.length,
+                                       interval = totalLength / maxLevel,
+                                       levels = [],
+                                       i;
+
+                               if (!maxLevel) {
+                                       return null;
+                               }
+
+                               for (i = 0; i < maxLevel; i += 1) {
+                                       levels[maxLevel - i] = this.getPercent(0, interval * i);
+                               }
+
+                               return levels;
+                       },
+                       /**
+                        * Calculate total length
+                        * @method calculateTotalLength
+                        * @return {number}
+                        * @member ns.util.bezierCurve
+                        */
+                       calculateTotalLength: function () {
+                               var step = this.step,
+                                       current = this.getPosition(0),
+                                       last = current,
+                                       length = 0,
+                                       percent;
+
+                               for (percent = step; percent <= 1; percent += step) {
+                                       current = this.getPosition(percent);
+                                       length += arcLength3d(last, current);
+                                       last = current;
+                               }
+                               return length;
+                       },
+                       /**
+                        * Get position
+                        * @method getPosition
+                        * @param {number} percent
+                        * @return {Array}
+                        * @member ns.util.bezierCurve
+                        */
+                       getPosition: function (percent) {
+                               var points = this.points,
+                                       getValue = function (p1, c1, c2, p2, t) {
+                                               return Math.pow(1 - t, 3) * p1 +
+                                                       3 * t * Math.pow(1 - t, 2) * c1 +
+                                                       3 * Math.pow(t, 2) * (1 - t) * c2 +
+                                                       Math.pow(t, 3) * p2;
+                                       },
+                                       result = [
+                                               getValue(points[0][0], points[1][0], points[2][0], points[3][0], percent),
+                                               getValue(points[0][2], points[1][2], points[2][2], points[3][2], percent)
+                                       ];
+
+                               return [result[0], 0, result[1]];
+                       },
+                       /**
+                        * Get percent
+                        * @method getPercent
+                        * @param {number} [start=0]
+                        * @param {?number} interval
+                        * @return {number}
+                        * @member ns.util.bezierCurve
+                        */
+                       getPercent: function (start, interval) {
+                               var step = this.step,
+                                       current,
+                                       last,
+                                       targetLength,
+                                       length = 0,
+                                       percent;
+
+                               start = start || 0;
+                               current = this.getPosition(start);
+                               last = current;
+                               targetLength = start + interval;
+                               for (percent = start + step; percent <= 1; percent += step) {
+                                       current = this.getPosition(percent);
+                                       length += arcLength3d(last, current);
+                                       if (length >= targetLength) {
+                                               return percent;
+                                       }
+                                       last = current;
+                               }
+                               return 1;
+                       },
+                       /**
+                        * Get angle
+                        * @method getAngle
+                        * @param {number} percent
+                        * @return {number}
+                        * @member ns.util.bezierCurve
+                        */
+                       getAngle: function (percent) {
+                               var points = this.points,
+                                       getTangent = function (p1, c1, c2, p2, t) {
+                                               return 3 * t * t * (-p1 + 3 * c1 - 3 * c2 + p2) + 6 * t * (p1 - 2 * c1 + c2) + 3 * (-p1 + c1);
+                                       },
+                                       tx = getTangent(points[0][0], points[1][0], points[2][0], points[3][0], percent),
+                                       ty = getTangent(points[0][2], points[1][2], points[2][2], points[3][2], percent);
+
+                               return Math.atan2(tx, ty) - HALF_PI;
+                       }
+               };
+               ns.util.bezierCurve = new BezierCurve();
+
+               }(ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Animation namespace
+ * Namespace for animation utilities
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @class ns.util.anim
+ */
+(function (ns) {
+       "use strict";
+                               ns.util.anim = ns.util.anim || {};
+                       }(ns));
+
+/*global window, define, ns */
+/*jslint nomen: true, plusplus: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * # Keyframes
+ *
+ * Keyframes class for easy keyframe css syntax creation and
+ * managing. Each frame is specified as an element of an array
+ * with size 100.
+ *
+ * @example
+
+ *        <div id="test"
+ *                style="width: 10px; height: 10px; background: red;"></div>
+ *
+ *        <script>
+ *        var frames = [{ "background-color": "red" }],
+ *            anim,
+ *            keys;
+ *
+ *        frames[100] = {"background-color": "blue"};
+ *        keys = new tau.util.anim.Keyframes(frames);
+ *        anim = new tau.util.anim.Animation({
+ *                             element: document.getElementById("test"),
+ *                             fillMode: "both",
+ *                             delay: "2s",
+ *                             duration: "5s",
+ *                             steps: keys,
+ *                             onEnd: function () {
+ *                                     console.log("Yay, finished!");
+ *                             }
+ *                     });
+ *        </script>
+ *
+ * @class ns.util.anim.Keyframes
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ */
+(function (document) {
+       "use strict";
+                               // Reference to stylesheet
+                       var styleContainer = null,
+                               /**
+                                * Helper function for generating css string from
+                                * optimized (most usages will use maybe up to 3-5
+                                * array elements, when it has 100) but thats not
+                                * important for the moment
+                                * frames array
+                                * @param {string} prefix
+                                * @param {string} name
+                                * @param {Array} steps
+                                * @return {string}
+                                * @private
+                                * @static
+                                * @method keyframesToString
+                                * @member ns.utils.anim.Keyframes
+                                */
+                               // @TODO the steps array could be probably be more
+                               keyframesToString = function (prefix, name, steps) {
+                                       var buff = "@" + prefix + "keyframes " + name + " {",
+                                               i,
+                                               l,
+                                               prop,
+                                               step;
+
+                                       for (i = 0, l = steps.length; i < l; ++i) {
+                                               step = steps[i];
+                                               if (!step) {
+                                                       continue;
+                                               }
+                                               buff += i + "% { ";
+                                               for (prop in step) {
+                                                       if (step.hasOwnProperty(prop)) {
+                                                               buff += prop + ": " + step[prop] + "; ";
+                                                       }
+                                               }
+                                               buff += "} ";
+                                       }
+                                       buff += "} ";
+                                       return buff;
+                               },
+
+                               cssPropertyPrefix = ns.support.cssAnimationPrefix,
+
+                               Keyframes = function (steps) {
+                                       var id = ns.getUniqueId(),
+                                               element;
+
+                                       if (!styleContainer) {
+                                               element = document.createElement("style");
+                                               // a text node hack, it forces the browser
+                                               // to create a stylesheet object in the
+                                               // HTMLStyleElement object, which we can
+                                               // then use
+                                               element.appendChild(document.createTextNode(""));
+                                               document.head.appendChild(element);
+                                               styleContainer = element.sheet;
+                                       }
+                                       styleContainer.insertRule(keyframesToString(cssPropertyPrefix, id, steps),
+                                               0);
+                                       /**
+                                        * Keyframes rule reference
+                                        * @property {CSSRule} keyframes
+                                        * @readonly
+                                        */
+                                       this.keyframes = styleContainer.rules[0];
+                                       /**
+                                        * Keyframes name
+                                        * @property {string} id
+                                        * @readonly
+                                        */
+                                       this.id = id;
+                               };
+
+                       /**
+                        * Destroys keyframes and removes css references from stylesheet
+                        * @method destroy
+                        * @member ns.util.anim.Keyframes
+                        */
+                       Keyframes.prototype.destroy = function () {
+                               var keyframes = this.keyframes,
+                                       stylesheet = keyframes.parentStyleSheet,
+                                       rules = stylesheet.rules,
+                                       i,
+                                       l;
+
+                               // no other way for removal than with index
+                               // and since it changes we have to search for it
+                               // :(
+                               for (i = 0, l = rules.length; i < l; ++i) {
+                                       if (rules[i] === keyframes) {
+                                               stylesheet.deleteRule(i);
+                                               break;
+                                       }
+                               }
+                       };
+
+                       ns.util.anim.Keyframes = Keyframes;
+                       }(window.document));
+
+/*global window, define, ns */
+/*jslint nomen: true, plusplus: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * # Animation
+ *
+ * Animation class for easy animations of elements. There can be
+ * multiple animations on one element but in such case the usage
+ * of tau.util.anim.Chain is preferred.
+ *
+ * ## Usage example
+ *
+ * @example
+ *
+ *        <div id="test"
+ *                style="width: 10px; height: 10px; background: red;"></div>
+ *
+ *        <script>
+ *            var a = new tau.util.anim.Animation({
+ *                             element: document.getElementById("test"),
+ *                             fillMode: "both",
+ *                             delay: "2s",
+ *                             duration: "5s",
+ *                             from: {
+ *                                     "background-color": "red"
+ *                             },
+ *                             to: {
+ *                                     "background-color": "blue"
+ *                             },
+ *                             onEnd: function () {
+ *                                     console.log("Yay, finished!");
+ *                             }
+ *                     });
+ *        </script>
+ *
+ * @class ns.util.anim.Animation
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ */
+(function () {
+       "use strict";
+       
+                       var objectUtils = ns.util.object,
+                               Keyframes = ns.util.anim.Keyframes,
+                               CSSUtils = ns.util.DOM,
+                               dateUtils = ns.util.date,
+                               cssPropertyPrefix = ns.support.cssAnimationPrefix,
+
+                               /**
+                                * Simple helper for using trim in Array.map() function
+                                * @param {string} string
+                                * @return {string}
+                                * @private
+                                * @static
+                                * @method trim
+                                * @member ns.util.anim.Animation
+                                */
+                               trim = function (string) {
+                                       return string.trim();
+                               },
+
+                               /**
+                                * Helper for fetching animation index in animation list
+                                * @param {string|string[]} props
+                                * @param {string} name
+                                * @return {string}
+                                * @private
+                                * @static
+                                * @member ns.util.anim.Animation
+                                */
+                               getAnimationIndex = function (props, name) {
+                                       if (typeof props === "string") {
+                                               props = props.split(",").map(trim);
+                                       }
+                                       return props.indexOf(name);
+                               },
+
+                               eventPrefix = (cssPropertyPrefix || "").replace(/\-/gi, ""),
+                               endEventName = eventPrefix.length > 0 ? eventPrefix +
+                               "AnimationEnd" : "animationEnd",
+                               // paused state flag
+                               PAUSED = 0,
+                               // playing state flag
+                               PLAYING = 1,
+                               // finished state flag
+                               FINISHED = 2,
+                               // alias for function string for typeof conditionals
+                               TYPE_FUNCTION = "function",
+                               /**
+                                * Animation end handler
+                                * @param {ns.util.anim.Animation} self
+                                * @param {Event} event
+                                * @private
+                                * @static
+                                * @member ns.util.anim.Animation
+                                */
+                               handleEnd = function (self, event) {
+                                       var options = self.options,
+                                               element = options.element,
+                                               onEnd = options.onEnd,
+                                               onPause = options.onPause;
+
+                                       if (event.animationName === self.keyframes.id) {
+                                               switch (self.state) {
+                                                       case PLAYING:
+                                                               self.state = FINISHED;
+                                                               if (typeof onEnd === TYPE_FUNCTION) {
+                                                                       onEnd(self, element, event);
+                                                               }
+                                                               break;
+                                                       case PAUSED:
+                                                               if (typeof onPause === TYPE_FUNCTION) {
+                                                                       onPause(self, element, event);
+                                                               }
+                                                               break;
+                                               }
+                                       }
+                               },
+                               /**
+                                * Helper for playing/pausing
+                                * @param {ns.util.anim.Animation} self
+                                * @param {string} state
+                                * @return {ns.util.anim.Animation}
+                                * @private
+                                * @static
+                                * @member ns.util.anim.Animation
+                                */
+                               changeState = function (self, state) {
+                                       var options,
+                                               element = null,
+                                               onPlay = null,
+                                               style,
+                                               keyframes,
+                                               propString,
+                                               propsArray,
+                                               index;
+
+                                       if (!self._applied) { // !set before keyframe fetch
+                                               self._apply();
+                                       }
+
+                                       options = self.options;
+                                       element = options.element;
+                                       onPlay = options.onPlay;
+                                       style = element.style;
+                                       keyframes = self.keyframes;
+                                       propString = style.getPropertyValue(cssPropertyPrefix +
+                                               "animation-play-state");
+                                       propsArray = (propString && propString.split(",").map(trim)) || [];
+                                       index = keyframes ? getAnimationIndex(
+                                               style.getPropertyValue(cssPropertyPrefix +
+                                                       "animation-name"),
+                                               keyframes.id
+                                       ) : -1;
+
+                                       if (index > -1) {
+                                               propsArray[index] = state || "running";
+                                               style.setProperty(cssPropertyPrefix +
+                                                       "animation-play-state", propsArray.join(","));
+                                               self.state = PLAYING;
+                                               if (typeof onPlay === TYPE_FUNCTION) {
+                                                       window.clearTimeout(self.playTimer);
+                                                       self.playTimer = window.setTimeout(function () {
+                                                               onPlay(self, element);
+                                                       }, dateUtils.convertToMiliseconds(options.delay));
+                                               }
+                                       }
+                                       return self;
+                               },
+                               /**
+                                * Constructor for Animation object
+                                * @param {Object} options
+                                * @param {HTMLElement} options.element The animated element
+                                * @param {Object|null} [options.from=null] The starting step, this can be defined later
+                                * @param {Object|null} [options.to=null]  The finishing step, this can also be defined later
+                                * @param {Object[]} [options.steps=Array(0)] Animation steps, when advanced keying is required, the array must have 100 elements, which are percentages of the timeline (animation duration)
+                                * @param {string} [options.duration="0"] The duration of the animation
+                                * @param {string} [options.direction="normal"] The direction of the animation (for possible values, refer to CSS Animation spec)
+                                * @param {string} [options.delay="0"] The delay of the animation. Please remember when using ns.util.anim.Chain with concurrent option to false, the of subsequent animations will be modified
+                                * @param {string} [options.fillMode="none"] The fill mode of the animations (for possible values, refer to CSS Animation spec)
+                                * @param {string} [options.timingFunction="ease"] Chooses the timing function for the css animation
+                                * @param {boolean} [options.autoPlay=false] Defines if the animation will start after definition
+                                * @constructor
+                                * @member ns.util.anim.Animation
+                                */
+                               Animation = function (options) {
+                                       var self = this,
+                                               /**
+                                                * @property {Object} options
+                                                * @property {HTMLElement} options.element The animated element
+                                                * @property {Object|null} [options.from=null] The starting step, this
+                                                *        can be defined later
+                                                * @property {Object|null} [options.to=null]  The finishing step, this
+                                                *        can also be defined later
+                                                * @property {Object[]} [options.steps=Array(0)] Animation steps,
+                                                *        when advanced keying is required, the array must have 100 elements,
+                                                *        which are percentages of the timeline (animation duration)
+                                                * @property {string} [options.duration="0"] The duration of the animation
+                                                * @property {string} [options.direction="normal"] The direction of the
+                                                *        animation (for possible values, refer to CSS Animation spec)
+                                                * @property {string} [options.delay="0"] The delay of the animation.
+                                                *        Please remember when using ns.util.anim.Chain with concurrent
+                                                *        option to false, the of subsequent animations will be modified
+                                                * @property {string} [options.fillMode="none"] The fill mode of the
+                                                *        animations (for possible values, refer to CSS Animation spec)
+                                                * @property {boolean} [options.preserve=false] Indicates if the last
+                                                *        key frame props should be kept after animation is destroyed
+                                                *        (not implemented!)
+                                                * @property {string} [options.timingFunction="ease"] Chooses the timing
+                                                *        function for the css animation (for possible values, refer to CSS
+                                                *        Animation spec)
+                                                * @property {boolean} [options.autoPlay=false] Defines if the animation
+                                                *        will start after definition
+                                                * @member ns.util.anim.Animation
+                                                */
+                                               opts = objectUtils.merge({
+                                                       element: null,
+                                                       from: null,
+                                                       to: null,
+                                                       steps: [],
+                                                       duration: "0",
+                                                       direction: "normal",
+                                                       delay: "0",
+                                                       iterationCount: 1,
+                                                       infinite: false,
+                                                       fillMode: "none",
+                                                       preserve: false, //@TODO preserve props after animation destroy!
+                                                       onEnd: null,
+                                                       onPause: null,
+                                                       onPlay: null,
+                                                       timingFunction: "ease",
+                                                       autoPlay: false
+                                               }, options || {}),
+                                               steps,
+                                               props,
+                                               endCallback = handleEnd.bind(null, this),
+                                               element = opts.element;
+
+                                       if (opts.steps.length === 0) {
+                                               steps = [];
+                                               steps.length = 101;
+                                               if (opts.to) {
+                                                       steps[100] = opts.to;
+                                               }
+                                               if (!opts.from) {
+                                                       if (opts.to && opts.element) {
+                                                               props = Object.keys(opts.to);
+                                                               CSSUtils.extractCSSProperties(opts.element, props);
+                                                               steps[0] = props;
+                                                       }
+                                               } else {
+                                                       steps[0] = opts.from;
+                                               }
+                                       } else {
+                                               steps = opts.steps;
+                                       }
+
+                                       self.options = opts;
+                                       /**
+                                        * @property {Array.<Object>} steps Array of animation steps
+                                        * @readonly
+                                        */
+                                       self.steps = steps;
+                                       // indicates if the css props were applied
+                                       self._applied = false;
+                                       /**
+                                        * @property {ns.util.anim.Keyframes|null} keyframes Keyframes reference
+                                        * @readonly
+                                        */
+                                       self.keyframes = null;
+                                       /**
+                                        * @property {number} [state=0] Animation state
+                                        *        (ns.util.anim.Animation.states.*)
+                                        * @readonly
+                                        */
+                                       self.state = PAUSED;
+                                       // timer for onPlay callback (we need to simulate actual event firing
+                                       self.playTimer = null;
+                                       this._endCallback = endCallback;
+
+                                       if (element) {
+                                               element.addEventListener(endEventName, endCallback, false);
+                                               if (opts.autoPlay) {
+                                                       self.play();
+                                               }
+                                       }
+
+                               },
+                               proto = {};
+
+                       /**
+                        * Applies css properties for the element
+                        * @method _apply
+                        * @protected
+                        * @member ns.util.anim.Animation
+                        */
+                       proto._apply = function () {
+                               var self = this,
+                                       opts = self.options,
+                                       element = opts.element,
+                                       style = element.style,
+                                       propString = style.getPropertyValue(cssPropertyPrefix + "animation"),
+                                       propsArray = (propString && propString.split(",").map(trim)) || [],
+                                       id;
+
+                               self.keyframes = new Keyframes(self.steps);
+                               id = self.keyframes.id;
+                               if (element) {
+                                       propsArray.push(id + " " + opts.duration + " " + opts.timingFunction +
+                                               " " + opts.delay + " " + opts.iterationCount + " " + opts.direction +
+                                               " " + opts.fillMode);
+                                       element.style.setProperty(cssPropertyPrefix + "animation",
+                                               propsArray.join(","));
+                                       self._applied = true;
+                               }
+                       };
+
+                       /**
+                        * Adds step to animation
+                        * Note: this will reset the whole animation, so do it only in paused state
+                        * @param {number} timePoint A keyframe number between from 0 to 100
+                        * @param {Object} stepOptions Css props to change in the keyframe
+                        * @return {ns.util.anim.Animation}
+                        * @method step
+                        * @member ns.util.anim.Animation
+                        */
+                       proto.step = function (timePoint, stepOptions) {
+                               var self = this;
+
+                               self.steps[timePoint] = stepOptions;
+                               return self.reset();
+                       };
+
+                       /**
+                        * Resets the animation
+                        * @return {ns.util.anim.Animation}
+                        * @method reset
+                        * @member ns.util.anim.Animation
+                        */
+                       proto.reset = function () {
+                               var self = this,
+                                       keyframes = self.keyframes,
+                                       style = self.options.element.style,
+                                       propString = style.getPropertyValue(cssPropertyPrefix + "animation-name"),
+                                       propsArray = (propString && propString.split(",").map(trim)) || [],
+                                       index = keyframes ? propsArray.indexOf(keyframes.id) : -1;
+
+                               if (self.keyframes) {
+                                       self.keyframes.destroy();
+                               }
+
+                               keyframes = new Keyframes(self.steps);
+                               if (index > -1) {
+                                       propsArray[index] = keyframes.id;
+                                       self.keyframes = keyframes;
+                                       style.setProperty(cssPropertyPrefix + "animation-name",
+                                               propsArray.join(","));
+                               }
+
+                               return self;
+                       };
+
+                       /**
+                        * Starts playback
+                        * @return {ns.util.anim.Animation}
+                        * @method play
+                        * @member ns.util.anim.Animation
+                        */
+                       proto.play = function () {
+                               return changeState(this, "running");
+                       };
+
+                       /**
+                        * Pauses playback
+                        * @return {ns.util.anim.Animation}
+                        * @method pause
+                        * @member ns.util.anim.Animation
+                        */
+                       proto.pause = function () {
+                               return changeState(this, "paused");
+                       };
+
+                       /**
+                        * Destroys the animation
+                        * Note: Please use "preserve" options to keep applied last animation props
+                        * @return {ns.util.anim.Animation}
+                        * @method destroy
+                        * @member ns.util.anim.Animation
+                        */
+                       proto.destroy = function () {
+                               var self = this,
+                                       element = self.options.element,
+                                       prop,
+                                       style,
+                                       keyframes = self.keyframes,
+                                       endCallback = self._endCallback,
+                                       propRegexp;
+
+                               if (element) {
+                                       if (self._applied && keyframes) {
+                                               style = element.style;
+                                               prop = style.getPropertyValue(cssPropertyPrefix + "animation");
+                                               if (prop) {
+                                                       propRegexp = new RegExp(",? ?" + keyframes.id + "[^,%]*,? ?", "i");
+                                                       style.removeProperty(cssPropertyPrefix + "animation",
+                                                               prop.replace(propRegexp, ""));
+                                               }
+                                               keyframes.destroy();
+                                               self._applied = false;
+                                       }
+                                       if (endCallback) {
+                                               element.removeEventListener(endEventName, endCallback, false);
+                                       }
+                               }
+                               window.clearTimeout(self.playTimer);
+                       };
+
+                       /**
+                        * @property {Object} states animation state definitions
+                        * @property {number} [states.PAUSED=0] paused state
+                        * @property {number} [states.PLAYING=1] playing state
+                        * @property {number} [states.FINISHED=2] finished state
+                        * @static
+                        * @readonly
+                        * @member ns.util.anim.Animation
+                        */
+                       Animation.states = {
+                               "PAUSED": PAUSED,
+                               "PLAYING": PLAYING,
+                               "FINISHED": FINISHED
+                       };
+                       Animation.prototype = proto;
+                       ns.util.anim.Animation = Animation;
+                       }());
+
+/*global define, ns */
+/*jslint plusplus: true, nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * # Chain
+ *
+ * Chain class for easy multiple animations management. The chain
+ * can be executed as is (animations are concurrent) or in order
+ * of adding in which animations are delayed so that the execute
+ * in turn
+ *
+ * ## Usage example
+ *
+ * @example
+ *
+ *        <div id="test"
+ *                style="width: 10px; height: 10px; background: red; position: absolute;">
+ *        </div>
+ *
+ *        <script>
+ *            var element = document.getElementById("test"),
+ *                chain = new tau.util.anim.Chain(
+ *                    {
+ *                                             concurrent: false,
+ *                                             onPlay: function () {
+ *                                                     console.log("chain started to play");
+ *                                             },
+ *                                             onPause: function () {
+ *                                                     console.log("chain paused");
+ *                                             },
+ *                                             onEnd: function () {
+ *                                                     console.log("chain finished");
+ *                                             }
+ *                                     },
+ *                    [
+ *                        {
+ *                                                     element: element,
+ *                                                     from: { "background-color": "red" },
+ *                                                     to: { "background-color": "blue"},
+ *                                                     duration: "3s",
+ *                                                     onPlay: function () {
+ *                                                             console.log("animation 1 started to play");
+ *                                                     },
+ *                                                     onPause: function () {
+ *                                                             console.log("animation 1 paused");
+ *                                                     },
+ *                                                     onEnd: function () {
+ *                                                             console.log("animation 1 finished");
+ *                                                     }
+ *                                             },
+ *                        {
+ *                                                     element: element,
+ *                                             from: { "-webkit-transform": "translate3d(0,0,0)" },
+ *                                                     to: { "-webkit-transform": "translate3d(100px, 100px, 0)"},
+ *                                                     duration: "3s",
+ *                                                     onPlay: function () {
+ *                                                             console.log("animation 2 started to play");
+ *                                                     },
+ *                                                     onPause: function () {
+ *                                                             console.log("animation 2 paused");
+ *                                                     },
+ *                                                     onEnd: function () {
+ *                                                             console.log("animation 2 finished");
+ *                                                     }
+ *                                             }
+ *                    ]
+ *                );
+ *            chain.play();
+ *        </script>
+ *
+ * @class ns.util.anim.Chain
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ */
+(function () {
+       "use strict";
+                               var Animation = ns.util.anim.Animation,
+                               objectUtils = ns.util.object,
+                               dateUtils = ns.util.date,
+                               // paused state flag
+                               PAUSED = 0,
+                               // playing state flag
+                               PLAYING = 1,
+                               // finished state flag
+                               FINISHED = 2,
+                               // function type for typeof comparisons
+                               TYPE_FUNCTION = "function",
+                               /**
+                                * Animation end handler
+                                * @param {ns.util.anim.Chain} self
+                                * @param {ns.util.anim.Animation} animation
+                                * @method handleEnd
+                                * @member ns.util.anim.Chain
+                                * @private
+                                * @static
+                                */
+                               handleEnd = function (self, animation) {
+                                       var onEnd = self.options.onEnd,
+                                               animations = self.animations,
+                                               index = animations.indexOf(animation);
+
+                                       self.current = index;
+                                       if (index === animations.length - 1) {
+                                               self.state = FINISHED;
+                                               if (typeof onEnd === TYPE_FUNCTION) {
+                                                       onEnd(self);
+                                               }
+                                       }
+                               },
+                               Chain = function (options, animations) {
+                                       /**
+                                        * @property {Object} options
+                                        * @property {boolean} [options.concurent='false'] Sets the type of the chain
+                                        * @property {function(ns.util.anim.Chain)} [options.onPlay=null] a callback for play start
+                                        * @property {function(ns.util.anim.Chain)} [options.onPause=null] a callback for play pause
+                                        * @property {function(ns.util.anim.Chain)} [options.onEnd=null] a callback for play end
+                                        */
+                                       var opts = objectUtils.merge({
+                                                       conocurrent: true,
+                                                       onPlay: null,
+                                                       onPause: null,
+                                                       onEnd: null
+                                               }, options || {}),
+                                               self = this;
+                                       /**
+                                        * @property {number} current Marks current animation
+                                        * @readonly
+                                        */
+
+                                       self.current = null;
+                                       /**
+                                        * @property {Array.<ns.util.anim.Animation>} animations The animations holder
+                                        * @readonly
+                                        */
+                                       self.animations = [];
+                                       /**
+                                        * @property {number} totalTime
+                                        * @readonly
+                                        */
+                                       self.totalTime = 0;
+                                       self.options = opts;
+                                       /**
+                                        * @property {number} state=0 (ns.util.anim.Chain.states.*)
+                                        * @readonly
+                                        */
+                                       self.state = PAUSED;
+
+                                       if (animations && animations.length > 0) {
+                                               self.addMultiple(animations);
+                                       }
+                               },
+                               proto = {
+                                       /**
+                                        * Adds animation to chain
+                                        * @param {ns.util.anim.Animation} animation
+                                        * @return {ns.util.anim.Chain}
+                                        * @method add
+                                        * @member ns.util.anim.Chain
+                                        */
+                                       add: function (animation) {
+                                               var animationInstance = animation instanceof Animation ?
+                                                               animation :
+                                                               new Animation(animation),
+                                                       animationOptions = animationInstance.options,
+                                                       time = dateUtils.convertToMiliseconds(animationOptions.duration),
+                                                       delay = dateUtils.convertToMiliseconds(animationOptions.delay),
+                                                       onEndCallback = animationOptions.onEnd,
+                                                       self = this;
+
+                                               if (typeof onEndCallback === TYPE_FUNCTION) {
+                                                       animationOptions.onEnd = function (_animation, element, event) {
+                                                               onEndCallback(_animation, element, event);
+                                                               handleEnd(self, _animation);
+                                                       };
+                                               } else {
+                                                       animationOptions.onEnd = handleEnd.bind(null, self);
+                                               }
+
+                                               if (self.options.concurrent === false) {
+                                                       animationOptions.delay = (delay + self.totalTime) + "ms";
+                                                       self.totalTime += delay + time;
+                                               }
+
+                                               self.animations.push(animationInstance);
+                                               if (!self.current) {
+                                                       self.current = 0;
+                                               }
+                                               return self;
+                                       },
+
+                                       /**
+                                        * Adds multiple animations to chain
+                                        * @param {Array.<ns.util.anim.Animation>} animations
+                                        * @return {ns.util.anim.Chain}
+                                        * @method addMultiple
+                                        * @member ns.util.anim.Chain
+                                        */
+                                       addMultiple: function (animations) {
+                                               var i,
+                                                       l;
+
+                                               for (i = 0, l = animations.length; i < l; ++i) {
+                                                       this.add(animations[i]);
+                                               }
+                                               return this;
+                                       },
+
+                                       /**
+                                        * Starts playing animation chain
+                                        * @method play
+                                        * @return {ns.util.anim.Chain}
+                                        * @member ns.util.anim.Chain
+                                        */
+                                       play: function () {
+                                               var i,
+                                                       l,
+                                                       self = this,
+                                                       onPlay = self.options.onPlay;
+
+                                               for (i = self.current, l = self.animations.length; i < l; ++i) {
+                                                       self.animations[i].play();
+                                               }
+                                               self.state = PLAYING;
+                                               if (typeof onPlay === TYPE_FUNCTION) {
+                                                       onPlay(self);
+                                               }
+                                               return self;
+                                       },
+
+                                       /**
+                                        * Pauses playback
+                                        * @method pause
+                                        * @return {ns.util.anim.Animation}
+                                        * @member ns.util.anim.Chain
+                                        */
+                                       pause: function () {
+                                               var i,
+                                                       l,
+                                                       self = this,
+                                                       onPause = self.options.onPause;
+
+                                               for (i = self.current, l = self.animations.length; i < l; ++i) {
+                                                       self.animations[i].pause();
+                                               }
+                                               self.state = PAUSED;
+                                               if (typeof onPause === TYPE_FUNCTION) {
+                                                       onPause(self);
+                                               }
+                                               return self;
+                                       },
+
+                                       /**
+                                        * Destroys chain and animations
+                                        * @method destroy
+                                        * @member ns.util.anim.Chain
+                                        */
+                                       destroy: function () {
+                                               var i,
+                                                       l;
+
+                                               for (i = 0, l = this.animations.length; i < l; ++i) {
+                                                       this.animations[i].destroy();
+                                               }
+                                       }
+                               };
+
+                       /**
+                        * Animation chain states
+                        * @property {Object} states
+                        * @property {number} [states.PAUSED = 0]
+                        * @property {number} [states.PLAYING = 1]
+                        * @property {number} [states.FINISHED = 2]
+                        * @readonly
+                        * @static
+                        * @member ns.util.anim.Chain
+                        */
+                       Chain.states = {
+                               "PAUSED": PAUSED,
+                               "PLAYING": PLAYING,
+                               "FINISHED": FINISHED
+                       };
+                       Chain.prototype = proto;
+                       ns.util.anim.Chain = Chain;
+                       }());
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Event hwkey
+ * Namespace to support tizenhwkey event
+ * @class ns.event.hwkey
+ */
+(function (window, ns) {
+       "use strict";
+                               var popupClose = function (event) {
+                                       var keyName = event.keyName,
+                                               activePopup = ns.activePopup,
+                                               container,
+                                               containerClass,
+                                               focused;
+
+                                       // Check enableHWKeyHandler property
+                                       if (ns.getConfig("enableHWKeyHandler", true) && activePopup) {
+                                               container = activePopup._ui.container;
+                                               containerClass = container && container.classList;
+                                               if (keyName === "menu") {
+                                                       focused = activePopup.element.querySelector(".ui-focus");
+                                                       if (focused) {
+                                                               // NOTE: If a popup is opened and focused element exists in it,
+                                                               //       do not close that popup.
+                                                               //       'false' is returned here, hence popup close routine is not run.
+                                                               event.preventDefault();
+                                                               event.stopPropagation();
+                                                               return;
+                                                       }
+                                               }
+                                               if (keyName === "menu" || keyName === "back") {
+                                                       if (containerClass && (!containerClass.contains("ui-datetimepicker") || containerClass.contains("in"))) {
+                                                               activePopup.close();
+                                                               event.preventDefault();
+                                                               event.stopPropagation();
+                                                       }
+                                               }
+                                       }
+                               },
+                               selectMenuClose = function (event) {
+                                       var keyName = event.keyName,
+                                               elActiveSelectMenu,
+                                               activeSelectMenu;
+
+                                       if (ns.getConfig("enableHWKeyHandler", true) && (keyName === "menu" || keyName === "back")) {
+                                               elActiveSelectMenu = document.querySelector("div.ui-selectmenu-active select");
+                                               if (elActiveSelectMenu) {
+                                                       activeSelectMenu = ns.widget.SelectMenu(elActiveSelectMenu);
+                                                       activeSelectMenu.close();
+                                                       event.preventDefault();
+                                                       event.stopPropagation();
+                                               }
+                                       }
+                               },
+                               eventType = ns.engine.eventType,
+                               hwkey = {
+                                       /**
+                                        * Bind event tizenhwkey to support hardware keys.
+                                        * @method bind
+                                        * @static
+                                        * @member ns.event.hwkey
+                                        */
+                                       bind: function () {
+                                               document.addEventListener("tizenhwkey", popupClose, true);
+                                               document.addEventListener("tizenhwkey", selectMenuClose, true);
+                                       },
+
+                                       /**
+                                        * Unbind event tizenhwkey to support hardware keys.
+                                        * @method unbind
+                                        * @static
+                                        * @member ns.event.hwkey
+                                        */
+                                       unbind: function () {
+                                               document.removeEventListener("tizenhwkey", popupClose, true);
+                                               document.removeEventListener("tizenhwkey", selectMenuClose, true);
+                                       }
+                               };
+
+                       ns.event.hwkey = hwkey;
+
+                       function init() {
+                               hwkey.unbind();
+                               hwkey.bind();
+                       }
+
+                       function destroy() {
+                               document.removeEventListener(eventType.INIT, init, false);
+                               document.removeEventListener(eventType.DESTROY, destroy, false);
+                       }
+
+                       document.addEventListener(eventType.INIT, init, false);
+                       document.addEventListener(eventType.DESTROY, destroy, false);
+
+                       }(window, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, ns, define */
+/**
+ * #Event throttledresize
+ * Object supports throttledresize event.
+ * @class ns.event.throttledresize
+ */
+/**
+ * Event throttledresize
+ * @event throttledresize
+ * @member ns.event.throttledresize
+ */
+(function (window) {
+       "use strict";
+                               var throttledresize = {
+                                       /**
+                                        * State of event support
+                                        * @property {boolean} [enabled=true]
+                                        * @static
+                                        * @member ns.event.throttledresize
+                                        */
+                                       enabled: ns.getConfig("enableThrottleResize", true),
+                                       /**
+                                        * Timeout of triggering event.
+                                        * @property {number} [ttl=250]
+                                        * @static
+                                        * @member ns.event.throttledresize
+                                        */
+                                       ttl: 250
+                               },
+                               timerID,
+                               eventUtils = ns.event,
+                               resizeHandler = function () {
+                                       if (timerID) {
+                                               window.clearTimeout(timerID);
+                                       }
+                                       timerID = window.setTimeout(function () {
+                                               eventUtils.trigger(window, "throttledresize");
+                                       }, throttledresize.ttl);
+                               },
+                               /**
+                                * Enables event support
+                                * @method enable
+                                * @static
+                                * @member ns.event.throttledresize
+                                */
+                               enable = function () {
+                                       if (!throttledresize.enabled) {
+                                               throttledresize.enabled = true;
+                                       }
+                                       window.addEventListener("resize", resizeHandler, true);
+                               },
+
+                               unbind = function () {
+                                       throttledresize.enabled = false;
+                                       window.removeEventListener("resize", resizeHandler, true);
+                               };
+
+                       if (throttledresize.enabled) {
+                               enable();
+                       }
+
+                       throttledresize.enable = enable;
+                       throttledresize.unbind = unbind;
+
+                       ns.event.throttledresize = throttledresize;
+
+                       }(window));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* global window, define, ns, CustomEvent */
+/*
+ * @class ns.event.gesture
+ */
+(function (ns) {
+       "use strict";
+                       var event = ns.event,
+                       gesture = function (elem, options) {
+                               return new ns.event.gesture.Instance(elem, options);
+                       };
+
+                       /**
+                        * Default values for Gesture feature
+                        * @property {Object} defaults
+                        * @property {boolean} [defaults.triggerEvent=false]
+                        * @property {number} [defaults.updateVelocityInterval=16]
+                        * Interval in which Gesture recalculates current velocity in ms
+                        * @property {number} [defaults.estimatedPointerTimeDifference=15]
+                        * pause time threshold.. tune the number to up if it is slow
+                        * @member ns.event.gesture
+                        * @static
+                        */
+               gesture.defaults = {
+                       triggerEvent: false,
+                       updateVelocityInterval: 16,
+                       estimatedPointerTimeDifference: 15
+               };
+
+               /**
+                        * Dictionary of orientation
+                        * @property {Object} Orientation
+                        * @property {1} Orientation.VERTICAL vertical orientation
+                        * @property {2} Orientation.HORIZONTAL horizontal orientation
+                        * @member ns.event.gesture
+                        * @static
+                        */
+               gesture.Orientation = {
+                       VERTICAL: "vertical",
+                       HORIZONTAL: "horizontal"
+               };
+
+               /**
+                        * Dictionary of direction
+                        * @property {Object} Direction
+                        * @property {1} Direction.UP up
+                        * @property {2} Direction.DOWN down
+                        * @property {3} Direction.LEFT left
+                        * @property {4} Direction.RIGHT right
+                        * @member ns.event.gesture
+                        * @static
+                        */
+               gesture.Direction = {
+                       UP: "up",
+                       DOWN: "down",
+                       LEFT: "left",
+                       RIGHT: "right"
+               };
+
+               /**
+                        * Dictionary of gesture events state
+                        * @property {Object} Event
+                        * @property {"start"} Event.START start
+                        * @property {"move"} Event.MOVE move
+                        * @property {"end"} Event.END end
+                        * @property {"cancel"} Event.CANCEL cancel
+                        * @property {"blocked"} Event.BLOCKED blocked
+                        * @member ns.event.gesture
+                        * @static
+                        */
+               gesture.Event = {
+                       START: "start",
+                       MOVE: "move",
+                       END: "end",
+                       CANCEL: "cancel",
+                       BLOCKED: "blocked"
+               };
+
+               /**
+                        * Dictionary of gesture events flags
+                        * @property {Object} Result
+                        * @property {number} [Result.PENDING=1] is pending
+                        * @property {number} [Result.RUNNING=2] is running
+                        * @property {number} [Result.FINISHED=4] is finished
+                        * @property {number} [Result.BLOCK=8] is blocked
+                        * @member ns.event.gesture
+                        * @static
+                        */
+               gesture.Result = {
+                       PENDING: 1,
+                       RUNNING: 2,
+                       FINISHED: 4,
+                       BLOCK: 8
+               };
+
+               /**
+                        * Create plugin namespace.
+                        * @property {Object} plugin
+                        * @member ns.event.gesture
+                        * @static
+                        */
+               gesture.plugin = {};
+
+               /**
+                        * Create object of Detector
+                        * @method createDetector
+                        * @param {string} gesture
+                        * @param {HTMLElement} eventSender
+                        * @param {Object} options
+                        * @return {ns.event.gesture.Gesture}
+                        * @member ns.event.gesture
+                        * @static
+                        */
+               gesture.createDetector = function (gesture, eventSender, options) {
+                       if (!gesture.plugin[gesture]) {
+                               throw gesture + " gesture is not supported";
+                       }
+                       return new gesture.plugin[gesture](eventSender, options);
+               };
+
+               event.gesture = gesture;
+               }(ns));
+
+/*global ns, window, define */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Gesture.Detector class
+ * Base class for create detectors in gestures.
+ *
+ * @class ns.event.gesture.Detector
+ */
+(function (ns) {
+       "use strict";
+                               var gesture = ns.event.gesture,
+
+                               objectMerge = ns.util.object.merge,
+
+                               Detector = function (strategy, sender) {
+                                       this.sender = sender;
+                                       this.strategy = strategy.create();
+                                       this.name = this.strategy.name;
+                                       this.index = this.strategy.index || 100;
+                                       this.options = this.strategy.options || {};
+                               };
+
+                       /**
+                        * Start of gesture detection of given type
+                        * @method detect
+                        * @param {string} gestureEvent
+                        * @return {Object}
+                        * @member ns.event.gesture.Detector
+                        */
+                       Detector.prototype.detect = function (gestureEvent) {
+                               return this.strategy.handler(gestureEvent, this.sender, this.strategy.options);
+                       };
+
+                       Detector.Sender = {
+                               sendEvent: function () {
+                               // Empty function for creating interface
+                               }
+                       };
+
+               /**
+                        * Create plugin namespace.
+                        * @property {Object} plugin
+                        * @member ns.event.gesture.Detector
+                        */
+                       Detector.plugin = {};
+
+               /**
+                        * Methods creates plugin
+                        * @method create
+                        * @param {Object} gestureHandler
+                        * @return {ns.event.gesture.Detector} gestureHandler
+                        * @member ns.event.gesture.Detector.plugin
+                        */
+                       Detector.plugin.create = function (gestureHandler) {
+                               var detector;
+
+                               if (!gestureHandler.types) {
+                                       gestureHandler.types = [gestureHandler.name];
+                               }
+
+                               detector = function (options) {
+                                       this.options = objectMerge({}, gestureHandler.defaults, options);
+                               };
+
+                               detector.prototype.create = function () {
+                                       return objectMerge({
+                                               options: this.options
+                                       }, gestureHandler);
+                               };
+
+                               Detector.plugin[gestureHandler.name] = detector;
+
+                               return detector;
+                       };
+
+               // definition
+                       gesture.Detector = Detector;
+
+               }(ns));
+
+/*global ns, window, define */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Gesture Utilities
+ * Contains helper function to gesture support.
+ * @class ns.event.gesture.utils
+ */
+(function (ns, math) {
+       "use strict";
+       
+               /**
+                        * Local alias for {@link ns.event.gesture}
+                        * @property {Object}
+                        * @member ns.event.gesture.utils
+                        * @private
+                        * @static
+                        */
+                       var gesture = ns.event.gesture;
+
+                       gesture.utils = {
+
+                       /**
+                                * Get center from array of touches
+                                * @method getCenter
+                                * @param {Event[]} touches description
+                                * @member ns.event.gesture.utils
+                                * @return {Object} position
+                                * @return {number} return.clientX position X
+                                * @return {number} return.clientY position Y
+                                */
+                               getCenter: function (touches) {
+                                       var valuesX = [],
+                                               valuesY = [];
+
+                                       [].forEach.call(touches, function (touch) {
+                                       // I prefer clientX because it ignore the scrolling position
+                                               valuesX.push(!isNaN(touch.clientX) ? touch.clientX : touch.pageX);
+                                               valuesY.push(!isNaN(touch.clientY) ? touch.clientY : touch.pageY);
+                                       });
+
+                                       return {
+                                               clientX: (math.min.apply(math, valuesX) + math.max.apply(math, valuesX)) / 2,
+                                               clientY: (math.min.apply(math, valuesY) + math.max.apply(math, valuesY)) / 2
+                                       };
+                               },
+
+                       /**
+                                * Get velocity
+                                * @method getVelocity
+                                * @param {number} deltaTime Delta of time
+                                * @param {number} deltaX Position change on x axis
+                                * @param {number} deltaY Position change on y axis
+                                * @return {Object} velocity
+                                * @return {number} return.x velocity on X axis
+                                * @return {number} return.y velocity on Y axis
+                                * @member ns.event.gesture.utils
+                                */
+                               getVelocity: function (deltaTime, deltaX, deltaY) {
+                                       return {
+                                               x: math.abs(deltaX / deltaTime) || 0,
+                                               y: math.abs(deltaY / deltaTime) || 0
+                                       };
+                               },
+
+                       /**
+                                * Get angel between position of two touches
+                                * @method getAngle
+                                * @param {Event} touch1 first touch
+                                * @param {Event} touch2 second touch
+                                * @return {number} angel (deg)
+                                * @member ns.event.gesture.utils
+                                */
+                               getAngle: function (touch1, touch2) {
+                                       var y = touch2.clientY - touch1.clientY,
+                                               x = touch2.clientX - touch1.clientX;
+
+                                       return math.atan2(y, x) * 180 / math.PI;
+                               },
+
+                       /**
+                                * Get direction indicated by position of two touches
+                                * @method getDirection
+                                * @param {Event} touch1 first touch
+                                * @param {Event} touch2 second touch
+                                * @return {ns.event.gesture.Direction.LEFT|ns.event.gesture.Direction.RIGHT|ns.event.gesture.Direction.UP|ns.event.gesture.Direction.DOWN}
+                                * @member ns.event.gesture.utils
+                                */
+                               getDirection: function (touch1, touch2) {
+                                       var x = math.abs(touch1.clientX - touch2.clientX),
+                                               y = math.abs(touch1.clientY - touch2.clientY);
+
+                                       if (x >= y) {
+                                               return touch1.clientX - touch2.clientX > 0 ? gesture.Direction.LEFT : gesture.Direction.RIGHT;
+                                       }
+                                       return touch1.clientY - touch2.clientY > 0 ? gesture.Direction.UP : gesture.Direction.DOWN;
+                               },
+
+                       /**
+                                * Get distance indicated by position of two touches
+                                * @method getDistance
+                                * @param {Event} touch1 first touch
+                                * @param {Event} touch2 second touch
+                                * @return {number} distance
+                                * @member ns.event.gesture.utils
+                                */
+                               getDistance: function (touch1, touch2) {
+                                       var x = touch2.clientX - touch1.clientX,
+                                               y = touch2.clientY - touch1.clientY;
+
+                                       return math.sqrt((x * x) + (y * y));
+                               },
+
+                       /**
+                                * Get scale indicated by position of the first and the last touch
+                                * @method getScale
+                                * @param {Event} start start touch
+                                * @param {Event} end end touch
+                                * @return {number} scale
+                                * @member ns.event.gesture.utils
+                                */
+                               getScale: function (start, end) {
+                               // need two fingers...
+                                       if (start.length >= 2 && end.length >= 2) {
+                                               return this.getDistance(end[0], end[1]) / this.getDistance(start[0], start[1]);
+                                       }
+                                       return 1;
+                               },
+
+                       /**
+                                * Get value of rotation indicated by position
+                                * of the first and the last touch
+                                * @method getRotation
+                                * @param {Event} start start touch
+                                * @param {Event} end end touch
+                                * @return {number} angle (deg)
+                                * @member ns.event.gesture.utils
+                                */
+                               getRotation: function (start, end) {
+                               // need two fingers
+                                       if (start.length >= 2 && end.length >= 2) {
+                                               return this.getAngle(end[1], end[0]) -
+                                                       this.getAngle(start[1], start[0]);
+                                       }
+                                       return 0;
+                               },
+
+                       /**
+                                * Check if the direction is vertical
+                                * @method isVertical
+                                * @param {ns.event.gesture.Direction.LEFT|ns.event.gesture.Direction.RIGHT|ns.event.gesture.Direction.UP|ns.event.gesture.Direction.DOWN} direction start touch
+                                * @return {boolean}
+                                * @member ns.event.gesture.utils
+                                */
+                               isVertical: function (direction) {
+                                       return direction === gesture.Direction.UP || direction === gesture.Direction.DOWN;
+                               },
+
+                       /**
+                                * Check if the direction is horizontal
+                                * @method isHorizontal
+                                * @param {ns.event.gesture.Direction.LEFT|ns.event.gesture.Direction.RIGHT|ns.event.gesture.Direction.UP|ns.event.gesture.Direction.DOWN} direction start touch
+                                * @return {boolean}
+                                * @member ns.event.gesture.utils
+                                */
+                               isHorizontal: function (direction) {
+                                       return direction === gesture.Direction.LEFT || direction === gesture.Direction.RIGHT;
+                               },
+
+                       /**
+                                * Check if the direction is horizontal
+                                * @method getOrientation
+                                * @param {ns.event.gesture.Direction.LEFT|ns.event.gesture.Direction.RIGHT|ns.event.gesture.Direction.UP|ns.event.gesture.Direction.DOWN} direction
+                                * @return {boolean}
+                                * @member ns.event.gesture.utils
+                                */
+                               getOrientation: function (direction) {
+                                       return this.isVertical(direction) ? gesture.Orientation.VERTICAL : gesture.Orientation.HORIZONTAL;
+                               }
+                       };
+               }(ns, window.Math));
+
+/*global ns, define */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Gesture.Manager class
+ * Main class controls all gestures.
+ * @class ns.event.gesture.Manager
+ */
+(function (ns, window, document) {
+       "use strict";
+       
+               /**
+                * Local alias for {@link ns.event.gesture}
+                * @property {Object}
+                * @member ns.event.gesture.Manager
+                * @private
+                * @static
+                */
+               var gesture = ns.event.gesture,
+
+                       gestureUtils = gesture.utils,
+
+                       utilObject = ns.util.object,
+
+                       instance = null,
+
+                       touchCheck = /touch/,
+
+                       Manager = function () {
+                               var self = this;
+
+                               self.instances = [];
+                               self.gestureDetectors = [];
+                               self.runningDetectors = [];
+                               self.detectorRequestedBlock = null;
+
+                               self.unregisterBlockList = [];
+
+                               self.gestureEvents = {};
+                               self.velocity = null;
+
+                               self._isReadyDetecting = false;
+                               self._blockMouseEvent = false;
+                               self.touchSupport = "ontouchstart" in window;
+                       };
+
+               function sortInstances(a, b) {
+                       if (a.index < b.index) {
+                               return -1;
+                       } else if (a.index > b.index) {
+                               return 1;
+                       }
+                       return 0;
+               }
+
+               Manager.prototype = {
+                       /**
+                        * Bind start events
+                        * @method _bindStartEvents
+                        * @param {ns.event.gesture.Instance} _instance gesture instance
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _bindStartEvents: function (_instance) {
+                               var element = _instance.getElement();
+
+                               if (this.touchSupport) {
+                                       element.addEventListener("touchstart", this, {passive: false});
+                               } else {
+                                       element.addEventListener("mousedown", this, false);
+                               }
+                       },
+
+                       /**
+                        * Bind move, end and cancel events
+                        * @method _bindEvents
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _bindEvents: function () {
+                               var self = this;
+
+                               if (self.touchSupport) {
+                                       document.addEventListener("touchmove", self, {passive: false});
+                                       document.addEventListener("touchend", self, {passive: false});
+                                       document.addEventListener("touchcancel", self, {passive: false});
+                               } else {
+                                       document.addEventListener("mousemove", self);
+                                       document.addEventListener("mouseup", self);
+                               }
+                       },
+
+                       /**
+                        * Unbind start events
+                        * @method _unbindStartEvents
+                        * @param {ns.event.gesture.Instance} _instance gesture instance
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _unbindStartEvents: function (_instance) {
+                               var element = _instance.getElement();
+
+                               if (this.touchSupport) {
+                                       element.removeEventListener("touchstart", this, {passive: false});
+                               } else {
+                                       element.removeEventListener("mousedown", this, false);
+                               }
+                       },
+
+                       /**
+                        * Unbind move, end and cancel events
+                        * @method _bindEvents
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _unbindEvents: function () {
+                               var self = this;
+
+                               if (self.touchSupport) {
+                                       document.removeEventListener("touchmove", self, {passive: false});
+                                       document.removeEventListener("touchend", self, {passive: false});
+                                       document.removeEventListener("touchcancel", self, {passive: false});
+                               } else {
+                                       document.removeEventListener("mousemove", self, false);
+                                       document.removeEventListener("mouseup", self, false);
+                               }
+                       },
+
+                       /**
+                        * Detect that event should be processed by handleEvent
+                        * @param {Event} event Input event object
+                        * @return {null|string}
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _detectEventType: function (event) {
+                               var eventType = event.type;
+
+                               if (eventType.match(touchCheck)) {
+                                       this._blockMouseEvent = true;
+                               } else {
+                                       if (this._blockMouseEvent || event.which !== 1) {
+                                               return null;
+                                       }
+                               }
+                               return eventType;
+                       },
+
+                       /**
+                        * Handle event
+                        * @method handleEvent
+                        * @param {Event} event
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       handleEvent: function (event) {
+                               var self = this,
+                                       eventType = self._detectEventType(event);
+
+                               switch (eventType) {
+                                       case "mousedown":
+                                       case "touchstart":
+                                               self._start(event);
+                                               break;
+                                       case "mousemove":
+                                       case "touchmove":
+                                               self._move(event);
+                                               break;
+                                       case "mouseup":
+                                       case "touchend":
+                                               self._end(event);
+                                               break;
+                                       case "touchcancel":
+                                               self._cancel(event);
+                                               break;
+                               }
+                       },
+
+                       /**
+                        * Handler for gesture start
+                        * @method _start
+                        * @param {Event} event
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _start: function (event) {
+                               var self = this,
+                                       element = event.currentTarget,
+                                       startEvent = {},
+                                       detectors = [];
+
+                               if (!self._isReadyDetecting) {
+                                       self.resetDetecting();
+                                       self._bindEvents();
+
+                                       startEvent = self._createDefaultEventData(gesture.Event.START, event);
+
+                                       self.gestureEvents = {
+                                               start: startEvent,
+                                               last: startEvent
+                                       };
+
+                                       self.velocity = {
+                                               event: startEvent,
+                                               x: 0,
+                                               y: 0
+                                       };
+
+                                       startEvent = utilObject.fastMerge(startEvent,
+                                               self._createGestureEvent(gesture.Event.START, event));
+                                       self._isReadyDetecting = true;
+                               }
+
+                               self.instances.forEach(function (_instance) {
+                                       if (_instance.getElement() === element) {
+                                               detectors = detectors.concat(_instance.getGestureDetectors());
+                                       }
+                               }, self);
+
+                               detectors.sort(sortInstances);
+
+                               self.gestureDetectors = self.gestureDetectors.concat(detectors);
+
+                               self._detect(detectors, startEvent);
+                       },
+
+                       /**
+                        * Handler for gesture move
+                        * @method _move
+                        * @param {Event} event
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _move: function (event) {
+                               var newEvent,
+                                       self = this;
+
+                               if (self._isReadyDetecting) {
+                                       newEvent = self._createGestureEvent(gesture.Event.MOVE, event);
+                                       self._detect(self.gestureDetectors, newEvent);
+                                       self.gestureEvents.last = newEvent;
+                               }
+                       },
+
+                       /**
+                        * Handler for gesture end
+                        * @method _end
+                        * @param {Event} event
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _end: function (event) {
+                               var self = this,
+                                       newEvent = utilObject.merge(
+                                               {},
+                                               self.gestureEvents.last,
+                                               self._createDefaultEventData(gesture.Event.END, event)
+                                       );
+
+                               if (newEvent.pointers.length === 0) {
+                                       self._detect(self.gestureDetectors, newEvent);
+
+                                       self.unregisterBlockList.forEach(function (_instance) {
+                                               this.unregister(_instance);
+                                       }, self);
+
+                                       self.resetDetecting();
+                                       self._blockMouseEvent = false;
+                               }
+                       },
+
+                       /**
+                        * Handler for gesture cancel
+                        * @method _cancel
+                        * @param {Event} event
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _cancel: function (event) {
+                               var self = this;
+
+                               event = utilObject.merge(
+                                       {},
+                                       self.gestureEvents.last,
+                                       self._createDefaultEventData(gesture.Event.CANCEL, event)
+                               );
+
+                               self._detect(self.gestureDetectors, event);
+
+                               self.unregisterBlockList.forEach(function (_instance) {
+                                       this.unregister(_instance);
+                               }, self);
+
+                               self.resetDetecting();
+                               self._blockMouseEvent = false;
+                       },
+
+                       /**
+                        * Detect gesture
+                        * @method _detect
+                        * @param {Array} detectors
+                        * @param {Event} event
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _detect: function (detectors, event) {
+                               var self = this,
+                                       finishedDetectors = [];
+
+                               detectors.forEach(function (detector) {
+                                       var result;
+
+                                       if (!self.detectorRequestedBlock) {
+                                               result = detector.detect(event);
+                                               if ((result & gesture.Result.RUNNING) &&
+                                                               self.runningDetectors.indexOf(detector) < 0) {
+                                                       self.runningDetectors.push(detector);
+                                               }
+                                               if (result & gesture.Result.FINISHED) {
+                                                       finishedDetectors.push(detector);
+                                               }
+                                               if (result & gesture.Result.BLOCK) {
+                                                       self.detectorRequestedBlock = detector;
+                                               }
+                                       }
+                               });
+
+                               // remove finished detectors.
+                               finishedDetectors.forEach(function (detector) {
+                                       var idx = self.gestureDetectors.indexOf(detector);
+
+                                       if (idx > -1) {
+                                               self.gestureDetectors.splice(idx, 1);
+                                       }
+                                       idx = self.runningDetectors.indexOf(detector);
+                                       if (idx > -1) {
+                                               self.runningDetectors.splice(idx, 1);
+                                       }
+                               });
+
+                               // remove all detectors except the detector that return block result
+                               if (self.detectorRequestedBlock) {
+                                       // send to cancel event.
+                                       self.runningDetectors.forEach(function (detector) {
+                                               var cancelEvent = utilObject.fastMerge({}, event);
+
+                                               cancelEvent.eventType = gesture.Event.BLOCKED;
+                                               detector.detect(cancelEvent);
+                                       });
+                                       self.runningDetectors.length = 0;
+                                       self.gestureDetectors.length = 0;
+                                       if (finishedDetectors.indexOf(self.detectorRequestedBlock) < 0) {
+                                               self.gestureDetectors.push(self.detectorRequestedBlock);
+                                       }
+                               }
+                       },
+
+                       /**
+                        * Reset of gesture manager detector
+                        * @method resetDetecting
+                        * @member ns.event.gesture.Manager
+                        * @public
+                        */
+                       resetDetecting: function () {
+                               var self = this;
+
+                               self._isReadyDetecting = false;
+
+                               self.gestureDetectors.length = 0;
+                               self.runningDetectors.length = 0;
+                               self.detectorRequestedBlock = null;
+
+                               self.gestureEvents = {};
+                               self.velocity = null;
+
+                               self._unbindEvents();
+                       },
+
+                       /**
+                        * Create default event data
+                        * @method _createDefaultEventData
+                        * @param {string} type event type
+                        * @param {Event} event source event
+                        * @return {Object} default event data
+                        * @return {string} return.eventType
+                        * @return {number} return.timeStamp
+                        * @return {Touch} return.pointer
+                        * @return {TouchList} return.pointers
+                        * @return {Event} return.srcEvent
+                        * @return {Function} return.preventDefault
+                        * @return {Function} return.stopPropagation
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _createDefaultEventData: function (type, event) {
+                               var pointers = event.touches;
+
+                               if (!pointers) {
+                                       if (event.type === "mouseup") {
+                                               pointers = [];
+                                       } else {
+                                               event.identifier = 1;
+                                               pointers = [event];
+                                       }
+                               }
+
+                               return {
+                                       eventType: type,
+                                       timeStamp: Date.now(),
+                                       pointer: pointers[0],
+                                       pointers: pointers,
+
+                                       srcEvent: event,
+                                       preventDefault: event.preventDefault.bind(event),
+                                       stopPropagation: event.stopPropagation.bind(event)
+                               };
+                       },
+
+                       /**
+                        * Create gesture event
+                        * @method _createGestureEvent
+                        * @param {string} type event type
+                        * @param {Event} event source event
+                        * @return {Object} gesture event consist from Event class and additional properties
+                        * @return {number} return.deltaTime
+                        * @return {number} return.deltaX
+                        * @return {number} return.deltaY
+                        * @return {number} return.velocityX
+                        * @return {number} return.velocityY
+                        * @return {number} return.estimatedX
+                        * @return {number} return.estimatedY
+                        * @return {number} return.estimatedDeltaX
+                        * @return {number} return.estimatedDeltaY
+                        * @return {number} return.distance
+                        * @return {number} return.angle
+                        * @return {number} return.direction
+                        * @return {number} return.scale
+                        * @return {number} return.rotation (deg)
+                        * @return {Event} return.startEvent
+                        * @return {Event} return.lastEvent
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _createGestureEvent: function (type, event) {
+                               var self = this,
+                                       defaultEvent = self._createDefaultEventData(type, event),
+                                       startEvent = self.gestureEvents.start,
+                                       lastEvent = self.gestureEvents.last,
+                                       velocity = self.velocity,
+                                       velocityEvent = velocity.event,
+                                       delta = {
+                                               time: defaultEvent.timeStamp - startEvent.timeStamp,
+                                               x: defaultEvent.pointer.clientX - startEvent.pointer.clientX,
+                                               y: defaultEvent.pointer.clientY - startEvent.pointer.clientY
+                                       },
+                                       deltaFromLast = {
+                                               x: defaultEvent.pointer.clientX - lastEvent.pointer.clientX,
+                                               y: defaultEvent.pointer.clientY - lastEvent.pointer.clientY
+                                       },
+                                       /* pause time threshold.util. tune the number to up if it is slow */
+                                       timeDifference = gesture.defaults.estimatedPointerTimeDifference,
+                                       estimated;
+
+                               // reset start event for multi touch
+                               if (startEvent && defaultEvent.pointers.length !== startEvent.pointers.length) {
+                                       startEvent.pointers = Array.prototype.slice.call(defaultEvent.pointers);
+                               }
+
+                               if (defaultEvent.timeStamp - velocityEvent.timeStamp >
+                                               gesture.defaults.updateVelocityInterval) {
+                                       utilObject.fastMerge(velocity, gestureUtils.getVelocity(
+                                               defaultEvent.timeStamp - velocityEvent.timeStamp,
+                                               defaultEvent.pointer.clientX - velocityEvent.pointer.clientX,
+                                               defaultEvent.pointer.clientY - velocityEvent.pointer.clientY
+                                       ));
+                                       velocity.event = defaultEvent;
+                               }
+
+                               estimated = {
+                                       x: Math.round(defaultEvent.pointer.clientX +
+                                                       (timeDifference * velocity.x * (deltaFromLast.x < 0 ? -1 : 1))),
+                                       y: Math.round(defaultEvent.pointer.clientY +
+                                                       (timeDifference * velocity.y * (deltaFromLast.y < 0 ? -1 : 1)))
+                               };
+
+                               // Prevent that point goes back even though direction is not changed.
+                               if ((deltaFromLast.x < 0 && estimated.x > lastEvent.estimatedX) ||
+                                               (deltaFromLast.x > 0 && estimated.x < lastEvent.estimatedX)) {
+                                       estimated.x = lastEvent.estimatedX;
+                               }
+
+                               if ((deltaFromLast.y < 0 && estimated.y > lastEvent.estimatedY) ||
+                                               (deltaFromLast.y > 0 && estimated.y < lastEvent.estimatedY)) {
+                                       estimated.y = lastEvent.estimatedY;
+                               }
+
+                               utilObject.fastMerge(defaultEvent, {
+                                       deltaTime: delta.time,
+                                       deltaX: delta.x,
+                                       deltaY: delta.y,
+
+                                       velocityX: velocity.x,
+                                       velocityY: velocity.y,
+
+                                       estimatedX: estimated.x,
+                                       estimatedY: estimated.y,
+                                       estimatedDeltaX: estimated.x - startEvent.pointer.clientX,
+                                       estimatedDeltaY: estimated.y - startEvent.pointer.clientY,
+
+                                       distance: gestureUtils.getDistance(startEvent.pointer, defaultEvent.pointer),
+
+                                       angle: gestureUtils.getAngle(startEvent.pointer, defaultEvent.pointer),
+
+                                       direction: gestureUtils.getDirection(startEvent.pointer, defaultEvent.pointer),
+
+                                       scale: gestureUtils.getScale(startEvent.pointers, defaultEvent.pointers),
+                                       rotation: gestureUtils.getRotation(startEvent.pointers, defaultEvent.pointers),
+
+                                       startEvent: startEvent,
+                                       lastEvent: lastEvent
+                               });
+
+                               return defaultEvent;
+                       },
+
+                       /**
+                        * Register instance of gesture
+                        * @method register
+                        * @param {ns.event.gesture.Instance} instance gesture instance
+                        * @member ns.event.gesture.Manager
+                        */
+                       register: function (instance) {
+                               var self = this,
+                                       idx = self.instances.indexOf(instance);
+
+                               if (idx < 0) {
+                                       self.instances.push(instance);
+                                       self._bindStartEvents(instance);
+                               }
+                       },
+
+                       /**
+                        * Unregister instance of gesture
+                        * @method unregister
+                        * @param {ns.event.gesture.Instance} instance gesture instance
+                        * @member ns.event.gesture.Manager
+                        */
+                       unregister: function (instance) {
+                               var idx,
+                                       self = this;
+
+                               if (self.gestureDetectors.length) {
+                                       self.unregisterBlockList.push(instance);
+                               } else {
+                                       idx = self.instances.indexOf(instance);
+                                       if (idx > -1) {
+                                               self.instances.splice(idx, 1);
+                                               self._unbindStartEvents(instance);
+                                       }
+
+                                       if (!self.instances.length) {
+                                               self._destroy();
+                                       }
+                               }
+                       },
+
+                       /**
+                        * Destroy instance of Manager
+                        * @method _destroy
+                        * @member ns.event.gesture.Manager
+                        * @protected
+                        */
+                       _destroy: function () {
+                               var self = this;
+
+                               self.resetDetecting();
+                               self.instances.length = 0;
+                               self.unregisterBlockList.length = 0;
+                               self._blockMouseEvent = false;
+                               instance = null;
+                       }
+
+               };
+
+               Manager.getInstance = function () {
+                       if (!instance) {
+                               instance = new Manager();
+                       }
+                       return instance;
+               };
+
+               gesture.Manager = Manager;
+               }(ns, window, window.document));
+
+/*global ns, window, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+(function (ns) {
+       "use strict";
+                       /**
+                        * Local alias for {@link ns.event.gesture}
+                        * @property {Object}
+                        * @member ns.event.gesture.Instance
+                        * @private
+                        * @static
+                        */
+                       var gesture = ns.event.gesture,
+                       /**
+                                * Local alias for {@link ns.event.gesture.Detector}
+                                * @property {Object}
+                                * @member ns.event.gesture.Instance
+                                * @private
+                                * @static
+                                */
+                               Detector = gesture.Detector,
+                       /**
+                                * Local alias for {@link ns.event.gesture.Manager}
+                                * @property {Object}
+                                * @member ns.event.gesture.Instance
+                                * @private
+                                * @static
+                                */
+                               Manager = gesture.Manager,
+                       /**
+                                * Local alias for {@link ns.event}
+                                * @property {Object}
+                                * @member ns.event.gesture.Instance
+                                * @private
+                                * @static
+                                */
+                               events = ns.event,
+                       /**
+                                * Alias for method {@link ns.util.object.merge}
+                                * @property {Function} merge
+                                * @member ns.event.gesture.Instance
+                                * @private
+                                * @static
+                                */
+                               merge = ns.util.object.merge,
+
+                       /**
+                                * #Gesture.Instance class
+                                * Creates instance of gesture manager on element.
+                                * @param {HTMLElement} element
+                                * @param {Object} options
+                                * @class ns.event.gesture.Instance
+                                */
+                               Instance = function (element, options) {
+                                       this.element = element;
+                                       this.eventDetectors = [];
+                                       this.options = merge({}, gesture.defaults, options);
+
+                                       this.gestureManager = Manager.getInstance();
+                                       this.eventSender = merge({}, Detector.Sender, {
+                                               sendEvent: this.trigger.bind(this)
+                                       });
+                               };
+
+                       Instance.prototype = {
+                       /**
+                                * Set options
+                                * @method setOptions
+                                * @param {Object} options options
+                                * @return {ns.event.gesture.Instance}
+                                * @member ns.event.gesture.Instance
+                                */
+                               setOptions: function (options) {
+                                       merge(this.options, options);
+                                       return this;
+                               },
+
+                       /**
+                                * Add detector
+                                * @method addDetector
+                                * @param {Object} detectorStrategy strategy
+                                * @return {ns.event.gesture.Instance}
+                                * @member ns.event.gesture.Instance
+                                */
+                               addDetector: function (detectorStrategy) {
+                                       var detector = new Detector(detectorStrategy, this.eventSender),
+                                               alreadyHasDetector = !!this.eventDetectors.length;
+
+                                       this.eventDetectors.push(detector);
+
+                                       if (!!this.eventDetectors.length && !alreadyHasDetector) {
+                                               this.gestureManager.register(this);
+                                       }
+
+                                       return this;
+                               },
+
+                       /**
+                                * Remove detector
+                                * @method removeDetector
+                                * @param {Object} detectorStrategy strategy
+                                * @return {ns.event.gesture.Instance}
+                                * @member ns.event.gesture.Instance
+                                */
+                               removeDetector: function (detectorStrategy) {
+                                       var idx = this.eventDetectors.indexOf(detectorStrategy);
+
+                                       if (idx > -1) {
+                                               this.eventDetectors.splice(idx, 1);
+                                       }
+
+                                       if (!this.eventDetectors.length) {
+                                               this.gestureManager.unregister(this);
+                                       }
+
+                                       return this;
+                               },
+
+                       /**
+                                * Triggers the gesture event
+                                * @method trigger
+                                * @param {string} gestureName gestureName name
+                                * @param {Object} eventInfo data provided to event object
+                                * @member ns.event.gesture.Instance
+                                */
+                               trigger: function (gestureName, eventInfo) {
+                                       return events.trigger(this.element, gestureName, eventInfo, false);
+                               },
+
+                       /**
+                                * Get HTML element assigned to gesture event instance
+                                * @method getElement
+                                * @member ns.event.gesture.Instance
+                                */
+                               getElement: function () {
+                                       return this.element;
+                               },
+
+                       /**
+                                * Get gesture event detectors assigned to instance
+                                * @method getGestureDetectors
+                                * @member ns.event.gesture.Instance
+                                */
+                               getGestureDetectors: function () {
+                                       return this.eventDetectors;
+                               },
+
+                       /**
+                                * Destroy instance
+                                * @method destroy
+                                * @member ns.event.gesture.Instance
+                                */
+                               destroy: function () {
+                                       this.element = null;
+                                       this.eventHandlers = {};
+                                       this.gestureManager = null;
+                                       this.eventSender = null;
+                                       this.eventDetectors.length = 0;
+                               }
+                       };
+
+                       gesture.Instance = Instance;
+
+               }(ns));
+
+/*global ns, window, define */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * # Gesture Plugin: drag
+ * Plugin enables drag event.
+ *
+ * @class ns.event.gesture.Drag
+ */
+(function (ns, window, tizen) {
+       "use strict";
+       
+               /**
+                        * Local alias for {@link ns.event.gesture}
+                        * @property {Object}
+                        * @member ns.event.gesture.Drag
+                        * @private
+                        * @static
+                        */
+                       var gesture = ns.event.gesture,
+                       /**
+                                * Local alias for {@link ns.event.gesture.Detector}
+                                * @property {Object}
+                                * @member ns.event.gesture.Drag
+                                * @private
+                                * @static
+                                */
+                               gestureUtils = gesture.utils,
+
+                               Detector = gesture.Detector,
+                       /**
+                                * Alias for method {@link ns.util.object.merge}
+                                * @property {Function} merge
+                                * @member ns.event.gesture.Drag
+                                * @private
+                                * @static
+                                */
+                               merge = ns.util.object.merge,
+
+                               eventNames = {
+                                       start: "dragstart",
+                                       drag: "drag",
+                                       end: "dragend",
+                                       cancel: "dragcancel",
+                                       prepare: "dragprepare"
+                               },
+
+                       // TODO UA test will move to support.
+                               isTizenWebkit2Browser = !!window.navigator.userAgent.match(/tizen/i) && (function () {
+                                       var result = true,
+                                               version;
+
+                                       if (tizen && tizen.systeminfo && tizen.systeminfo.getCapability) {
+                                               try {
+                                                       version = tizen.systeminfo.getCapability("http://tizen.org/feature/platform.version");
+                                                       return version < "3.0";
+                                               } catch (error) {
+                                                       ns.error("Error name: " + error.name + ", message: " + error.message);
+                                               }
+                                       }
+                                       return result;
+                               })(),
+
+                               isChromeBrowser = window.navigator.userAgent.indexOf("Chrome") > -1,
+
+                               RESULTS = gesture.Result,
+
+                               Drag = Detector.plugin.create({
+
+                               /**
+                                        * Gesture name
+                                        * @property {string} [name="drag"]
+                                        * @member ns.event.gesture.Drag
+                                        */
+                                       name: "drag",
+
+                               /**
+                                        * Gesture Index
+                                        * @property {number} [index=500]
+                                        * @member ns.event.gesture.Drag
+                                        */
+                                       index: 500,
+
+                               /**
+                                        * Default values for drag gesture
+                                        * @property {Object} defaults
+                                        * @property {boolean} [defaults.blockHorizontal=false]
+                                        * @property {boolean} [defaults.blockVertical=false]
+                                        * @property {number} [defaults.threshold=20]
+                                        * @property {number} [defaults.delay=0]
+                                        * @member ns.event.gesture.Drag
+                                        */
+                                       defaults: {
+                                               blockHorizontal: false,
+                                               blockVertical: false,
+                                               threshold: 20,
+                                               delay: 0
+                                       },
+
+                               /**
+                                        * Triggered
+                                        * @property {boolean} [isTriggered=false]
+                                        * @member ns.event.gesture.Drag
+                                        */
+                                       isTriggered: false,
+
+                               /**
+                                        * Handler for drag gesture
+                                        * @method handler
+                                        * @param {Event} gestureEvent gesture event
+                                        * @param {Object} sender event's sender
+                                        * @param {Object} options options
+                                        * @return {number}
+                                        * @member ns.event.gesture.Drag
+                                        */
+                                       handler: function (gestureEvent, sender, options) {
+                                               var newGestureEvent,
+                                                       threshold = options.threshold,
+                                                       result = RESULTS.PENDING,
+                                                       direction = gestureEvent.direction;
+
+                                               if (!this.isTriggered && gestureEvent.eventType === gesture.Event.MOVE) {
+                                                       if (Math.abs(gestureEvent.deltaX) < threshold && Math.abs(gestureEvent.deltaY) < threshold) {
+                                                       // Branching statement for specifying Tizen 2.X and Tizen 3.0
+                                                               if (isChromeBrowser) {
+                                                                       gestureEvent.preventDefault();
+                                                               }
+                                                               return RESULTS.PENDING;
+                                                       }
+
+                                                       if (options.delay && gestureEvent.deltaTime < options.delay) {
+                                                               if (!isTizenWebkit2Browser) {
+                                                                       gestureEvent.preventDefault();
+                                                               }
+                                                               return RESULTS.PENDING;
+                                                       }
+
+                                                       if (options.blockHorizontal && gestureUtils.isHorizontal(gestureEvent.direction) ||
+                                                               options.blockVertical && gestureUtils.isVertical(gestureEvent.direction)) {
+                                                               return RESULTS.FINISHED;
+                                                       }
+
+                                                       this.fixedStartPointX = 0;
+                                                       this.fixedStartPointY = 0;
+                                                       if (gestureUtils.isHorizontal(gestureEvent.direction)) {
+                                                               this.fixedStartPointX = (gestureEvent.deltaX < 0 ? 1 : -1) * threshold;
+                                                       } else {
+                                                               this.fixedStartPointY = (gestureEvent.deltaY < 0 ? 1 : -1) * threshold;
+                                                       }
+                                               }
+
+                                               if (options.blockHorizontal) {
+                                                       direction = gestureEvent.deltaY < 0 ? gesture.Direction.UP : gesture.Direction.DOWN;
+                                               }
+
+                                               if (options.blockVertical) {
+                                                       direction = gestureEvent.deltaX < 0 ? gesture.Direction.LEFT : gesture.Direction.RIGHT;
+                                               }
+
+                                               newGestureEvent = merge({}, gestureEvent, {
+                                                       deltaX: gestureEvent.deltaX + this.fixedStartPointX,
+                                                       deltaY: gestureEvent.deltaY + this.fixedStartPointY,
+                                                       estimatedDeltaX: gestureEvent.estimatedDeltaX + this.fixedStartPointX,
+                                                       estimatedDeltaY: gestureEvent.estimatedDeltaY + this.fixedStartPointY,
+
+                                                       direction: direction
+                                               });
+
+                                               switch (newGestureEvent.eventType) {
+                                                       case gesture.Event.START:
+                                                               this.isTriggered = false;
+                                                               if (sender.sendEvent(eventNames.prepare, newGestureEvent) === false) {
+                                                                       result = RESULTS.FINISHED;
+                                                               }
+                                                               break;
+                                                       case gesture.Event.MOVE:
+                                                               if (!this.isTriggered && sender.sendEvent(eventNames.start, newGestureEvent) === false) {
+                                                                       newGestureEvent.preventDefault();
+                                                               }
+                                                               result = sender.sendEvent(eventNames.drag, newGestureEvent) ? RESULTS.RUNNING : RESULTS.FINISHED;
+                                                               if (result === false) {
+                                                                       newGestureEvent.preventDefault();
+                                                               }
+                                                               this.isTriggered = true;
+                                                               break;
+
+                                                       case gesture.Event.BLOCKED:
+                                                       case gesture.Event.END:
+                                                               result = RESULTS.FINISHED;
+                                                               if (this.isTriggered) {
+                                                                       if (sender.sendEvent(eventNames.end, newGestureEvent) === false) {
+                                                                               newGestureEvent.preventDefault();
+                                                                       }
+                                                                       this.isTriggered = false;
+                                                               }
+                                                               break;
+
+                                                       case gesture.Event.CANCEL:
+                                                               result = RESULTS.FINISHED;
+                                                               if (this.isTriggered) {
+                                                                       if (sender.sendEvent(eventNames.cancel, newGestureEvent) === false) {
+                                                                               newGestureEvent.preventDefault();
+                                                                       }
+                                                                       this.isTriggered = false;
+                                                               }
+                                                               break;
+                                               }
+
+                                               return result;
+                                       }
+                               });
+
+                       ns.event.gesture.Drag = Drag;
+               }(ns, window, window.tizen));
+
+/*global ns, window, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Gesture Plugin: swipe
+ * Plugin enables swipe event.
+ *
+ * @class ns.event.gesture.Swipe
+ */
+(function (ns) {
+       "use strict";
+       
+                       var gesture = ns.event.gesture,
+                               Result = gesture.Result,
+                               Detector = gesture.Detector,
+                               Swipe = Detector.plugin.create({
+                               /**
+                                        * Gesture name
+                                        * @property {string} [name="swipe"]
+                                        * @member ns.event.gesture.Swipe
+                                        */
+                                       name: "swipe",
+
+                               /**
+                                        * Gesture Index
+                                        * @property {number} [index=400]
+                                        * @member ns.event.gesture.Swipe
+                                        */
+                                       index: 400,
+
+                               /**
+                                        * Default values for swipe gesture
+                                        * @property {Object} defaults
+                                        * @property {number} [defaults.timeThreshold=400]
+                                        * @property {number} [defaults.velocity=0.6]
+                                        * @property {ns.event.gesture.HORIZONTAL|ns.event.gesture.VERTICAL} [defaults.orientation=ns.event.gesture.HORIZONTAL]
+                                        * @member ns.event.gesture.Swipe
+                                        */
+                                       defaults: {
+                                               timeThreshold: 400,
+                                               velocity: 0.6,
+                                               orientation: gesture.Orientation.HORIZONTAL
+                                       },
+
+                               /**
+                                        * Handler for swipe gesture
+                                        * @method handler
+                                        * @param {Event} gestureEvent gesture event
+                                        * @param {Object} sender event's sender
+                                        * @param {Object} options options
+                                        * @return {number}
+                                        * @member ns.event.gesture.Swipe
+                                        */
+                                       handler: function (gestureEvent, sender, options) {
+                                               var result = Result.PENDING,
+                                                       velocity = options.velocity;
+
+                                               if (gestureEvent.eventType === gesture.Event.END) {
+                                                       if ((gestureEvent.deltaTime > options.timeThreshold) ||
+                                                               (options.orientation !== gesture.utils.getOrientation(gestureEvent.direction))) {
+                                                               result = Result.FINISHED;
+                                                       } else if (gestureEvent.velocityX > velocity || gestureEvent.velocityY > velocity) {
+                                                               sender.sendEvent(this.name, gestureEvent);
+                                                               result = Result.FINISHED | Result.BLOCK;
+                                                       }
+                                               }
+
+                                               return result;
+                                       }
+                               });
+
+                       gesture.Swipe = Swipe;
+
+               }(ns));
+
+/*global ns, window, define */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * # Gesture Plugin: pinch
+ * Plugin enables pinch event.
+ *
+ * @class ns.event.gesture.Pinch
+ */
+(function (ns) {
+       "use strict";
+       
+               /**
+                        * Local alias for {@link ns.event.gesture}
+                        * @property {Object}
+                        * @member ns.event.gesture.Pinch
+                        * @private
+                        * @static
+                        */
+                       var gesture = ns.event.gesture,
+                       /**
+                                * Local alias for {@link ns.event.gesture.Detector}
+                                * @property {Object}
+                                * @member ns.event.gesture.Pinch
+                                * @private
+                                * @static
+                                */
+                               Result = gesture.Result,
+
+                               Detector = ns.event.gesture.Detector,
+                               eventNames = {
+                                       start: "pinchstart",
+                                       move: "pinchmove",
+                                       end: "pinchend",
+                                       cancel: "pinchcancel",
+                                       in: "pinchin",
+                                       out: "pinchout"
+                               },
+
+                               Pinch = Detector.plugin.create({
+                               /**
+                                        * Gesture name
+                                        * @property {string} [name="pinch"]
+                                        * @member ns.event.gesture.Pinch
+                                        */
+                                       name: "pinch",
+
+                               /**
+                                        * Gesture Index
+                                        * @property {number} [index=300]
+                                        * @member ns.event.gesture.Pinch
+                                        */
+                                       index: 300,
+
+                               /**
+                                        * Array of possible pinch events
+                                        * @property {Object} eventNames
+                                        * @member ns.event.gesture.Pinch
+                                        */
+                                       eventNames: eventNames,
+
+                               /**
+                                        * Default values for pinch gesture
+                                        * @property {Object} defaults
+                                        * @property {number} [defaults.velocity=0.6]
+                                        * @property {number} [defaults.timeThreshold=400]
+                                        * @member ns.event.gesture.Pinch
+                                        */
+                                       defaults: {
+                                               velocity: 0.6,
+                                               timeThreshold: 400
+                                       },
+
+                               /**
+                                        * Triggered
+                                        * @property {boolean} [isTriggered=false]
+                                        * @member ns.event.gesture.Pinch
+                                        */
+                                       isTriggered: false,
+
+                               /**
+                                        * Handler for pinch gesture
+                                        * @method handler
+                                        * @param {Event} gestureEvent gesture event
+                                        * @param {Object} sender event's sender
+                                        * @param {Object} options options
+                                        * @return {number}
+                                        * @member ns.event.gesture.Pinch
+                                        */
+                                       handler: function (gestureEvent, sender, options) {
+                                               var result = Result.PENDING,
+                                                       prevented;
+
+                                               switch (gestureEvent.eventType) {
+                                                       case gesture.Event.MOVE:
+                                                               if (gestureEvent.pointers.length === 1 && gestureEvent.distance > 35) {
+                                                                       result = Result.FINISHED;
+                                                               } else if (!this.isTriggered && gestureEvent.pointers.length >= 2) {
+                                                                       this.isTriggered = true;
+                                                                       if (sender.sendEvent(eventNames.start, gestureEvent) === false) {
+                                                                               gestureEvent.preventDefault();
+                                                                       }
+                                                                       result = Result.RUNNING;
+                                                               } else if (this.isTriggered) {
+                                                                       if ((gestureEvent.deltaTime < options.timeThreshold) &&
+                                                                               (gestureEvent.velocityX > options.velocity || gestureEvent.velocityY > options.velocity)) {
+                                                                               if (gestureEvent.scale < 1) {
+                                                                                       prevented = sender.sendEvent(eventNames.in, gestureEvent);
+                                                                               } else {
+                                                                                       prevented = sender.sendEvent(eventNames.out, gestureEvent);
+                                                                               }
+                                                                               if (prevented === false) {
+                                                                                       gestureEvent.preventDefault();
+                                                                               }
+                                                                               this.isTriggered = false;
+                                                                               result = Result.FINISHED | Result.BLOCK;
+                                                                               return result;
+                                                                       } else {
+                                                                               if (sender.sendEvent(eventNames.move, gestureEvent) === false) {
+                                                                                       gestureEvent.preventDefault();
+                                                                               }
+                                                                               result = Result.RUNNING;
+                                                                       }
+                                                               }
+                                                               break;
+                                                       case gesture.Event.BLOCKED:
+                                                       case gesture.Event.END:
+                                                               if (this.isTriggered) {
+                                                                       if (sender.sendEvent(eventNames.end, gestureEvent) === false) {
+                                                                               gestureEvent.preventDefault();
+                                                                       }
+                                                                       this.isTriggered = false;
+                                                                       result = Result.FINISHED;
+                                                               }
+                                                               break;
+                                                       case gesture.Event.CANCEL:
+                                                               if (this.isTriggered) {
+                                                                       if (sender.sendEvent(eventNames.cancel, gestureEvent) === false) {
+                                                                               gestureEvent.preventDefault();
+                                                                       }
+                                                                       this.isTriggered = false;
+                                                                       result = Result.FINISHED;
+                                                               }
+                                                               break;
+                                               }
+                                               return result;
+                                       }
+                               });
+
+                       ns.event.gesture.Pinch = Pinch;
+               }(ns));
+
+/*global ns, window, define */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Gesture Plugin: longPress
+ * Plugin enables long press event.
+ *
+ * @class ns.event.gesture.LongPress
+ */
+(function (ns) {
+       "use strict";
+       
+               /**
+                        * Local alias for {@link ns.event.gesture}
+                        * @property {Object}
+                        * @member ns.event.gesture.LongPress
+                        * @private
+                        * @static
+                        */
+                       var gesture = ns.event.gesture,
+                       /**
+                                * Local alias for {@link ns.event.gesture.Detector}
+                                * @property {Object}
+                                * @member ns.event.gesture.LongPress
+                                * @private
+                                * @static
+                                */
+                               Detector = gesture.Detector,
+
+                               LongPress = Detector.plugin.create({
+                               /**
+                                        * Gesture name
+                                        * @property {string} [name="longpress"]
+                                        * @member ns.event.gesture.LongPress
+                                        */
+                                       name: "longpress",
+
+                               /**
+                                        * Gesture Index
+                                        * @property {number} [index=200]
+                                        * @member ns.event.gesture.LongPress
+                                        */
+                                       index: 600,
+
+                               /**
+                                        * Default values for longPress gesture
+                                        * @property {Object} defaults
+                                        * @property {number} [defaults.timeThreshold=400]
+                                        * @property {number} [defaults.longPressDistanceThreshold=15]
+                                        * @property {boolean} [defaults.preventClick]
+                                        * @member ns.event.gesture.LongPress
+                                        */
+                                       defaults: {
+                                               longPressTimeThreshold: 750,
+                                               longPressDistanceThreshold: 20,
+                                               preventClick: true
+                                       },
+
+                               /**
+                                        * IsTriggered
+                                        * @property {boolean} [isTriggered=false]
+                                        * @member ns.event.gesture.LongPress
+                                        */
+                                       isTriggered: false,
+
+                               /**
+                                        * longPressTimeOutId
+                                        * @property {number} [longPressTimeOutId=0]
+                                        * @member ns.event.gesture.LongPress
+                                        */
+                                       longPressTimeOutId: 0,
+
+                               /**
+                                        * Handler for longPress gesture
+                                        * @method handler
+                                        * @param {Event} gestureEvent gesture event
+                                        * @param {Object} sender event's sender
+                                        * @param {Object} options options
+                                        * @return {number}
+                                        * @member ns.event.gesture.LongPress
+                                        */
+                                       handler: function (gestureEvent, sender, options) {
+                                               var result = gesture.Result.PENDING;
+
+                                               switch (gestureEvent.eventType) {
+                                                       case gesture.Event.START:
+                                                               this.isTriggered = false;
+                                                               this.longPressTimeOutId = setTimeout(function () {
+                                                                       this.isTriggered = true;
+                                                                       sender.sendEvent(this.name, gestureEvent);
+                                                               }.bind(this), options.longPressTimeThreshold);
+                                                               break;
+
+                                                       case gesture.Event.MOVE:
+                                                               if (gestureEvent.distance > options.longPressDistanceThreshold && !this.isTriggered) {
+                                                                       clearTimeout(this.longPressTimeOutId);
+                                                                       result = gesture.Result.FINISHED;
+                                                               }
+                                                               break;
+
+                                                       case gesture.Event.END:
+                                                               if (!this.isTriggered) {
+                                                                       clearTimeout(this.longPressTimeOutId);
+                                                               } else if (options.preventClick) {
+                                                                       gestureEvent.preventDefault();
+                                                               }
+                                                               result = gesture.Result.FINISHED;
+                                                               break;
+                                               }
+                                               return result;
+                                       }
+                               });
+
+                       gesture.LongPress = LongPress;
+
+               }(ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Scroller namespace
+ * Namespace contains classes and objects connected with scroller widget.
+ * @class ns.widget.core.scroller
+ * @internal
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function (window, ns) {
+       "use strict";
+                               ns.widget.core.scroller = ns.widget.core.scroller || {};
+                       }(window, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * #Effect namespace
+ * Namespace with effects for scroller widget.
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @internal
+ * @class ns.widget.core.scroller.effect
+ */
+(function (window, ns) {
+       "use strict";
+                               ns.widget.core.scroller.effect = ns.widget.core.scroller.effect || {};
+                       }(window, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * # Bouncing effect
+ * Bouncing effect for scroller widget.
+ * @class ns.widget.core.scroller.effect.Bouncing
+ * @internal
+ * @since 2.3
+ */
+(function (document, ns) {
+       "use strict";
+                               // scroller.start event trigger when user try to move scroller
+                       var utilsObject = ns.util.object,
+                               selectors = ns.util.selectors,
+                               Bouncing = function (scrollerElement, options) {
+                                       var self = this;
+
+                                       self._orientation = null;
+                                       self._maxScrollValue = null;
+                                       self._container = null;
+                                       self._effectElement = {
+                                               top: null,
+                                               bottom: null,
+                                               left: null,
+                                               right: null
+                                       }
+
+                                       self.options = utilsObject.merge({}, Bouncing.defaults, {scrollEndEffectArea: ns.getConfig("scrollEndEffectArea", Bouncing.defaults.scrollEndEffectArea)});
+                                       /**
+                                        * target element for bouncing effect
+                                        * @property {HTMLElement} targetElement
+                                        * @member ns.widget.core.scroller.effect.Bouncing
+                                        */
+                                       self._targetElement = null;
+
+                                       self._isShow = false;
+                                       self._isDrag = false;
+                                       self._isShowAnimating = false;
+                                       self._isHideAnimating = false;
+
+                                       self._create(scrollerElement, options);
+                               },
+                               Orientation = {
+                                       VERTICAL: "vertical",
+                                       HORIZONTAL: "horizontal",
+                                       VERTICAL_HORIZONTAL: "vertical-horizontal"
+                               },
+                               endEffectAreaType = {
+                                       content: "content",
+                                       screen: "screen"
+                               },
+                               defaults = {
+                                       duration: 500,
+                                       scrollEndEffectArea: "content"
+                               },
+                               classes = {
+                                       bouncingEffect: "ui-scrollbar-bouncing-effect",
+                                       page: "ui-page",
+                                       left: "ui-left",
+                                       right: "ui-right",
+                                       top: "ui-top",
+                                       bottom: "ui-bottom",
+                                       hide: "ui-hide",
+                                       show: "ui-show"
+                               };
+
+                       Bouncing.Orientation = Orientation;
+
+                       Bouncing.defaults = defaults;
+
+                       Bouncing.prototype = {
+                               _create: function (scrollerElement, options) {
+                                       var self = this;
+
+                                       if (self.options.scrollEndEffectArea === endEffectAreaType.content) {
+                                               self._container = scrollerElement;
+                                       } else {
+                                               self._container = selectors.getClosestByClass(scrollerElement, classes.page);
+                                       }
+
+                                       self._orientation = options.orientation;
+
+                                       if (self._orientation === Orientation.HORIZONTAL || self._orientation == Orientation.VERTICAL) {
+                                               self._maxScrollValue = self._getValue(options.maxScrollX, options.maxScrollY);
+                                       } else {
+                                               self._maxScrollValue = {
+                                                       x: options.maxScrollX,
+                                                       y: options.maxScrollY
+                                               }
+                                       }
+
+                                       self._initLayout();
+                               },
+
+                               _createDivElement: function () {
+                                       return document.createElement("DIV");
+                               },
+
+                               _initLayout: function () {
+                                       var self = this,
+                                               leftEffectElement = null,
+                                               rightEffectElement = null,
+                                               topEffectElement = null,
+                                               bottomEffectElement = null,
+                                               className = classes.bouncingEffect;
+
+                                       if (self._orientation === Orientation.HORIZONTAL || self._orientation == Orientation.VERTICAL_HORIZONTAL) {
+                                               leftEffectElement = self._createDivElement();
+                                               rightEffectElement = self._createDivElement();
+                                               leftEffectElement.className = className + " " + classes.left;
+                                               rightEffectElement.className = className + " " + classes.right;
+                                               self._container.appendChild(leftEffectElement);
+                                               self._container.appendChild(rightEffectElement);
+                                               self._registerAnimationEnd(leftEffectElement);
+                                               self._registerAnimationEnd(rightEffectElement);
+                                               self._effectElement.left = leftEffectElement;
+                                               self._effectElement.right = rightEffectElement;
+                                       }
+
+                                       if (self._orientation === Orientation.VERTICAL || self._orientation == Orientation.VERTICAL_HORIZONTAL) {
+                                               topEffectElement = self._createDivElement();
+                                               bottomEffectElement = self._createDivElement();
+                                               topEffectElement.className = className + " " + classes.top;
+                                               bottomEffectElement.className = className + " " + classes.bottom;
+                                               self._container.appendChild(topEffectElement);
+                                               self._container.appendChild(bottomEffectElement);
+                                               self._registerAnimationEnd(topEffectElement);
+                                               self._registerAnimationEnd(bottomEffectElement);
+                                               self._effectElement.top = topEffectElement;
+                                               self._effectElement.bottom = bottomEffectElement;
+                                       }
+                               },
+
+                               _registerAnimationEnd: function (element) {
+                                       element.addEventListener("animationEnd", this);
+                                       element.addEventListener("webkitAnimationEnd", this);
+                                       element.addEventListener("mozAnimationEnd", this);
+                                       element.addEventListener("msAnimationEnd", this);
+                                       element.addEventListener("oAnimationEnd", this);
+                               },
+
+                               _unregisterAnimationEnd: function (element) {
+                                       element.removeEventListener("animationEnd", this);
+                                       element.removeEventListener("webkitAnimationEnd", this);
+                                       element.removeEventListener("mozAnimationEnd", this);
+                                       element.removeEventListener("msAnimationEnd", this);
+                                       element.removeEventListener("oAnimationEnd", this);
+                               },
+
+                               /**
+                                * ...
+                                * @method drag
+                                * @param {number} x
+                                * @param {number} y
+                                * @member ns.widget.core.scroller.effect.Bouncing
+                                */
+                               drag: function (x, y) {
+                                       this._isDrag = true;
+                                       this._checkAndShow(x, y);
+                               },
+
+                               /**
+                                * ...
+                                * @method dragEnd
+                                * @member ns.widget.core.scroller.effect.Bouncing
+                                */
+                               dragEnd: function () {
+                                       var self = this;
+
+                                       if (self._isShow && !self._isShowAnimating && !self._isHideAnimating) {
+                                               self._beginHide();
+                                       }
+
+                                       self._isDrag = false;
+                               },
+
+                               /**
+                                * Shows effect.
+                                * @method show
+                                * @member ns.widget.core.scroller.effect.Bouncing
+                                */
+                               show: function () {
+                                       var self = this;
+
+                                       if (self._targetElement) {
+                                               self._isShow = true;
+                                               self._beginShow();
+                                       }
+                               },
+
+                               /**
+                                * Hides effect.
+                                * @method hide
+                                * @member ns.widget.core.scroller.effect.Bouncing
+                                */
+                               hide: function () {
+                                       var self = this;
+
+                                       if (self._isShow) {
+                                               self._targetElement.style.display = "none";
+                                               self._targetElement.classList.remove(classes.hide);
+                                               self._targetElement.classList.remove(classes.show);
+                                       }
+                                       self._isShow = false;
+                                       self._isShowAnimating = false;
+                                       self._isHideAnimating = false;
+                                       self._targetElement = null;
+                               },
+
+                               _checkAndShow: function (x, y) {
+                                       var self = this,
+                                               val = null;
+
+                                       if (!self._isShow) {
+                                               if (self._orientation === Orientation.HORIZONTAL || self._orientation === Orientation.VERTICAL) {
+                                                       val = self._getValue(x, y);
+                                                       if (val >= 0) {
+                                                               self._targetElement = self._getMinEffectElement();
+                                                       } else if (val <= self._maxScrollValue) {
+                                                               self._targetElement = self._getMaxEffectElement();
+                                                       }
+                                               } else {
+                                                       // Handle bouncing in both orientations.
+                                                       if (y == 0) {
+                                                               self._targetElement = self._effectElement.top;
+                                                       } else if (y == -self._maxScrollValue.y) {
+                                                               self._targetElement = self._effectElement.bottom;
+                                                       } else if (x == 0) {
+                                                               self._targetElement = self._effectElement.left;
+                                                       } else if (x == -self._maxScrollValue.x) {
+                                                               self._targetElement = self._effectElement.right;
+                                                       }
+                                               }
+                                               self.show();
+                                       } else if (self._isShow && !self._isDrag && !self._isShowAnimating && !self._isHideAnimating) {
+                                               self._beginHide();
+                                       }
+                               },
+
+                               _getValue: function (x, y) {
+                                       if (this._orientation === Orientation.VERTICAL_HORIZONTAL) {
+                                               return null;
+                                       }
+                                       return this._orientation === Orientation.HORIZONTAL ? x : y;
+                               },
+
+                               _getMinEffectElement: function () {
+                                       var self = this;
+
+                                       if (self._orientation === Orientation.VERTICAL_HORIZONTAL) {
+                                               return null;
+                                       }
+                                       return self._orientation === Orientation.HORIZONTAL ? self._effectElement.left : self._effectElement.top;
+                               },
+
+                               _getMaxEffectElement: function () {
+                                       var self = this;
+
+                                       if (self._orientation === Orientation.VERTICAL_HORIZONTAL) {
+                                               return null;
+                                       }
+                                       return self._orientation === Orientation.HORIZONTAL ? self._effectElement.right : self._effectElement.bottom;
+                               },
+
+                               _beginShow: function () {
+                                       var self = this;
+
+                                       if (!self._targetElement || self._isShowAnimating) {
+                                               return;
+                                       }
+
+                                       self._targetElement.style.display = "block";
+
+                                       self._targetElement.classList.remove(classes.hide);
+                                       self._targetElement.classList.add(classes.show);
+
+                                       self._isShowAnimating = true;
+                                       self._isHideAnimating = false;
+                               },
+
+                               _finishShow: function () {
+                                       var self = this;
+
+                                       self._isShowAnimating = false;
+                                       if (!self._isDrag) {
+                                               self._targetElement.classList.remove(classes.show);
+                                               self._beginHide();
+                                       }
+                               },
+
+                               _beginHide: function () {
+                                       var self = this;
+
+                                       if (self._isHideAnimating) {
+                                               return;
+                                       }
+
+                                       self._targetElement.classList.remove(classes.show);
+                                       self._targetElement.classList.add(classes.hide);
+
+                                       self._isHideAnimating = true;
+                                       self._isShowAnimating = false;
+                               },
+
+                               _finishHide: function () {
+                                       var self = this;
+
+                                       self._isHideAnimating = false;
+                                       self._targetElement.classList.remove(classes.hide);
+                                       self.hide();
+                                       self._checkAndShow();
+                               },
+
+                               /**
+                                * Supports events.
+                                * @method handleEvent
+                                * @param {Event} event
+                                * @member ns.widget.core.scroller.effect.Bouncing
+                                */
+                               handleEvent: function (event) {
+                                       if (event.type.toLowerCase().indexOf("animationend") > -1 && event.animationName.charAt(0) !== "-") {
+                                               if (this._isShowAnimating) {
+                                                       this._finishShow();
+                                               } else if (this._isHideAnimating) {
+                                                       this._finishHide();
+                                               }
+                                       }
+                               },
+
+                               /**
+                                * Destroys effect.
+                                * @method destroy
+                                * @member ns.widget.core.scroller.effect.Bouncing
+                                */
+                               destroy: function () {
+                                       var self = this,
+                                               topEffectElement = self._effectElement.top,
+                                               bottomEffectElement = self._effectElement.bottom,
+                                               leftEffectElement = self._effectElement.left,
+                                               rightEffectElement = self._effectElement.right;
+
+                                       if (topEffectElement) {
+                                               self._unregisterAnimationEnd(topEffectElement);
+                                               self._container.removeChild(topEffectElement);
+                                       }
+
+                                       if (bottomEffectElement) {
+                                               self._unregisterAnimationEnd(bottomEffectElement);
+                                               self._container.removeChild(bottomEffectElement);
+                                       }
+
+                                       if (leftEffectElement) {
+                                               self._unregisterAnimationEnd(leftEffectElement);
+                                               self._container.removeChild(leftEffectElement);
+                                       }
+
+                                       if (rightEffectElement) {
+                                               self._unregisterAnimationEnd(rightEffectElement);
+                                               self._container.removeChild(rightEffectElement);
+                                       }
+
+                                       self._container = null;
+                                       self._effectElement = null;
+                                       self._targetElement = null;
+
+                                       self._isShow = null;
+                                       self._orientation = null;
+                                       self._maxScrollValue = null;
+                               }
+                       };
+
+                       ns.widget.core.scroller.effect.Bouncing = Bouncing;
+                       }(window.document, ns));
+
+/*global window, define, Event, console, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * # Scroller Widget
+ * Widget creates scroller on content.
+ * @class ns.widget.core.scroller.Scroller
+ * @since 2.3
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               // scroller.start event trigger when user try to move scroller
+                       var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               utilsObject = ns.util.object,
+                               utilsEvents = ns.event,
+                               prototype = new BaseWidget(),
+                               EffectBouncing = ns.widget.core.scroller.effect.Bouncing,
+                               eventType = {
+                                       /**
+                                        * event trigger when scroller start
+                                        * @event scrollstart
+                                        */
+                                       START: "scrollstart",
+                                       /**
+                                        * event trigger when scroller move
+                                        * @event scrollmove
+                                        */
+                                       MOVE: "scrollmove",
+                                       /**
+                                        * event trigger when scroller end
+                                        * @event scrollend
+                                        */
+                                       END: "scrollend",
+                                       /**
+                                        * event trigger when scroll is cancel
+                                        * @event scrollcancel
+                                        */
+                                       CANCEL: "scrollcancel"
+                               },
+
+                               /*
+                                * this option is related operation of scroll bar.
+                                * the value is true, scroll bar is shown during touching screen even if content doesn't scroll.
+                                * the value is false, scroll bar disappear when there is no movement of the scroll bar.
+                                */
+                               _keepShowingScrollbarOnTouch = false,
+
+                               Scroller = function () {
+                               };
+
+                       Scroller.Orientation = {
+                               VERTICAL: "vertical",
+                               HORIZONTAL: "horizontal"
+                       };
+
+                       Scroller.EventType = eventType;
+
+                       prototype._build = function (element) {
+                               if (element.children.length !== 1) {
+                                       ns.error("[Scroller] Scroller should have only one child.");
+                               } else {
+
+                                       this.scroller = element.children[0];
+                                       this.scrollerStyle = this.scroller.style;
+
+                                       this.bouncingEffect = null;
+                                       this.scrollbar = null;
+
+                                       this.scrollerWidth = 0;
+                                       this.scrollerHeight = 0;
+                                       this.scrollerOffsetX = 0;
+                                       this.scrollerOffsetY = 0;
+
+                                       this.maxScrollX = 0;
+                                       this.maxScrollY = 0;
+
+                                       this.startScrollerOffsetX = 0;
+                                       this.startScrollerOffsetY = 0;
+
+                                       this.orientation = null;
+
+                                       this.enabled = true;
+                                       this.scrolled = false;
+                                       this.dragging = false;
+                                       this.scrollCanceled = false;
+                               }
+
+                               return element;
+                       };
+
+                       prototype._configure = function () {
+                               /**
+                                * @property {Object} options Options for widget
+                                * @property {number} [options.scrollDelay=0]
+                                * @property {number} [options.threshold=10]
+                                * @property {""|"bar"|"tab"} [options.scrollbar=""]
+                                * @property {boolean} [options.useBouncingEffect=true]
+                                * @property {"vertical"|"horizontal"} [options.orientation="vertical"]
+                                * @member ns.widget.core.Scroller
+                                */
+                               this.options = utilsObject.merge({}, this.options, {
+                                       scrollDelay: 0,
+                                       threshold: 30,
+                                       scrollbar: "",
+                                       useBouncingEffect: true,
+                                       orientation: "vertical" // vertical or horizontal,
+                               });
+                       };
+
+                       prototype._init = function (element) {
+                               var scroller = null,
+                                       options = this.options,
+                                       scrollerChildren = null,
+                                       elementStyle = element.style,
+                                       scrollerStyle = null,
+                                       elementHalfWidth = element.offsetWidth / 2,
+                                       elementHalfHeight = element.offsetHeight / 2;
+
+                               scroller = element.children[0];
+                               this.scroller = scroller;
+                               scrollerStyle = scroller.style,
+                               this.scrollerStyle = scrollerStyle;
+                               scrollerChildren = scroller.children;
+
+                               this.orientation = this.orientation ||
+                                       (options.orientation === "horizontal" ? Scroller.Orientation.HORIZONTAL : Scroller.Orientation.VERTICAL);
+                               this.scrollerWidth = scroller.offsetWidth;
+                               this.scrollerHeight = scroller.offsetHeight;
+
+                               if (scrollerChildren.length) {
+                                       this.maxScrollX = elementHalfWidth - this.scrollerWidth + scrollerChildren[scrollerChildren.length - 1].offsetWidth / 2;
+                                       this.maxScrollY = elementHalfHeight - this.scrollerHeight + scrollerChildren[scrollerChildren.length - 1].offsetHeight / 2;
+                                       this.minScrollX = elementHalfWidth - scrollerChildren[0].offsetWidth / 2;
+                                       this.minScrollY = elementHalfHeight - scrollerChildren[0].offsetHeight / 2;
+                               } else {
+                                       this.maxScrollY = 360;
+                                       this.minScrollY = 0;
+                               }
+
+                               this.scrolled = false;
+                               this.touching = true;
+                               this.scrollCanceled = false;
+
+                               if (this.orientation === Scroller.Orientation.HORIZONTAL) {
+                                       this.maxScrollY = 0;
+                               } else {
+                                       this.maxScrollX = 0;
+                               }
+                               elementStyle.overflow = "hidden";
+                               elementStyle.position = "relative";
+                               scrollerStyle.position = "absolute";
+                               scrollerStyle.top = "0px";
+                               scrollerStyle.left = "0px";
+                               scrollerStyle.width = this.scrollerWidth + "px";
+                               scrollerStyle.height = this.scrollerHeight + "px";
+                               this._initScrollbar();
+                               this._initBouncingEffect();
+                               return element;
+                       };
+
+                       prototype._initScrollbar = function () {
+                               var type = this.options.scrollbar,
+                                       scrollbarType;
+
+                               if (type) {
+                                       scrollbarType = ns.widget.core.scroller.scrollbar.type[type];
+                                       if (scrollbarType) {
+                                               this.scrollbar = engine.instanceWidget(this.element, "ScrollBar", {
+                                                       type: scrollbarType,
+                                                       orientation: this.orientation
+                                               });
+                                       }
+                               }
+                       };
+
+                       prototype._initBouncingEffect = function () {
+                               var o = this.options;
+
+                               if (o.useBouncingEffect) {
+                                       this.bouncingEffect = new EffectBouncing(this.element, {
+                                               maxScrollX: this.maxScrollX,
+                                               maxScrollY: this.maxScrollY,
+                                               orientation: this.orientation
+                                       });
+                               }
+                       };
+
+                       prototype._resetLayout = function () {
+                               var elementStyle = this.element.style,
+                                       scrollerStyle = this.scrollerStyle;
+
+                               elementStyle.overflow = "hidden";
+                               elementStyle.position = "relative";
+
+                               if (scrollerStyle) {
+                                       scrollerStyle.position = "";
+                                       scrollerStyle.top = "";
+                                       scrollerStyle.left = "";
+                                       scrollerStyle.width = "";
+                                       scrollerStyle.height = "";
+
+                                       scrollerStyle["-webkit-transform"] = "";
+                                       scrollerStyle["-moz-transition"] = "";
+                                       scrollerStyle["-ms-transition"] = "";
+                                       scrollerStyle["-o-transition"] = "";
+                                       scrollerStyle["transition"] = "";
+                               }
+                       };
+
+                       prototype._bindEvents = function () {
+                               ns.event.enableGesture(
+                                       this.scroller,
+
+                                       new ns.event.gesture.Drag({
+                                               threshold: this.options.threshold,
+                                               delay: this.options.scrollDelay,
+                                               blockVertical: this.orientation === Scroller.Orientation.HORIZONTAL,
+                                               blockHorizontal: this.orientation === Scroller.Orientation.VERTICAL
+                                       })
+                               );
+
+                               utilsEvents.on(this.scroller, "drag dragstart dragend dragcancel", this);
+                               window.addEventListener("resize", this);
+                       };
+
+                       prototype._unbindEvents = function () {
+                               if (this.scroller) {
+                                       ns.event.disableGesture(this.scroller);
+                                       utilsEvents.off(this.scroller, "drag dragstart dragend dragcancel", this);
+                                       window.removeEventListener("resize", this);
+                               }
+                       };
+
+                       /* jshint -W086 */
+                       prototype.handleEvent = function (event) {
+                               switch (event.type) {
+                                       case "dragstart":
+                                               this._start(event);
+                                               break;
+                                       case "drag":
+                                               this._move(event);
+                                               break;
+                                       case "dragend":
+                                               this._end(event);
+                                               break;
+                                       case "dragcancel":
+                                               this._cancel(event);
+                                               break;
+                                       case "resize":
+                                               this.refresh();
+                                               break;
+                               }
+                       };
+
+                       prototype._refresh = function () {
+                               this._unbindEvents();
+                               this._clear();
+                               this._init(this.element);
+                               this._bindEvents();
+                       };
+
+                       /**
+                        * Scrolls to new position.
+                        * @method scrollTo
+                        * @param {number} x
+                        * @param {number} y
+                        * @param {number} duration
+                        * @member ns.widget.core.scroller.Scroller
+                        */
+                       prototype.scrollTo = function (x, y, duration) {
+                               this._translate(x, y, duration);
+                               this._translateScrollbar(x, y, duration);
+                       };
+
+                       prototype._translate = function (x, y, duration) {
+                               var translate,
+                                       transition = {
+                                               normal: "none",
+                                               webkit: "none",
+                                               moz: "none",
+                                               ms: "none",
+                                               o: "none"
+                                       },
+                                       scrollerStyle = this.scrollerStyle;
+
+                               if (duration) {
+                                       transition.normal = "transform " + duration / 1000 + "s ease-out";
+                                       transition.webkit = "-webkit-transform " + duration / 1000 + "s ease-out";
+                                       transition.moz = "-moz-transform " + duration / 1000 + "s ease-out";
+                                       transition.ms = "-ms-transform " + duration / 1000 + "s ease-out";
+                                       transition.o = "-o-transform " + duration / 1000 + "s ease-out";
+                               }
+                               translate = "translate3d(" + x + "px," + y + "px, 0)";
+
+                               scrollerStyle["-webkit-transform"] =
+                                       scrollerStyle["-moz-transform"] =
+                                               scrollerStyle["-ms-transform"] =
+                                                       scrollerStyle["-o-transform"] =
+                                                               scrollerStyle.transform = translate;
+                               scrollerStyle.transition = transition.normal;
+                               scrollerStyle["-webkit-transition"] = transition.webkit;
+                               scrollerStyle["-moz-transition"] = transition.moz;
+                               scrollerStyle["-ms-transition"] = transition.ms;
+                               scrollerStyle["-o-transition"] = transition.o;
+
+                               this.scrollerOffsetX = window.parseInt(x, 10);
+                               this.scrollerOffsetY = window.parseInt(y, 10);
+                       };
+
+                       prototype._translateScrollbar = function (x, y, duration, autoHidden) {
+                               if (!this.scrollbar) {
+                                       return;
+                               }
+
+                               this.scrollbar.translate(this.orientation === Scroller.Orientation.HORIZONTAL ? -x : -y, duration, autoHidden);
+                       };
+
+                       prototype._start = function () {
+                               var self = this;
+
+                               self.scrolled = false;
+                               self.dragging = true;
+                               self.scrollCanceled = false;
+                               self.startScrollerOffsetX = self.scrollerOffsetX;
+                               self.startScrollerOffsetY = self.scrollerOffsetY;
+                       };
+
+                       prototype._move = function (event) {
+                               var newX = this.startScrollerOffsetX,
+                                       newY = this.startScrollerOffsetY,
+                                       autoHide = !_keepShowingScrollbarOnTouch;
+
+                               if (!this.enabled || this.scrollCanceled || !this.dragging) {
+                                       return;
+                               }
+
+                               if (this.orientation === Scroller.Orientation.HORIZONTAL) {
+                                       newX += event.detail.estimatedDeltaX;
+                               } else {
+                                       newY += event.detail.estimatedDeltaY;
+                               }
+
+                               if (newX > this.minScrollX || newX < this.maxScrollX) {
+                                       newX = newX > this.minScrollX ? this.minScrollX : this.maxScrollX;
+                               }
+                               if (newY > this.minScrollY || newY < this.maxScrollY) {
+                                       newY = newY > this.minScrollY ? this.minScrollY : this.maxScrollY;
+                               }
+
+                               if (newX !== this.scrollerOffsetX || newY !== this.scrollerOffsetY) {
+                                       if (!this.scrolled) {
+                                               this.trigger(eventType.START);
+                                       }
+                                       this.scrolled = true;
+
+                                       this._translate(newX, newY);
+                                       this._translateScrollbar(newX, newY, 0, autoHide);
+                                       // TODO to dispatch move event is too expansive. it is better to use callback.
+                                       this.trigger(eventType.MOVE);
+
+                                       if (this.bouncingEffect) {
+                                               this.bouncingEffect.hide();
+                                       }
+                               } else {
+                                       if (this.bouncingEffect) {
+                                               this.bouncingEffect.drag(newX, newY);
+                                       }
+                                       this._translateScrollbar(newX, newY, 0, autoHide);
+                               }
+                       };
+
+                       prototype._end = function () {
+                               if (this.dragging) {
+
+                                       // bouncing effect
+                                       if (this.bouncingEffect) {
+                                               this.bouncingEffect.dragEnd();
+                                       }
+
+                                       if (this.scrollbar) {
+                                               this.scrollbar.end();
+                                       }
+
+                                       this._endScroll();
+                                       this.dragging = false;
+                               }
+                       };
+
+                       prototype._endScroll = function () {
+                               if (this.scrolled) {
+                                       this.trigger(eventType.END);
+                               }
+
+                               this.scrolled = false;
+                       };
+
+                       /**
+                        * Cancels scroll.
+                        * @method _cancel
+                        * @protected
+                        * @member ns.widget.core.scroller.Scroller
+                        */
+                       prototype._cancel = function () {
+                               this.scrollCanceled = true;
+
+                               if (this.scrolled) {
+                                       this._translate(this.startScrollerOffsetX, this.startScrollerOffsetY);
+                                       this._translateScrollbar(this.startScrollerOffsetX, this.startScrollerOffsetY);
+                                       this.trigger(eventType.CANCEL);
+                               }
+
+                               if (this.scrollbar) {
+                                       this.scrollbar.end();
+                               }
+
+                               this.scrolled = false;
+                               this.dragging = false;
+                       };
+
+                       prototype._clear = function () {
+                               this.scrolled = false;
+                               this.scrollCanceled = false;
+
+                               this._resetLayout();
+                               this._clearScrollbar();
+                               this._clearBouncingEffect();
+                       };
+
+                       prototype._clearScrollbar = function () {
+                               if (this.scrollbar) {
+                                       this.scrollbar.destroy();
+                               }
+                               this.scrollbar = null;
+                       };
+
+                       prototype._clearBouncingEffect = function () {
+                               if (this.bouncingEffect) {
+                                       this.bouncingEffect.destroy();
+                               }
+                               this.bouncingEffect = null;
+                       };
+
+                       prototype._disable = function () {
+                               this.enabled = false;
+                       };
+
+                       prototype._enable = function () {
+                               this.enabled = true;
+                       };
+
+                       prototype._destroy = function () {
+                               this._unbindEvents();
+                               this._clear();
+                               this.scrollerStyle = null;
+                               this.scroller = null;
+                       };
+
+                       Scroller.prototype = prototype;
+
+                       ns.widget.core.scroller.Scroller = Scroller;
+
+                       engine.defineWidget(
+                               "Scroller",
+                               ".scroller",
+                               ["scrollTo", "cancel"],
+                               Scroller
+                       );
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * #Scrollbar namespace
+ * Namespace with scrollbar for scroller widget.
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @class ns.widget.core.scroller.scrollbar
+ */
+(function (window, ns) {
+       "use strict";
+                               ns.widget.core.scroller.scrollbar = ns.widget.core.scroller.scrollbar || {};
+                       }(window, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * #type namespace
+ * Namespace with types of scroll bars..
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @class ns.widget.core.scroller.scrollbar.type
+ * @internal
+ */
+(function (window, ns) {
+       "use strict";
+                               /** @namespace ns.widget.core */
+                       ns.widget.core.scroller.scrollbar.type = ns.widget.core.scroller.scrollbar.type || {};
+                       }(window, ns));
+
+/*global window, define, Event, console, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Type Interface
+ * Interface for types used in scroll bar widget.
+ * @class ns.widget.core.scroller.scrollbar.type.interface
+ */
+(function (document, ns) {
+       "use strict";
+                               // scroller.start event trigger when user try to move scroller
+
+                       ns.widget.core.scroller.scrollbar.type.interface = {
+                               /**
+                                * Inserts elements end decorate.
+                                * @method insertAndDecorate
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.interface
+                                */
+                               setScrollbarLayout: function (/* options */) {
+                               },
+                               /**
+                                * Removes element.
+                                * @method remove
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.interface
+                                */
+                               remove: function (/* options */) {
+                               },
+                               /**
+                                * ...
+                                * @method start
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.interface
+                                */
+                               start: function (/* scrollbarElement, barElement */) {
+                               },
+                               /**
+                                * ...
+                                * @method end
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.interface
+                                */
+                               end: function (/* scrollbarElement, barElement */) {
+                               },
+                               /**
+                                * ...
+                                * @method offset
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.interface
+                                */
+                               offset: function (/* orientation, offset  */) {
+                               }
+                       };
+                       }(window.document, ns));
+
+/*global window, define, Event, console, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Bar Type
+ * Bar type support for scroll bar widget.
+ * @class ns.widget.core.scroller.scrollbar.type.bar
+ * @extends ns.widget.core.scroller.scrollbar.type.interface
+ */
+(function (document, ns) {
+       "use strict";
+                               // scroller.start event trigger when user try to move scroller
+                       var utilsObject = ns.util.object,
+                               type = ns.widget.core.scroller.scrollbar.type,
+                               typeInterface = type.interface,
+                               Scroller = ns.widget.core.scroller.Scroller;
+
+                       type.bar = utilsObject.merge({}, typeInterface, {
+                               options: {
+                                       animationDuration: 500
+                               },
+
+                               /**
+                                * @method setScrollbar
+                                * @param viewLayout
+                                * @param firstChildLayout
+                                * @param clipLayout
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.bar
+                                */
+
+                               setScrollbar: function (viewLayout, firstChildLayout, clipLayout) {
+                                       this._viewLayout = viewLayout;
+                                       this._clipLayout = clipLayout;
+                                       this._firstChildLayout = firstChildLayout;
+                                       this._ratio = clipLayout / firstChildLayout;
+                               },
+
+                               /**
+                                * @method getScrollbarSize
+                                * @return {number} scrollbar size
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.bar
+                                */
+                               getScrollbarSize: function () {
+                                       return this._firstChildLayout / this._viewLayout * this._firstChildLayout * this._ratio;
+                               },
+                               /**
+                                * @method offset
+                                * @param {string} orientation
+                                * @param {number} offset
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.bar
+                                */
+                               offset: function (orientation, offset) {
+                                       var x,
+                                               y;
+
+                                       offset = offset * this._clipLayout / this._viewLayout;
+
+                                       if (orientation === Scroller.Orientation.VERTICAL) {
+                                               x = 0;
+                                               y = offset;
+                                       } else {
+                                               x = offset;
+                                               y = 0;
+                                       }
+
+                                       return {
+                                               x: x,
+                                               y: y
+                                       };
+                               },
+
+                               /**
+                                * @method start
+                                * @param {HTMLElement} scrollbarElement
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.bar
+                                */
+                               start: function (scrollbarElement/*, barElement */) {
+                                       var style = scrollbarElement.style,
+                                               duration = this.options.animationDuration;
+
+                                       style["-webkit-transition"] =
+                                               style["-moz-transition"] =
+                                                       style["-ms-transition"] =
+                                                               style["-o-transition"] =
+                                                                       style.transition = "opacity " + duration / 1000 + "s ease";
+                                       style.opacity = 1;
+                               },
+
+                               /**
+                                * @method end
+                                * @param {HTMLElement} scrollbarElement
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.bar
+                                */
+                               end: function (scrollbarElement) {
+                                       var style = scrollbarElement.style,
+                                               duration = this.options.animationDuration;
+
+                                       style["-webkit-transition"] =
+                                               style["-moz-transition"] =
+                                                       style["-ms-transition"] =
+                                                               style["-o-transition"] =
+                                                                       style.transition = "opacity " + duration / 1000 + "s ease";
+                                       style.opacity = 0;
+                               }
+                       });
+
+                       }(window.document, ns));
+
+/*global window, define, Event, console, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Tab Type
+ * Tab type support for scroll bar widget.
+ * @class ns.widget.core.scroller.scrollbar.type.tab
+ * @extends ns.widget.core.scroller.scrollbar.type.interface
+ */
+(function (document, ns) {
+       "use strict";
+                               // scroller.start event trigger when user try to move scroller
+                       var utilsObject = ns.util.object,
+                               type = ns.widget.core.scroller.scrollbar.type,
+                               typeInterface = type.interface,
+                               Scroller = ns.widget.core.scroller.Scroller;
+
+                       type.tab = utilsObject.merge({}, typeInterface, {
+                               options: {
+                                       wrapperClass: "ui-scrollbar-tab-type",
+                                       barClass: "ui-scrollbar-indicator",
+                                       margin: 1
+                               },
+                               /**
+                                * ...
+                                * @method insertAndDecorate
+                                * @param {Object} data
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.tab
+                                */
+                               insertAndDecorate: function (data) {
+                                       var scrollbarElement = data.wrapper,
+                                               barElement = data.bar,
+                                               container = data.container,
+                                               clip = data.clip,
+                                               sections = data.sections,
+                                               orientation = data.orientation,
+                                               margin = this.options.margin,
+                                               clipWidth = clip.offsetWidth,
+                                               clipHeight = clip.offsetHeight,
+                                               containerWidth = container.offsetWidth,
+                                               containerHeight = container.offsetHeight,
+                                               clipSize = orientation === Scroller.Orientation.VERTICAL ? clipHeight : clipWidth,
+                                               containerSize = orientation === Scroller.Orientation.VERTICAL ? containerHeight : containerWidth,
+                                               sectionSize = clipSize / containerSize,
+                                               height,
+                                               barHeight,
+                                               i,
+                                               len;
+
+                                       this.containerSize = containerWidth;
+                                       this.maxScrollOffset = clipSize - containerSize;
+                                       this.scrollZoomRate = containerWidth / clipSize;
+                                       this.barSize = window.parseInt((containerWidth - margin * 2 * (sectionSize - 1)) / sectionSize);
+
+                                       scrollbarElement.className = this.options.wrapperClass;
+                                       barElement.className = this.options.barClass;
+
+                                       barElement.style.width = this.barSize + "px";
+                                       barElement.style.left = "0px";
+
+                                       container.insertBefore(scrollbarElement, clip);
+
+                                       // reset page container and section layout.
+                                       barHeight = barElement.offsetHeight;
+                                       height = clipHeight - barHeight;
+                                       clip.style.height = height + "px";
+                                       if (sections && sections.length) {
+                                               for (i = 0, len = sections.length; i < len; i++) {
+                                                       sections[i].style.height = height + "px";
+                                               }
+                                       }
+                               },
+
+                               /**
+                                * ...
+                                * @method remove
+                                * @param {Object} data
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.tab
+                                */
+                               remove: function (data) {
+                                       var scrollbarElement = data.wrapper,
+                                               container = data.container;
+
+                                       if (container && scrollbarElement) {
+                                               container.removeChild(scrollbarElement);
+                                       }
+                               },
+
+                               /**
+                                * ...
+                                * @method offset
+                                * @param {string} orientation
+                                * @param {number} offset
+                                * @static
+                                * @member ns.widget.core.scroller.scrollbar.type.tab
+                                */
+                               offset: function (orientation, offset) {
+                                       return {
+                                               x: offset === 0 ? -1 :
+                                                       offset === this.maxScrollOffset ? this.containerSize - this.barSize - this.options.margin : offset * this.scrollZoomRate,
+                                               y: 0
+                                       };
+                               }
+
+                       });
+                       }(window.document, ns));
+
+/*global window, define, Event, console, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Scroll Bar Widget
+ * Widget creates scroll bar.
+ * @class ns.widget.core.scroller.scrollbar.ScrollBar
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               // scroller.start event trigger when user try to move scroller
+                       var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               prototype = new BaseWidget(),
+                               utilsObject = ns.util.object,
+                               selectors = ns.util.selectors,
+                               Page = ns.widget.core.Page,
+                               Classes = {
+                                       wrapperClass: "ui-scrollbar-bar-type",
+                                       barClass: "ui-scrollbar-indicator",
+                                       orientationClass: "ui-scrollbar-",
+                                       page: Page.classes.uiPage
+                               },
+
+                               Scroller = ns.widget.core.scroller.Scroller,
+                               ScrollerScrollBar = function () {
+
+                                       this.wrapper = null;
+                                       this.barElement = null;
+
+                                       this.container = null;
+                                       this.view = null;
+
+                                       this.options = {};
+                                       this.type = null;
+
+                                       this.maxScroll = null;
+                                       this.started = false;
+                                       this.displayDelayTimeoutId = null;
+
+                                       this.lastScrollPosition = 0;
+                               };
+
+                       prototype._build = function (scrollElement) {
+                               this.clip = scrollElement;
+                               this.view = scrollElement.children[0];
+                               this.firstChild = this.view.children[0];
+                               return scrollElement;
+                       };
+
+                       prototype._configure = function () {
+                               /**
+                                * @property {Object} options Options for widget
+                                * @property {boolean} [options.type=false]
+                                * @property {number} [options.displayDelay=700]
+                                * @property {"vertical"|"horizontal"} [options.orientation="vertical"]
+                                * @member ns.widget.core.scroller.scrollbar.ScrollBar
+                                */
+                               this.options = utilsObject.merge({}, this.options, {
+                                       type: false,
+                                       displayDelay: 700,
+                                       orientation: Scroller.Orientation.VERTICAL
+                               });
+                       };
+
+                       prototype._init = function (scrollElement) {
+                               this.clip = scrollElement;
+                               this.view = scrollElement.children[0];
+                               this.firstChild = this.view.children[0];
+                               this.type = this.options.type;
+
+                               if (!this.type) {
+                                       return;
+                               }
+                               this._createScrollbar();
+                       };
+
+                       prototype._bindEvents = function () {
+                               document.addEventListener("visibilitychange", this);
+                       };
+
+                       prototype._createScrollbar = function () {
+                               var orientation = this.options.orientation,
+                                       wrapper = document.createElement("DIV"),
+                                       bar = document.createElement("span"),
+                                       view = this.view,
+                                       clip = this.clip,
+                                       firstChild = this.firstChild,
+                                       type = this.type;
+
+                               clip.appendChild(wrapper);
+                               wrapper.appendChild(bar);
+                               wrapper.classList.add(Classes.wrapperClass);
+                               bar.className = Classes.barClass;
+
+                               if (orientation === Scroller.Orientation.HORIZONTAL) {
+                                       type.setScrollbar(view.offsetWidth, firstChild.offsetWidth, clip.offsetWidth);
+                                       bar.style.width = type.getScrollbarSize() + "px";
+                                       wrapper.classList.add(Classes.orientationClass + "horizontal");
+                               } else {
+                                       type.setScrollbar(view.offsetHeight, firstChild.offsetHeight, clip.offsetHeight);
+                                       bar.style.height = type.getScrollbarSize() + "px";
+                                       wrapper.classList.add(Classes.orientationClass + "vertical");
+                               }
+
+                               this.wrapper = wrapper;
+                               this.barElement = bar;
+                       };
+
+                       prototype._removeScrollbar = function () {
+                               this.clip.removeChild(this.wrapper);
+
+                               this.wrapper = null;
+                               this.barElement = null;
+                       };
+
+                       prototype._refresh = function () {
+                               var self = this;
+
+                               self._clear();
+                               self._init(self.element);
+                               self.translate(self.lastScrollPosition);
+                       };
+
+                       /**
+                        * Translates widget.
+                        * @method translate
+                        * @param {number} offset
+                        * @param {number} duration
+                        * @param {boolean} autoHidden
+                        * @member ns.widget.core.scroller.scrollbar.ScrollBar
+                        */
+                       prototype.translate = function (offset, duration, autoHidden) {
+                               var orientation = this.options.orientation,
+                                       translate,
+                                       transition = {
+                                               normal: "none",
+                                               webkit: "none",
+                                               moz: "none",
+                                               ms: "none",
+                                               o: "none"
+                                       },
+                                       barStyle,
+                                       endDelay;
+
+                               if (!this.wrapper || !this.type || this.lastScrollPosition === offset) {
+                                       return;
+                               }
+
+                               autoHidden = autoHidden !== false;
+
+                               this.lastScrollPosition = offset;
+
+                               offset = this.type.offset(orientation, offset);
+
+                               barStyle = this.barElement.style;
+                               if (duration) {
+                                       transition.normal = "transform " + duration / 1000 + "s ease-out";
+                                       transition.webkit = "-webkit-transform " + duration / 1000 + "s ease-out";
+                                       transition.moz = "-moz-transform " + duration / 1000 + "s ease-out";
+                                       transition.ms = "-ms-transform " + duration / 1000 + "s ease-out";
+                                       transition.o = "-o-transform " + duration / 1000 + "s ease-out";
+                               }
+
+                               translate = "translate3d(" + offset.x + "px," + offset.y + "px, 0)";
+
+                               barStyle["-webkit-transform"] =
+                                       barStyle["-moz-transform"] =
+                                               barStyle["-ms-transform"] =
+                                                       barStyle["-o-transform"] =
+                                                               barStyle.transform = translate;
+                               barStyle["-webkit-transition"] = transition.webkit;
+                               barStyle["-moz-transition"] = transition.moz;
+                               barStyle["-ms-transition"] = transition.ms;
+                               barStyle["-o-transition"] = transition.o;
+                               barStyle.transition = transition.normal;
+
+                               if (!this.started) {
+                                       this._start();
+                               }
+
+                               if (this.displayDelayTimeoutId !== null) {
+                                       window.clearTimeout(this.displayDelayTimeoutId);
+                                       this.displayDelayTimeoutId = null;
+                               }
+
+                               if (autoHidden) {
+                                       endDelay = (duration || 0) + this.options.displayDelay;
+                                       this.displayDelayTimeoutId = window.setTimeout(this._end.bind(this), endDelay);
+                               }
+                       };
+
+                       prototype.end = function () {
+                               if (!this.displayDelayTimeoutId) {
+                                       this.displayDelayTimeoutId = window.setTimeout(this._end.bind(this), this.options.displayDelay);
+                               }
+                       };
+
+                       prototype._start = function () {
+                               this.type.start(this.wrapper, this.barElement);
+                               this.started = true;
+                       };
+
+                       prototype._end = function () {
+                               this.started = false;
+                               this.displayDelayTimeoutId = null;
+
+                               if (this.type) {
+                                       this.type.end(this.wrapper, this.barElement);
+                               }
+                       };
+
+                       /**
+                        * Supports events.
+                        * @method handleEvent
+                        * @param {Event} event
+                        * @member ns.widget.core.scroller.scrollbar.ScrollBar
+                        */
+                       prototype.handleEvent = function (event) {
+                               var page;
+
+                               switch (event.type) {
+                                       case "visibilitychange":
+                                               page = selectors.getClosestBySelector(this.clip, "." + Classes.page);
+                                               if (document.visibilityState === "visible" && page === ns.activePage) {
+                                                       this.refresh();
+                                               }
+                                               break;
+                               }
+                       };
+
+                       prototype._clear = function () {
+                               this._removeScrollbar();
+
+                               this.started = false;
+                               this.type = null;
+                               this.barElement = null;
+                               this.displayDelayTimeoutId = null;
+                       };
+
+                       prototype._destroy = function () {
+                               this._clear();
+                               document.removeEventListener("visibilitychange", this);
+
+                               this.options = null;
+                               this.clip = null;
+                               this.view = null;
+                       };
+
+                       ScrollerScrollBar.prototype = prototype;
+
+                       ns.widget.core.scroller.scrollbar.ScrollBar = ScrollerScrollBar;
+
+                       engine.defineWidget(
+                               "ScrollBar",
+                               "",
+                               ["translate"],
+                               ScrollerScrollBar
+                       );
+                       }(window.document, ns));
+
+/*global window, ns, define */
+/*jslint nomen: true, plusplus: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Easing Utility
+ * Utility calculates time function for animations.
+ * @class ns.util.easing
+ */
+
+(function (ns) {
+       "use strict";
+                               ns.util.easing = {
+                               /**
+                                * Performs cubit out easing calculations based on time
+                                * @method cubicOut
+                                * @member ns.util.easing
+                                * @param {number} currentTime
+                                * @param {number} startValue
+                                * @param {number} changeInValue
+                                * @param {number} duration
+                                * @return {number}
+                                * @static
+                                */
+                               cubicOut: function (currentTime, startValue, changeInValue, duration) {
+                                       currentTime /= duration;
+                                       currentTime--;
+                                       return changeInValue * (currentTime * currentTime * currentTime + 1) + startValue;
+                               },
+
+                               /**
+                                * Performs quad easing out calculations based on time
+                                * @method easeOutQuad
+                                * @member ns.util.easing
+                                * @param {number} currentTime
+                                * @param {number} startValue
+                                * @param {number} changeInValue
+                                * @param {number} duration
+                                * @return {number}
+                                * @static
+                                */
+                               easeOutQuad: function (currentTime, startValue, changeInValue, duration) {
+                                       return -changeInValue * (currentTime /= duration) * (currentTime - 2) + startValue;
+                               },
+
+                               /**
+                                * Performs sine easing out calculations based on time
+                                * The easing functions can be compared on: https://easings.net
+                                * @method easeOutSine
+                                * @member ns.util.easing
+                                * @param {number} currentTime
+                                * @param {number} startValue
+                                * @param {number} changeInValue
+                                * @param {number} duration
+                                * @return {number}
+                                * @static
+                                */
+                               easeOutSine: function (currentTime, startValue, changeInValue, duration) {
+                                       return changeInValue * Math.sin(currentTime / duration * (Math.PI / 2)) + startValue;
+                               },
+
+                               /**
+                                * Performs out expo easing calculations based on time
+                                * @method easeOutExpo
+                                * @member ns.util.easing
+                                * @param {number} currentTime
+                                * @param {number} startValue
+                                * @param {number} changeInValue
+                                * @param {number} duration
+                                * @return {number}
+                                * @static
+                                */
+                               easeOutExpo: function (currentTime, startValue, changeInValue, duration) {
+                                       return (currentTime === duration) ?
+                                               startValue + changeInValue :
+                                               changeInValue * (-Math.pow(2, -10 * currentTime / duration) + 1) +
+                                       startValue;
+                               },
+                               /**
+                                * Performs out linear calculations based on time
+                                * @method linear
+                                * @member ns.util.easing
+                                * @param {number} currentTime
+                                * @param {number} startValue
+                                * @param {number} changeInValue
+                                * @param {number} duration
+                                * @return {number}
+                                * @static
+                                */
+                               linear: function (currentTime, startValue, changeInValue, duration) {
+                                       return startValue + changeInValue * currentTime / duration;
+                               }
+                       };
+                       }(ns));
+
+/*global window, define, ns*/
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * # ScrollView Widget
+ * Widgets allows for creating scrollable panes, lists, etc.
+ *
+ * ## Default selectors
+ * All elements with _data-role=content attribute or _.ui-scrollview
+ * css class will be changed to ScrollView widgets, unless they specify
+ * _data-scroll=none attribute.
+ *
+ * ### HTML Examples
+ *
+ * #### Data attribute
+ *
+ *        @example
+ *        <div data-role="page">
+ *            <div data-role="content"><!-- this will become scrollview //-->
+ *                content data
+ *            </div>
+ *        </div>
+ *
+ * #### CSS Class
+ *
+ *        @example
+ *        <div data-role="page">
+ *            <div class="ui-content"><!-- this will become scrollview //-->
+ *                content data
+ *            </div>
+ *        </div>
+ *
+ * ## Manual constructor
+ *
+ * To create the widget manually you can use 2 different APIs, the TAU
+ * API or jQuery API.
+ *
+ * ### Create scrollview by TAU API
+ *
+ *        @example
+ *        <div data-role="page" id="myPage">
+ *            <div data-role="content">
+ *                page content
+ *            </div>
+ *        </div>
+ *        <script>
+ *            var page = tau.widget.Page(document.getElementById("myPage")),
+ *                scrollview = tau.widget.Scrollview(page.ui.content);
+ *        </script>
+ *
+ * ### Create scrollview using jQuery API
+ *
+ *        @example
+ *        <div data-role="page" id="myPage">
+ *            <div data-role="content">
+ *                page content
+ *            </div>
+ *        </div>
+ *        <script>
+ *            $("#myPage > div[data-role='content']").scrollview();
+ *        </script>
+ *
+ * ## Options for Scrollview widget
+ *
+ * Options can be set using data-* attributes or by passing them to
+ * the constructor.
+ *
+ * There is also a method **option** for changing them after widget
+ * creation.
+ *
+ * jQuery mobile format is also supported.
+ *
+ * ## Scroll
+ *
+ * This options specifies of a content element should become Scrollview
+ * widget.
+ *
+ * You can change this by all available methods for changing options.
+ *
+ * ### By data-scroll attribute
+ *
+ *        @example
+ *        <div data-role="page">
+ *            <div data-role="content" data-scroll="none">
+ *                content
+ *            </div>
+ *        </div>
+ *
+ * ### By config passed to constructor
+ *
+ *        @example
+ *        <div class="myPageClass" data-role="page">
+ *            <div data-role="content">
+ *                content
+ *            </div>
+ *        </div>
+ *        <script>
+ *            var contentElement = document.querySelector(".myPageClass > div[data-role=content]");
+ *            tau.widget.Scrollview(contentElement, {
+ *                             "scroll": false
+ *                     });
+ *        </script>
+ *
+ * ### By using jQuery API
+ *
+ *        @example
+ *        <div class="myPageClass" data-role="page">
+ *            <div data-role="content">
+ *                content
+ *            </div>
+ *        </div>
+ *        <script>
+ *            $(".myPageClass > div[data-role='content']").scrollview({
+ *                             "scroll": false
+ *                     });
+ *        </script>
+ *
+ * ## ScrollJumps
+ *
+ * Scroll jumps are small buttons which allow the user to quickly
+ * scroll to top or left
+ *
+ * You can change this by all available methods for changing options.
+ *
+ * ### By data-scroll-jump
+ *
+ *        @example
+ *        <div data-role="page">
+ *            <div data-role="content" data-scroll-jump="true">
+ *                content
+ *            </div>
+ *        </div>
+ *
+ * ### By config passed to constructor
+ *
+ *        @example
+ *        <div class="myPageClass" data-role="page">
+ *            <div data-role="content">
+ *                content
+ *            </div>
+ *        </div>
+ *        <script>
+ *            var contentElement = document.querySelector(".myPageClass > div[data-role=content]");
+ *            tau.widget.Scrollview(contentElement, {
+ *                             "scrollJump": true
+ *                     });
+ *        </script>
+ *
+ * ### By using jQuery API
+ *
+ *        @example
+ *        <div class="myPageClass" data-role="page">
+ *            <div data-role="content">
+ *                content
+ *            </div>
+ *        </div>
+ *        <script>
+ *            $(".myPageClass > div[data-role='content']").scrollview({
+ *                             "scrollJump": true
+ *                     });
+ *        </script>
+ *
+ * ## Methods
+ *
+ * Page methods can be called trough 2 APIs: TAU API and jQuery API
+ * (jQuery mobile-like API)
+ *
+ * @class ns.widget.core.Scrollview
+ * @extends ns.widget.BaseWidget
+ *
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Grzegorz Osimowicz <g.osimowicz@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Hyunkook Cho <hk0713.cho@samsung.com>
+ * @author Junhyeon Lee <juneh.lee@samsung.com>
+ */
+/**
+ * Triggered when scrolling operation starts
+ * @event scrollstart
+ * @member ns.widget.core.Scrollview
+ */
+/**
+ * Triggered when scroll is being updated
+ * @event scrollupdate
+ * @member ns.widget.core.Scrollview
+ */
+/**
+ * Triggered when scrolling stops
+ * @event scrollstop
+ * @member ns.widget.core.Scrollview
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               util = ns.util,
+                               easingUtils = ns.util.easing,
+                               eventUtils = ns.event,
+                               DOMUtils = ns.util.DOM,
+                               selectors = ns.util.selectors,
+                               currentTransition = null,
+                               Page = ns.widget.core.Page,
+                               pageClass = Page.classes.uiPage,
+                               pageActiveClass = Page.classes.uiPageActive,
+                               pageEvents = Page.events,
+                               Scrollview = function () {
+                                       var self = this,
+                                               ui;
+                                       /**
+                                        * @property {Object} _scrollState Scrollview internal state object
+                                        * @property {Function} _scrollState.currentTransition Instance transition function
+                                        * @readonly
+                                        */
+
+                                       self._scrollState = {
+                                               currentTransition: null
+                                       };
+                                       /**
+                                        * @property {number} scrollDuration The time length of the scroll animation
+                                        * @member ns.widget.core.Scrollview
+                                        */
+                                       self.scrollDuration = 300;
+                                       self.scrollviewSetHeight = false;
+                                       /**
+                                        * Scrollview options
+                                        * @property {Object} options
+                                        * @property {string} [options.scroll='y'] Scroll direction
+                                        * @property {boolean} [options.scrollJump=false] Scroll jump buttons flag
+                                        * @member ns.widget.core.Scrollview
+                                        */
+                                       self.options = {
+                                               scroll: "y",
+                                               scrollJump: false,
+                                               scrollIndicator: false
+                                       };
+                                       /**
+                                        * Dictionary for holding internal DOM elements
+                                        * @property {Object} ui
+                                        * @property {HTMLElement} ui.view The main view element
+                                        * @property {HTMLElement} ui.page The main page element
+                                        * @property {HTMLElement} ui.jumpHorizontalButton Jump left button
+                                        * @property {HTMLElement} ui.jumpVerticalButton Jump top button
+                                        * @member ns.widget.core.Scrollview
+                                        * @readonly
+                                        */
+                                       ui = self._ui || {};
+                                       ui.view = null;
+                                       ui.page = null;
+                                       ui.jumpHorizontalButton = null;
+                                       ui.jumpVerticalButton = null;
+                                       self._ui = ui;
+                                       /**
+                                        * Dictionary for holding internal listeners
+                                        * @property {Object} _callbacks
+                                        * @property {Function} _callbacks.repositionJumps Refresh jumps listener
+                                        * @property {Function} _callbacks.jumpTop Top jump button click callback
+                                        * @property {Function} _callbacks.jumpLeft Left jump button click callback
+                                        * @member ns.widget.core.Scrollview
+                                        * @protected
+                                        * @readonly
+                                        */
+                                       self._callbacks = {
+                                               repositionJumps: null,
+                                               jumpTop: null,
+                                               jumpBottom: null
+                                       };
+
+                                       self._timers = {
+                                               scrollIndicatorHide: null
+                                       };
+                               },
+                               /**
+                                * Dictionary for scrollview css classes
+                                * @property {Object} classes
+                                * @property {string} [classes.view='ui-scrollview-view'] View main class
+                                * @property {string} [classes.clip='ui-scrollview-clip'] Clip main class
+                                * @property {string} [classes.jumpTop='ui-scroll-jump-top-bg'] Jump top button background
+                                * @property {string} [classes.jumpLeft='ui-scroll-jump-left-bg'] Jump bottom button background
+                                * @member ns.widget.core.Scrollview
+                                * @static
+                                * @readonly
+                                */
+                               classes = {
+                                       view: "ui-scrollview-view",
+                                       clip: "ui-scrollview-clip",
+                                       jumpTop: "ui-scroll-jump-top-bg",
+                                       jumpLeft: "ui-scroll-jump-left-bg",
+                                       indicatorTop: "ui-overflow-indicator-top",
+                                       indicatorBottom: "ui-overflow-indicator-bottom",
+                                       indicatorTopShown: "ui-scrollindicator-top",
+                                       indicatorBottomShown: "ui-scrollindicator-bottom",
+                                       indicatorLeftShown: "ui-scrollindicator-left",
+                                       indicatorRightShown: "ui-scrollindicator-right"
+                               };
+
+                       // Changes static position to relative
+                       // @param {HTMLElement} view
+                       function makePositioned(view) {
+                               if (DOMUtils.getCSSProperty(view, "position") === "static") {
+                                       view.style.position = "relative";
+                               } else {
+                                       view.style.position = "absolute";
+                               }
+                       }
+
+                       // Translation animation loop
+                       // @param {Object} state Scrollview instance state
+                       // @param {HTMLElement} element
+                       // @param {number} startTime
+                       // @param {number} startX
+                       // @param {number} startY
+                       // @param {number} translateX
+                       // @param {number} translateY
+                       // @param {number} endX
+                       // @param {number} endY
+                       // @param {number} duration
+                       function translateTransition(state, element, startTime, startX, startY, translateX, translateY, endX, endY, duration) {
+                               var timestamp = (new Date()).getTime() - startTime,
+                                       newX = parseInt(easingUtils.cubicOut(timestamp, startX, translateX, duration), 10),
+                                       newY = parseInt(easingUtils.cubicOut(timestamp, startY, translateY, duration), 10);
+
+                               if (element.scrollLeft !== endX) {
+                                       element.scrollLeft = newX;
+                               }
+                               if (element.scrollTop !== endY) {
+                                       element.scrollTop = newY;
+                               }
+
+                               if ((newX !== endX || newY !== endY) &&
+                                       (newX >= 0 && newY >= 0) &&
+                                       state.currentTransition) {
+                                       util.requestAnimationFrame(state.currentTransition);
+                               } else {
+                                       state.currentTransition = null;
+                               }
+                       }
+
+                       // Translates scroll position directly or with an animation
+                       // if duration is specified
+                       // @param {Object} state Scrollview instance state
+                       // @param {HTMLElement} element
+                       // @param {number} x
+                       // @param {number} y
+                       // @param {number=} [duration]
+                       function translate(state, element, x, y, duration) {
+                               if (duration) {
+                                       state.currentTransition = translateTransition.bind(
+                                               null,
+                                               state,
+                                               element,
+                                               (new Date()).getTime(),
+                                               element.scrollLeft,
+                                               element.scrollTop,
+                                               x,
+                                               y,
+                                               element.scrollLeft + x,
+                                               element.scrollTop + y,
+                                               duration
+                                       );
+                                       util.requestAnimationFrame(state.currentTransition);
+                               } else {
+                                       if (x) {
+                                               element.scrollLeft = element.scrollLeft + x;
+                                       }
+                                       if (y) {
+                                               element.scrollTop = element.scrollTop + y;
+                                       }
+                               }
+                       }
+
+                       // Refresh jumpTop jumpLeft buttons
+                       // @param {ns.widget.core.Scrollview} self
+                       function repositionJumps(self) {
+                               var ui = self._ui,
+                                       horizontalJumpButton = ui.jumpHorizontalButton,
+                                       verticalJumpButton = ui.jumpVerticalButton,
+                                       offsets = horizontalJumpButton || verticalJumpButton ? DOMUtils.getElementOffset(self.element) : null; // don't calc when not used
+
+                               if (horizontalJumpButton) {
+                                       horizontalJumpButton.style.left = offsets.left + "px";
+                               }
+
+                               if (verticalJumpButton) {
+                                       verticalJumpButton.style.top = offsets.top + "px";
+                               }
+                       }
+
+                       Scrollview.classes = classes;
+
+                       Scrollview.prototype = new BaseWidget();
+
+                       /**
+                        * Builds the widget
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @method _build
+                        * @protected
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype._build = function (element) {
+                               //@TODO wrap element's content with external function
+                               var self = this,
+                                       ui = self._ui,
+                                       view = selectors.getChildrenByClass(element, classes.view)[0] || document.createElement("div"),
+                                       node,
+                                       child = element.firstChild,
+                                       options = self.options,
+                                       direction = options.scroll,
+                                       jumpButton,
+                                       jumpBackground;
+
+                               view.className = classes.view;
+
+                               while (child) {
+                                       node = child;
+                                       child = child.nextSibling;
+                                       if (view !== node) {
+                                               view.appendChild(node);
+                                       }
+                               }
+
+                               if (view.parentNode !== element) {
+                                       element.appendChild(view);
+                               }
+
+                               // setting view style
+                               makePositioned(view);
+
+                               element.classList.add(classes.clip);
+
+                               // Adding ui-content class for the proper styling with CE
+                               element.classList.add("ui-content");
+
+                               self._setClipOverflowStyle(element);
+
+                               if (options.scrollJump) {
+                                       if (direction.indexOf("x") > -1) {
+                                               jumpBackground = document.createElement("div");
+                                               jumpBackground.className = classes.jumpLeft;
+                                               jumpButton = document.createElement("div");
+
+                                               jumpBackground.appendChild(jumpButton);
+                                               element.appendChild(jumpBackground);
+                                               engine.instanceWidget(
+                                                       jumpButton,
+                                                       "Button",
+                                                       {
+                                                               "icon": "scrollleft",
+                                                               "style": "box"
+                                                       }
+                                               );
+                                               ui.jumpHorizontalButton = jumpBackground;
+                                       }
+
+                                       if (direction.indexOf("y") > -1) {
+                                               jumpBackground = document.createElement("div");
+                                               jumpBackground.className = classes.jumpTop;
+                                               jumpButton = document.createElement("div");
+
+                                               jumpBackground.appendChild(jumpButton);
+                                               element.appendChild(jumpBackground);
+                                               engine.instanceWidget(
+                                                       jumpButton,
+                                                       "Button",
+                                                       {
+                                                               "icon": "scrolltop",
+                                                               "style": "box"
+                                                       }
+                                               );
+                                               ui.jumpVerticalButton = jumpBackground;
+                                       }
+                               }
+
+                               ui.view = view;
+
+                               // add scroll indicators
+                               if (options.scrollIndicator) {
+                                       self._addOverflowIndicator(element);
+                               }
+
+                               return element;
+                       };
+
+                       /**
+                        * Sets overflow property for clip element accordingly to scrolling direction
+                        * @method _setClipOverflowHidden
+                        * @protected
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype._setClipOverflowStyle = function (element) {
+                               var self = this,
+                                       direction = self.options.scroll,
+                                       clipStyle;
+
+                               element = element || self.element;
+                               clipStyle = element.style;
+
+                               switch (direction) {
+                                       case "x":
+                                               clipStyle.overflowX = "scroll";
+                                               break;
+                                       case "xy":
+                                               clipStyle.overflow = "scroll";
+                                               break;
+                                       default:
+                                               clipStyle.overflowY = "auto";
+                                               break;
+                               }
+                       }
+
+                       /**
+                        * Sets overflow hidden style for clip element
+                        * @method _setClipOverflowHidden
+                        * @protected
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype._setClipOverflowHidden = function (element) {
+                               var self = this,
+                                       direction = self.options.scroll,
+                                       clipStyle;
+
+                               element = element || self.element;
+                               clipStyle = element.style;
+
+                               switch (direction) {
+                                       case "x":
+                                               clipStyle.overflowX = "hidden";
+                                               break;
+                                       case "xy":
+                                               clipStyle.overflow = "hidden";
+                                               break;
+                                       default:
+                                               clipStyle.overflowY = "hidden";
+                                               break;
+                               }
+                       }
+
+                       /**
+                        * Inits widget
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype._init = function (element) {
+                               var ui = this._ui,
+                                       page = ui.page;
+
+                               if (!ui.view) {
+                                       ui.view = selectors.getChildrenByClass(element, classes.view)[0];
+                               }
+
+                               if (!page) {
+                                       page = selectors.getClosestByClass(element, pageClass);
+                                       if (page) {
+                                               ui.page = page;
+                                               if (page.classList.contains(pageActiveClass) && this.options.scrollJump) {
+                                                       repositionJumps(this);
+                                               }
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Adds overflow indicators
+                        * @param {HTMLElement} clip
+                        * @method _addOverflowIndicator
+                        * @protected
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype._addOverflowIndicator = function (clip) {
+                               clip.insertAdjacentHTML("beforeend",
+                                       "<div class='" + classes.indicatorTop + "'></div><div class='" + classes.indicatorBottom + "'></div>");
+                       };
+
+                       /**
+                        * Clear classes and styles of indicators
+                        * @param {HTMLElement} element
+                        * @method clearIndicator
+                        * @private
+                        * @member ns.widget.core.Scrollview
+                        */
+                       function clearIndicator(element) {
+                               var clipClasses = element.classList,
+                                       topIndicator = selectors.getChildrenByClass(element, classes.indicatorTop)[0],
+                                       bottomIndicator = selectors.getChildrenByClass(element, classes.indicatorBottom)[0];
+
+                               clipClasses.remove(classes.indicatorTopShown);
+                               clipClasses.remove(classes.indicatorBottomShown);
+                               clipClasses.remove(classes.indicatorRightShown);
+                               clipClasses.remove(classes.indicatorLeftShown);
+                               topIndicator.style = "";
+                               bottomIndicator.style = "";
+                       }
+
+                       /**
+                        * Set top and bottom indicators
+                        * @param {HTMLElement} clip
+                        * @param {Object} options
+                        * @method setTopAndBottomIndicators
+                        * @private
+                        * @member ns.widget.core.Scrollview
+                        */
+                       function setTopAndBottomIndicators(clip, options) {
+                               var topIndicator = selectors.getChildrenByClass(clip, classes.indicatorTop)[0],
+                                       bottomIndicator = selectors.getChildrenByClass(clip, classes.indicatorBottom)[0],
+                                       style;
+
+                               // set top indicator
+                               if (topIndicator) {
+                                       style = topIndicator.style;
+                                       style.width = options.width + "px";
+                                       style.top = options.clipTop + "px";
+                                       style.backgroundColor = options.color;
+                               }
+                               if (bottomIndicator) {
+                                       // set bottom indicator
+                                       style = bottomIndicator.style;
+                                       style.width = options.width + "px";
+                                       style.top = options.clipTop + options.clipHeight - DOMUtils.getElementHeight(bottomIndicator) + "px";
+                                       style.backgroundColor = options.color;
+                               }
+                       }
+
+                       /**
+                        * Show scroll indicators.
+                        * @method _showScrollIndicator
+                        * @protected
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype._showScrollIndicator = function () {
+                               var self = this,
+                                       clip = self.element,
+                                       view = self._ui.view,
+                                       scrollTop = clip.scrollTop,
+                                       clipHeight = DOMUtils.getElementHeight(clip),
+                                       clipOffset = DOMUtils.getElementOffset(clip),
+                                       viewHeight = DOMUtils.getElementHeight(view),
+                                       viewWidth = DOMUtils.getElementWidth(view),
+                                       viewOffset = DOMUtils.getElementOffset(view);
+
+                               clearIndicator(clip);
+
+                               switch (self.options.scroll) {
+                                       case "x":
+                                       case "xy":
+                                               // @todo
+                                               break;
+                                       default:
+                                               setTopAndBottomIndicators(clip, {
+                                                       clipTop: clipOffset.top,
+                                                       clipHeight: clipHeight,
+                                                       width: viewWidth,
+                                                       color: window.getComputedStyle(clip).backgroundColor
+                                               });
+                                               if (viewOffset.top - scrollTop < clipOffset.top) {
+                                                       // the top is not visible
+                                                       clip.classList.add(classes.indicatorTopShown);
+                                               }
+                                               if (viewOffset.top - scrollTop + viewHeight > clipOffset.top + clipHeight) {
+                                                       // the bottom is not visible
+                                                       clip.classList.add(classes.indicatorBottomShown);
+                                               }
+                               }
+                       };
+
+                       /**
+                        * Hide scroll indicators.
+                        * @method _hideScrollIndicator
+                        * @protected
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype._hideScrollIndicator = function () {
+                               var self = this,
+                                       timers = self._timers,
+                                       timer = timers.scrollIndicatorHide;
+
+                               if (timer) {
+                                       window.clearTimeout(timer);
+                               }
+                               timers.scrollIndicatorHide = window.setTimeout(function () {
+                                       clearIndicator(self.element);
+                               }, 1500);
+                       };
+
+                       /**
+                        * Scrolls to specified position
+                        *
+                        * This method give possibility to scroll on Scrollview widget form JS interface of widget.
+                        *
+                        * <mobile>
+                        * On mobile profile you can use method in jQuery style.
+                        * </mobile>
+                        *
+                        * If duration is set then scroll will be animated in given time period.
+                        *
+                        * <wearable>
+                        * On wearable profile Scrollview widget isn't build automatically. Before using method scrollTo, you need
+                        * create widget on content of page.
+                        * </wearable>
+                        * ### Example usage with TAU API
+                        *
+                        *              @example mobile wearable
+                        *              <div class="myPageClass" data-role="page">
+                        *                      <div data-role="content" data-scroll="y">
+                        *                              content
+                        *                      </div>
+                        *              </div>
+                        *              <script>
+                        *                      var scrollview = tau.widget.Scrollview(document.querySelector(".myPageClass > div[data-role=content]"));
+                        *                      scrollview.scrollTo(0, 200, 1000); // scroll to 200px vertical with 1s animation
+                        *              </script>
+                        *
+                        * ### Example usage with jQuery API
+                        *
+                        *              @example mobile
+                        *              <div class="myPageClass" data-role="page">
+                        *                      <div data-role="content" data-scroll="y">
+                        *                              content
+                        *                      </div>
+                        *              </div>
+                        *              <script>
+                        *                      var element = $(".myPageClass > div[data-role=content]"));
+                        *                      element.scrollview();
+                        *                      element.scrollview("scrollTo", 0, 200, 1000); // scroll to 200px vertical with 1s animation
+                        *              </script>
+                        *
+                        * @param {number} x
+                        * @param {number} y
+                        * @param {number=} [duration]
+                        * @method scrollTo
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype.scrollTo = function (x, y, duration) {
+                               var element = this.element;
+
+                               this.translateTo(x - element.scrollLeft, y - element.scrollTop, duration);
+                       };
+
+                       /**
+                        * Translates the scroll to specified position
+                        *
+                        * ### Example usage with TAU API
+                        *
+                        *        @example
+                        *        <div class="myPageClass" data-role="page">
+                        *            <div data-role="content" data-scroll="y">
+                        *                content
+                        *            </div>
+                        *        </div>
+                        *        <script>
+                        *            var scrollview = tau.widget.Scrollview(document.querySelector(".myPageClass > div[data-role=content]"));
+                        *            scrollview.translateTo(0, 200, 1000); // scroll forward 200px in vertical direction with 1s animation
+                        *        </script>
+                        *
+                        * ### Example usage with jQuery API
+                        *
+                        *        @example
+                        *        <div class="myPageClass" data-role="page">
+                        *            <div data-role="content" data-scroll="y">
+                        *                content
+                        *            </div>
+                        *        </div>
+                        *        <script>
+                        *            var element = $(".myPageClass > div[data-role=content]"));
+                        *            element.scrollview();
+                        *            element.scrollview("translateTo", 0, 200, 1000); // scroll forward 200px in vertical direction with 1s animation
+                        *        </script>
+                        *
+                        * @param {number} x
+                        * @param {number} y
+                        * @param {number=} [duration]
+                        * @method translateTo
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype.translateTo = function (x, y, duration) {
+                               translate(this._scrollState, this.element, x, y, duration);
+                       };
+
+                       /**
+                        * Ensures that specified element is visible in the
+                        * clip area
+                        *
+                        * ### Example usage with TAU API
+                        *
+                        *        @example
+                        *        <div class="myPageClass" data-role="page">
+                        *            <div data-role="content" data-scroll="y">
+                        *                content
+                        *                <div class="testElementClass">some data</div>
+                        *            </div>
+                        *        </div>
+                        *        <script>
+                        *            var scrollview = tau.widget.Scrollview(document.querySelector(".myPageClass > div[data-role=content]")),
+                        *                testElement = document.querySelector(".testElementClass");
+                        *            scrollview.ensureElementIsVisible(testElement);
+                        *        </script>
+                        *
+                        * ### Example usage with jQuery API
+                        *
+                        *        @example
+                        *        <div class="myPageClass" data-role="page">
+                        *            <div data-role="content" data-scroll="y">
+                        *                content
+                        *                <div class="testElementClass">some data</div>
+                        *            </div>
+                        *        </div>
+                        *        <script>
+                        *            var element = $(".myPageClass > div[data-role=content]")),
+                        *                testElement = $(".testElementClass");
+                        *            element.scrollview();
+                        *            element.scrollview("ensureElementIsVisible", testElement);
+                        *        </script>
+                        *
+                        * @param {HTMLElement} element
+                        * @method ensureElementIsVisible
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype.ensureElementIsVisible = function (element) {
+                               var clip = this.element,
+                                       clipHeight = DOMUtils.getElementHeight(clip),
+                                       clipWidth = DOMUtils.getElementWidth(clip),
+                                       clipTop = 0,
+                                       clipBottom = clipHeight,
+                                       elementHeight = DOMUtils.getElementHeight(element),
+                                       elementWidth = DOMUtils.getElementWidth(element),
+                                       elementTop = 0,
+                                       elementBottom,
+                                       elementFits = clipHeight >= elementHeight && clipWidth >= elementWidth,
+                                       anchor,
+                                       anchorPositionX,
+                                       anchorPositionY,
+                                       parent,
+                                       findPositionAnchor = function (input) {
+                                               var id = input.getAttribute("id"),
+                                                       tagName = input.tagName.toLowerCase();
+
+                                               if (id && ["input", "textarea", "button"].indexOf(tagName) > -1) {
+                                                       return input.parentNode.querySelector("label[for=" + id + "]");
+                                               }
+
+                                               return null;
+                                       },
+                                       _true = true;
+
+                               parent = element.parentNode;
+                               while (parent && parent !== clip) {
+                                       elementTop += parent.offsetTop;
+                                       //elementLeft += parent.offsetLeft;
+                                       parent = parent.parentNode;
+                               }
+                               elementBottom = elementTop + elementHeight;
+                               //elementRight = elementLeft + elementWidth;
+
+                               /* C1) element fits in view is inside clip area
+                                * C2) element visible only at top; eg. partly visible textarea
+                                * C3) element visible only at bottom
+                                * C4) element fits in view but its visible only at top
+                                * C5) element fits in view but its visible only at bottom
+                                */
+                               switch (_true) {
+                                       case elementFits && clipTop < elementTop && clipBottom > elementBottom:
+                                       case clipTop < elementTop && elementTop < clipBottom && clipBottom < elementBottom:
+                                       case clipTop > elementTop && clipBottom > elementBottom:
+                                               // (1) pass, element position is ok
+                                               // (2, 3) pass, we cant do anything, if we move the scroll the user could lost view of
+                                               // something he scrolled to
+                                               break;
+                                       case elementFits && clipTop < elementTop && clipBottom < elementBottom:
+                                       case elementFits && clipTop > elementTop && clipBottom > elementBottom:
+                                       case elementFits: // element fits in view but is not visible
+                                               this.centerToElement(element);
+                                               break;
+                                       default: // element is not visible
+                                               anchor = findPositionAnchor(element);
+                                               if (!anchor) {
+                                                       anchor = element;
+                                               }
+                                               anchorPositionX = anchor.offsetLeft + DOMUtils.getCSSProperty(anchor, "margin-left", 0, "integer");
+                                               anchorPositionY = anchor.offsetTop + DOMUtils.getCSSProperty(anchor, "margin-top", 0, "integer");
+                                               parent = anchor.parentNode;
+                                               while (parent && parent !== clip) {
+                                                       anchorPositionX += parent.offsetLeft;
+                                                       anchorPositionY += parent.offsetTop;
+                                                       parent = parent.parentNode;
+                                               }
+                                               this.scrollTo(anchorPositionX, anchorPositionY, this.scrollDuration);
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * Centers specified element in the clip area
+                        *
+                        * ### Example usage with TAU API
+                        *
+                        *        @example
+                        *        <div class="myPageClass" data-role="page">
+                        *            <div data-role="content" data-scroll="y">
+                        *                content
+                        *                <div class="testElementClass">some data</div>
+                        *            </div>
+                        *        </div>
+                        *        <script>
+                        *            var scrollview = tau.widget.Scrollview(document.querySelector(".myPageClass > div[data-role=content]")),
+                        *                testElement = document.querySelector(".testElementClass");
+                        *            scrollview.centerToElement(testElement);
+                        *        </script>
+                        *
+                        * ### Example usage with jQuery API
+                        *
+                        *        @example
+                        *        <div class="myPageClass" data-role="page">
+                        *            <div data-role="content" data-scroll="y">
+                        *                content
+                        *                <div class="testElementClass">some data</div>
+                        *            </div>
+                        *        </div>
+                        *        <script>
+                        *            var element = $(".myPageClass > div[data-role=content]")),
+                        *                testElement = $(".testElementClass");
+                        *            element.scrollview();
+                        *            element.scrollview("centerToElement", testElement);
+                        *        </script>
+                        *
+                        * @param {HTMLElement} element
+                        * @method centerToElement
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype.centerToElement = function (element) {
+                               var clip = this.element,
+                                       deltaX = parseInt(DOMUtils.getElementWidth(clip) / 2 - DOMUtils.getElementWidth(element) / 2, 10),
+                                       deltaY = parseInt(DOMUtils.getElementHeight(clip) / 2 - DOMUtils.getElementHeight(element) / 2, 10),
+                                       elementPositionX = element.offsetLeft,
+                                       elementPositionY = element.offsetTop,
+                                       parent = element.parentNode;
+
+                               while (parent && parent !== clip) {
+                                       elementPositionX += parent.offsetLeft + DOMUtils.getCSSProperty(parent, "margin-left", 0, "integer");
+                                       elementPositionY += parent.offsetTop + DOMUtils.getCSSProperty(parent, "margin-top", 0, "integer");
+                                       parent = parent.parentNode;
+                               }
+                               this.scrollTo(elementPositionX - deltaX, elementPositionY - deltaY, this.scrollDuration);
+                       };
+
+                       /**
+                        * Returns scroll current position
+                        *
+                        *        @example
+                        *        <div class="myPageClass" data-role="page">
+                        *            <div data-role="content" data-scroll="y">
+                        *                content
+                        *            </div>
+                        *        </div>
+                        *        <script>
+                        *            var scrollview = tau.widget.Scrollview(document.querySelector(".myPageClass > div[data-role=content]")),
+                        *                currentPosition = scrollview.getScrollPosition();
+                        *        </script>
+                        *
+                        * ### Example usage with jQuery API
+                        *
+                        *        @example
+                        *        <div class="myPageClass" data-role="page">
+                        *            <div data-role="content" data-scroll="y">
+                        *                content
+                        *            </div>
+                        *        </div>
+                        *        <script>
+                        *            var element = $(".myPageClass > div[data-role=content]")),
+                        *                position;
+                        *            element.scrollview();
+                        *            position = element.scrollview("getScrollPosition");
+                        *        </script>
+                        *
+                        * @return {Object}
+                        * @method getScrollPosition
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype.getScrollPosition = function () {
+                               var element = this.element;
+
+                               return {
+                                       "x": element.scrollLeft,
+                                       "y": element.scrollTop
+                               };
+                       };
+
+                       /**
+                        * Binds scrollview events
+                        * @method _bindEvents
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype._bindEvents = function (element) {
+                               var scrollTimer = null,
+                                       notifyScrolled = function () {
+                                               eventUtils.trigger(element, "scrollstop");
+                                               window.clearTimeout(scrollTimer);
+                                               scrollTimer = null;
+                                       },
+                                       self = this,
+                                       //FIXME there should be some other way to get parent container
+                                       ui = self._ui,
+                                       page = ui.page,
+                                       jumpTop = ui.jumpVerticalButton,
+                                       jumpLeft = ui.jumpHorizontalButton,
+                                       repositionJumpsCallback,
+                                       jumpTopCallback,
+                                       jumpLeftCallback,
+                                       callbacks = self._callbacks,
+                                       scrollDirection = self.options.scroll;
+
+                               if (page) {
+                                       if (self.options.scrollJump) {
+                                               repositionJumpsCallback = repositionJumps.bind(null, self);
+                                               jumpTopCallback = function () {
+                                                       self.scrollTo(element.scrollLeft, 0, 250);
+                                               };
+                                               jumpLeftCallback = function () {
+                                                       self.scrollTo(0, element.scrollTop, 250);
+                                               };
+                                               page.addEventListener(pageEvents.SHOW, repositionJumpsCallback, false);
+                                               if (jumpTop) {
+                                                       jumpTop.firstChild.addEventListener("vclick", jumpTopCallback, false);
+                                               }
+                                               if (jumpLeft) {
+                                                       jumpLeft.firstChild.addEventListener("vclick", jumpLeftCallback, false);
+                                               }
+
+                                               callbacks.repositionJumps = repositionJumpsCallback;
+                                               callbacks.jumpTop = jumpTopCallback;
+                                               callbacks.jumpLeft = jumpLeftCallback;
+                                       }
+
+                                       element.addEventListener("scroll", function () {
+                                               if (scrollTimer) {
+                                                       window.clearTimeout(scrollTimer);
+                                               } else {
+                                                       eventUtils.trigger(element, "scrollstart");
+                                               }
+
+                                               if (scrollDirection === "y" &&
+                                                       (element.scrollTop === 0 || element.scrollTop + element.clientHeight === element.scrollHeight)) {
+                                                       eventUtils.trigger(element, "scrollboundary", {
+                                                               direction: (element.scrollTop === 0) ? "top" : "bottom"
+                                                       });
+                                               } else if (scrollDirection === "x" &&
+                                                       (element.scrollLeft === 0 || element.scrollLeft + element.clientWidth === element.scrollWidth)) {
+                                                       eventUtils.trigger(element, "scrollboundary", {
+                                                               direction: (element.scrollLeft === 0) ? "left" : "right"
+                                                       });
+                                               }
+
+                                               scrollTimer = window.setTimeout(notifyScrolled, 100);
+                                               eventUtils.trigger(element, "scrollupdate");
+                                       }, false);
+
+                                       document.addEventListener("vmousedown", function () {
+                                               if (currentTransition) {
+                                                       currentTransition = null;
+                                               }
+                                       }, false);
+
+                                       if (self.options.scrollIndicator) {
+                                               callbacks.scrollUpdate = self._showScrollIndicator.bind(self);
+                                               element.addEventListener("scrollupdate", callbacks.scrollUpdate, false);
+                                               callbacks.scrollStop = self._hideScrollIndicator.bind(self);
+                                               element.addEventListener("scrollstop", callbacks.scrollStop, false);
+                                       }
+
+                               }
+                       };
+
+                       Scrollview.prototype._destroy = function () {
+                               var self = this,
+                                       element = self.element,
+                                       ui = self._ui,
+                                       page = ui.page,
+                                       scrollJump = this.options.scrollJump,
+                                       jumpTop = ui.jumpVerticalButton,
+                                       jumpLeft = ui.jumpHorizontalButton,
+                                       callbacks = self._callbacks,
+                                       repositionJumpsCallback = callbacks.repositionJumps,
+                                       jumpTopCallback = callbacks.jumpTop,
+                                       jumpLeftCallback = callbacks.jumpLeft;
+
+                               if (scrollJump) {
+                                       if (page && repositionJumpsCallback) {
+                                               page.removeEventListener(pageEvents.SHOW, repositionJumpsCallback, false);
+                                       }
+                                       if (jumpTop && jumpTopCallback) {
+                                               jumpTop.firstChild.removeEventListener("vclick", jumpTopCallback, false);
+                                       }
+                                       if (jumpLeft && jumpLeftCallback) {
+                                               jumpLeft.firstChild.removeEventListener("vclick", jumpLeftCallback, false);
+                                       }
+                               }
+
+                               if (self.options.scrollIndicator) {
+                                       element.removeEventListener("scrollupdate", callbacks.scrollUpdate, false);
+                               }
+
+                               if (self._timers.scrollIndicatorHide) {
+                                       window.clearTimeout(self._timers.scrollIndicatorHide);
+                               }
+
+                       };
+
+                       /**
+                        * Enables scrollview action
+                        * @method enableScrolling
+                        * @public
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype.enableScrolling = function () {
+                               this._setClipOverflowStyle();
+                       }
+
+                       /**
+                        * Disables scrollview action
+                        * @method disableScrolling
+                        * @public
+                        * @member ns.widget.core.Scrollview
+                        */
+                       Scrollview.prototype.disableScrolling = function () {
+                               this._setClipOverflowHidden();
+                       }
+
+                       ns.widget.core.Scrollview = Scrollview;
+                       }(window, window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * @class ns.widget.mobile.Tab
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               events = ns.event,
+                               Tab = function () {
+                               },
+                               /**
+                                * Object with class dictionary
+                                * @property {Object} classes
+                                * @static
+                                * @member ns.widget.mobile.Tab
+                                * @readonly
+                                */
+                               classes = {},
+                               CustomEvent = {
+                                       TAB_CHANGE: "tabchange"
+                               },
+                               prototype = new BaseWidget();
+
+                       Tab.prototype = prototype;
+                       Tab.classes = classes;
+
+                       /**
+                        * Set the active tab
+                        * @method setActive
+                        * @param {number} index of the tab
+                        * @public
+                        * @member ns.widget.mobile.Tab
+                        */
+                       prototype._setActive = function (index) {
+                               var element = this.element;
+
+                               events.trigger(element, CustomEvent.TAB_CHANGE, {
+                                       active: index
+                               });
+                       };
+                       /**
+                        * Set the active tab
+                        * @method setActive
+                        * @param {number} index of the tab
+                        * @public
+                        * @member ns.widget.mobile.Tab
+                        */
+                       prototype.setActive = function (index) {
+                               this._setActive(index);
+                       };
+
+                       /**
+                        * Get the active tab
+                        * @method setActive
+                        * @public
+                        * @member ns.widget.mobile.Tab
+                        */
+                       prototype._getActive = function () {
+                               return this.options.active;
+                       };
+
+                       /**
+                        * Get the active tab
+                        * @method setActive
+                        * @public
+                        * @member ns.widget.mobile.Tab
+                        */
+                       prototype.getActive = function () {
+                               return this._getActive();
+                       };
+
+                       ns.widget.core.Tab = Tab;
+                       engine.defineWidget(
+                               "Tab",
+                               "",
+                               ["setActive", "getActive"],
+                               Tab,
+                               "tizen"
+                       );
+                       }(window.document, ns));
+
+/*global window, ns, define, Event, console */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #TabIndicator Widget
+ * Widget create tabs indicator.
+ * @class ns.widget.core.TabIndicator
+ * @since 2.3
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var Tab = ns.widget.core.Tab,
+                               engine = ns.engine,
+                               object = ns.util.object,
+
+                               TabIndicator = function () {
+                                       this.tabSize = 0;
+                                       this.width = 0;
+                               },
+
+                               TabPrototype = Tab.prototype,
+                               prototype = new Tab();
+
+                       TabIndicator.prototype = prototype;
+
+                       prototype._init = function (element) {
+                               var o = this.options;
+
+                               this.width = element.offsetWidth;
+                               element.classList.add(o.wrapperClass);
+                       };
+
+                       prototype._configure = function () {
+                               /**
+                                * @property {Object} options Options for widget
+                                * @property {number} [options.margin=2]
+                                * @property {boolean} [options.triggerEvent=false]
+                                * @property {string} [options.wrapperClass="ui-tab-indicator]
+                                * @property {string} [options.itemClass="ui-tab-item"]
+                                * @property {string} [options.activeClass="ui-tab-active"]
+                                * @member ns.widget.core.TabIndicator
+                                */
+                               object.merge(this.options, {
+                                       margin: 4,
+                                       triggerEvent: false,
+                                       wrapperClass: "ui-tab-indicator",
+                                       itemClass: "ui-tab-item",
+                                       activeClass: "ui-tab-active",
+                                       active: 0
+                               });
+                       };
+
+                       prototype._createIndicator = function () {
+                               var o = this.options,
+                                       wrap = document.createDocumentFragment(),
+                                       widthTable = [],
+                                       margin = o.margin,
+                                       i = 0,
+                                       len = this.tabSize,
+                                       width = this.width - margin * (len - 1),
+                                       std = Math.floor(width / len),
+                                       remain = width % len,
+                                       span,
+                                       offset = 0;
+
+                               for (i = 0; i < len; i++) {
+                                       widthTable[i] = std;
+                               }
+
+                               for (i = Math.floor((len - remain) / 2); remain > 0; i++, remain--) {
+                                       widthTable[i] += 1;
+                               }
+
+                               for (i = 0; i < len; i++) {
+                                       span = document.createElement("span");
+                                       span.classList.add(o.itemClass);
+                                       span.style.width = widthTable[i] + "px";
+                                       span.style.left = offset + "px";
+                                       offset += widthTable[i] + margin;
+
+                                       if (i === o.active) {
+                                               span.classList.add(o.activeClass);
+                                       }
+                                       wrap.appendChild(span);
+                               }
+
+                               this.element.appendChild(wrap);
+                       };
+
+                       prototype._removeIndicator = function () {
+                               this.element.innerHTML = "";
+                       };
+
+                       prototype._refresh = function () {
+                               this._removeIndicator();
+                               this._createIndicator();
+                       };
+
+                       /**
+                        * @method setActive
+                        * @param {number} index
+                        * @member ns.widget.core.TabIndicator
+                        */
+                       prototype._setActive = function (index) {
+                               var o = this.options,
+                                       nodes = this.element.children;
+
+                               o.active = index;
+
+                               [].forEach.call(nodes, function (element) {
+                                       element.classList.remove(o.activeClass);
+                               });
+
+                               if (index < nodes.length) {
+                                       nodes[index].classList.add(o.activeClass);
+
+                                       TabPrototype._setActive.call(this, index);
+                               }
+                       };
+
+                       /**
+                        * @method setSize
+                        * @param {number} size
+                        * @member ns.widget.core.TabIndicator
+                        */
+                       prototype.setSize = function (size) {
+                               var needRefresh = this.tabSize !== size;
+
+                               this.tabSize = size;
+                               if (needRefresh) {
+                                       this.refresh();
+                               }
+                       };
+
+                       prototype._destroy = function () {
+                               var o = this.options;
+
+                               this._removeIndicator();
+
+                               this.element.classList.remove(o.wrapperClass);
+                       };
+
+                       ns.widget.core.TabIndicator = TabIndicator;
+
+                       engine.defineWidget(
+                               "TabIndicator",
+                               ".ui-tab",
+                               ["setActive", "getActive", "setSize"],
+                               TabIndicator
+                       );
+                       }(window.document, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, define, ns*/
+/**
+ * # Section Changer
+ * Section changer component provides an application architecture, which has multiple sections on one page.
+ *
+ * The section changer widget provides an application architecture, which has
+ * multiple sections on a page and enables scrolling through the *section* elements.
+ *
+ * ## Manual constructor
+ *
+ *      @example template tau-section-changer
+ *         <div class="ui-section-changer">
+ *             <div>
+ *                 <section style="text-align:center"><span>${1:Section 1}</span></section>
+ *                 <section style="text-align:center"><span>${2:Section 2}</span></section>
+ *             </div>
+ *         </div>
+ *
+ *
+ *      @example
+ *         <div id="hasSectionchangerPage" class="ui-page">
+ *             <header class="ui-header">
+ *                 <h2 class="ui-title">SectionChanger</h2>
+ *             </header>
+ *             <div id="sectionchanger" class="ui-content">
+ *                 <!--Section changer has only one child-->
+ *                 <div>
+ *                     <section>
+ *                         <h3>LEFT1 PAGE</h3>
+ *                     </section>
+ *                     <section class="ui-section-active">
+ *                         <h3>MAIN PAGE</h3>
+ *                     </section>
+ *                     <section>
+ *                         <h3>RIGHT1 PAGE</h3>
+ *                     </section>
+ *                 </div>
+ *             </div>
+ *         </div>
+ *         <script>
+ *             (function () {
+ *                 var page = document.getElementById("hasSectionchangerPage"),
+ *                     element = document.getElementById("sectionchanger"),
+ *                     sectionChanger;
+ *
+ *                 page.addEventListener("pageshow", function () {
+ *                     // Create the SectionChanger object
+ *                     sectionChanger = new tau.SectionChanger(element, {
+ *                         circular: true,
+ *                         orientation: "horizontal",
+ *                         useBouncingEffect: true
+ *                     });
+ *                 });
+ *
+ *                 page.addEventListener("pagehide", function () {
+ *                     // Release the object
+ *                     sectionChanger.destroy();
+ *                 });
+ *             })();
+ *         </script>
+ *
+ * ## Handling Events
+ *
+ * To handle section changer events, use the following code:
+ *
+ *      @example
+ *         <script>
+ *             (function () {
+ *                 var changer = document.getElementById("sectionchanger");
+ *                 changer.addEventListener("sectionchange", function (event) {
+ *                     console.debug(event.detail.active + " section is active.");
+ *                 });
+ *             })();
+ *         </script>
+ *
+ * @class ns.widget.core.SectionChanger
+ * @since 2.4
+ * @component-selector [data-role="section-changer"], .ui-section-changer
+ * @component-type container-component
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var Scroller = ns.widget.core.scroller.Scroller,
+                               gesture = ns.event.gesture,
+                               Orientation = gesture.Orientation,
+                               engine = ns.engine,
+                               utilsObject = ns.util.object,
+                               utilsEvents = ns.event,
+                               objectMerge = ns.util.object.merge,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               Page = ns.widget.core.Page,
+                               selectors = ns.util.selectors,
+                               eventType = objectMerge({
+                                       /**
+                                        * Triggered when the section is changed.
+                                        * @event sectionchange
+                                        * @member ns.widget.core.SectionChanger
+                                        */
+                                       CHANGE: "sectionchange"
+                               }, Scroller.EventType),
+                               classes = {
+                                       uiSectionChanger: "ui-section-changer"
+                               },
+                               /**
+                                * Options for widget
+                                * @property {Object} defaultOptions
+                                * @property {"horizontal"|"vertical"} [defaultOptions.orientation="horizontal"] Sets the section changer orientation:
+                                * @property {boolean} [defaultOptions.circular=false] Presents the sections in a circular scroll fashion.
+                                * @property {boolean} [defaultOptions.useBouncingEffect=false] Shows a scroll end effect on the scroll edge.
+                                * @property {string} [defaultOptions.items="section"] Defines the section element selector.
+                                * @property {string} [defaultOptions.activeClass="ui-section-active"] Specifies the CSS classes which define the active section element. Add the specified class (ui-section-active) to a *section* element to indicate which section must be shown first. By default, the first section is shown first.
+                                * @property {boolean} [defaultOptions.fillContent=true] declare to section tag width to fill content or not.
+                                * @member ns.widget.core.SectionChanger
+                                */
+                               defaultOptions = {
+                                       items: "section",
+                                       activeClass: "ui-section-active",
+                                       circular: false,
+                                       animate: true,
+                                       animateDuration: 100,
+                                       orientation: "horizontal",
+                                       changeThreshold: -1,
+                                       useTab: false,
+                                       fillContent: true,
+                                       model: null,
+                                       directives: null
+                               };
+
+                       function SectionChanger() {
+                               this.options = objectMerge({}, defaultOptions);
+                               BaseKeyboardSupport.call(this);
+                               this._ui = {
+                                       page: null
+                               };
+                       }
+
+                       function calculateCustomLayout(direction, elements, lastIndex) {
+                               var elementsLength = elements.length,
+                                       length = lastIndex !== undefined ? lastIndex : elementsLength,
+                                       result = 0,
+                                       i = 0;
+
+                               if (length > elementsLength) {
+                                       length = elementsLength;
+                               }
+
+                               for (i; i < length; i++) {
+                                       result += direction === Orientation.HORIZONTAL ? elements[i].offsetWidth : elements[i].offsetHeight;
+                               }
+                               return result;
+                       }
+
+                       function calculateCenter(direction, elements, index) {
+                               var result = calculateCustomLayout(direction, elements, index + 1),
+                                       element = elements[index];
+
+                               if (element) {
+                                       result -= direction === Orientation.HORIZONTAL ? element.offsetWidth / 2 : element.offsetHeight / 2;
+                               }
+
+                               return result;
+                       }
+
+                       utilsObject.inherit(SectionChanger, Scroller, {
+                               _build: function (element) {
+                                       var self = this,
+                                               options = self.options;
+
+                                       self.tabIndicatorElement = null;
+                                       self.tabIndicator = null;
+
+                                       self.sections = null;
+                                       self.sectionPositions = [];
+
+                                       self.activeIndex = 0;
+                                       self.beforeIndex = 0;
+
+                                       self._super(element);
+
+                                       element.classList.add(classes.uiSectionChanger);
+
+                                       self.scroller.style.position = "absolute";
+                                       self.scroller.classList.add("ui-section-changer-container");
+                                       self.orientation = options.orientation === "horizontal" ? Orientation.HORIZONTAL : Orientation.VERTICAL;
+
+                                       return element;
+                               },
+
+                               _configure: function () {
+                                       this._super();
+                                       this.options = utilsObject.merge(this.options, defaultOptions);
+                               },
+
+                               /**
+                                * Generic method for data-bind for HTML element
+                                * @method _fillElementFromModel
+                                * @param {HTMLElement} element
+                                * @param {Object} dataItem
+                                * @param {Function[]} directive
+                                * @member ns.widget.core.SectionChanger
+                                * @protected
+                                */
+                               _fillElementFromModel: function (element, dataItem, directive) {
+                                       var itemName,
+                                               dataBoundElement;
+
+                                       for (itemName in dataItem) {
+                                               if (dataItem.hasOwnProperty(itemName)) {
+                                                       dataBoundElement = element.querySelector("[data-bind='" + itemName + "']");
+                                                       if (dataBoundElement) {
+                                                               if (directive && typeof directive[itemName] === "function") {
+                                                                       directive[itemName].call(dataBoundElement, dataItem[itemName]);
+                                                               } else {
+                                                                       dataBoundElement.innerText = dataItem[itemName];
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+
+                               _setModel: function (element, value) {
+                                       this.options.model = value;
+                                       this._findDataBinding();
+                               },
+
+                               /**
+                                * Specific method for widget filling from model
+                                * @method _fillElementFromModel
+                                * @param {string} key
+                                * @param {Array} data
+                                * @param {Function} directive
+                                * @member ns.widget.core.SectionChanger
+                                * @protected
+                                */
+                               _fillWidgetFromModel: function (key, data, directive) {
+                                       var self = this,
+                                               element = self.element,
+                                               dataBoundElements,
+                                               dataBoundElement,
+                                               content,
+                                               parentElement;
+
+                                       // clone section for all items
+                                       dataBoundElements = element.querySelectorAll("[data-bind='" + key + "'] > section");
+
+                                       if (dataBoundElements.length === 1) { // clone element for each item
+                                               dataBoundElement = dataBoundElements[0];
+                                               content = dataBoundElement.innerHTML;
+                                               parentElement = dataBoundElement.parentElement;
+
+                                               parentElement.removeChild(dataBoundElement);
+                                               data.forEach(function (dataItem) {
+                                                       var newElement = dataBoundElement.cloneNode();
+
+                                                       newElement.innerHTML = content;
+                                                       self._fillElementFromModel(newElement, dataItem, directive);
+
+                                                       parentElement.appendChild(newElement);
+                                               });
+                                       } else {
+                                               // @todo
+                                               // fill existent elements by data
+                                       }
+                               },
+
+                               _findDataBinding: function () {
+                                       var model = this.options.model,
+                                               modelItem,
+                                               directives = this.options.directives,
+                                               directive,
+                                               key;
+
+                                       // create items for data
+                                       if (model) {
+                                               for (key in model) {
+                                                       if (model.hasOwnProperty(key)) {
+                                                               modelItem = model[key];
+                                                               if (typeof modelItem === "string") {
+                                                                       // @todo
+                                                                       // innerText for item
+                                                               } else if (Array.isArray(modelItem)) {
+                                                                       if (directives) {
+                                                                               directive = directives[key];
+                                                                       }
+                                                                       this._fillWidgetFromModel(key, modelItem, directive);
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               },
+
+                               _init: function (element) {
+                                       var self = this,
+                                               options = self.options,
+                                               scroller = self.scroller,
+                                               sectionLength,
+                                               i,
+                                               className,
+                                               ui = self._ui;
+
+                                       if (options.scrollbar === "tab") {
+                                               options.scrollbar = false;
+                                               options.useTab = true;
+                                       }
+
+                                       if (options.model) {
+                                               self._findDataBinding();
+                                       }
+
+                                       // find parent page
+                                       ui.page = selectors.getClosestBySelector(self.element, "." + Page.classes.uiPage);
+
+                                       if (scroller) {
+                                               self.sections = typeof options.items === "string" ?
+                                                       scroller.querySelectorAll(options.items) :
+                                                       options.items;
+
+                                               sectionLength = self.sections.length;
+
+                                               if (options.circular && sectionLength < 3) {
+                                                       ns.error("[SectionChanger] if you use circular option, you must have at least three sections.");
+                                               } else {
+                                                       for (i = 0; i < sectionLength; i++) {
+                                                               className = self.sections[i].className;
+                                                               if (className && className.indexOf(options.activeClass) > -1) {
+                                                                       self.activeIndex = i;
+                                                               } else {
+                                                                       if (self.isKeyboardSupport === true) {
+                                                                               self.disableFocusableElements(self.sections[i]);
+                                                                       }
+                                                               }
+
+                                                               self.sectionPositions[i] = i;
+                                                       }
+
+                                                       self._prepareLayout();
+                                                       self._initLayout();
+                                                       self._super(element);
+                                                       self._repositionSections(true);
+                                                       self.setActiveSection(self.activeIndex);
+
+                                                       // set correct options values.
+                                                       if (!options.animate) {
+                                                               options.animateDuration = 0;
+                                                       }
+                                                       if (options.changeThreshold < 0) {
+                                                               options.changeThreshold = self._sectionChangerHalfWidth;
+                                                       }
+                                               }
+                                       }
+
+                                       return element;
+                               },
+
+                               _prepareLayout: function () {
+                                       var o = this.options,
+                                               sectionLength = this.sections.length,
+                                               orientation = this.orientation,
+                                               scrollerStyle = this.scroller.style,
+                                               offsetHeight = this.element.offsetHeight,
+                                               tabHeight;
+
+                                       if (offsetHeight === 0) {
+                                               offsetHeight = this.element.parentNode.offsetHeight;
+                                               this.element.style.height = offsetHeight + "px";
+                                       }
+
+                                       this._sectionChangerWidth = this.element.offsetWidth;
+                                       this._sectionChangerHeight = offsetHeight;
+                                       this._sectionChangerHalfWidth = this._sectionChangerWidth / 2;
+                                       this._sectionChangerHalfHeight = this._sectionChangerHeight / 2;
+
+                                       if (o.useTab) {
+                                               this._initTabIndicator();
+                                               tabHeight = this.tabIndicatorElement.offsetHeight;
+                                               this._sectionChangerHeight -= tabHeight;
+                                               this._sectionChangerHalfHeight = this._sectionChangerHeight / 2;
+                                               this.element.style.height = this._sectionChangerHeight + "px";
+                                       }
+
+                                       if (orientation === Orientation.HORIZONTAL) {
+                                               scrollerStyle.width = (o.fillContent ? this._sectionChangerWidth * sectionLength : calculateCustomLayout(orientation, this.sections)) + "px";
+                                               scrollerStyle.height = this._sectionChangerHeight + "px";
+                                       } else {
+                                               scrollerStyle.width = this._sectionChangerWidth + "px";
+                                               scrollerStyle.height = (o.fillContent ? this._sectionChangerHeight * sectionLength : calculateCustomLayout(orientation, this.sections)) + "px";
+                                       }
+
+                               },
+
+                               _initLayout: function () {
+                                       var sectionStyle,
+                                               left = 0,
+                                               top = 0,
+                                               i,
+                                               sectionLength;
+
+                                       //section element has absolute position
+                                       for (i = 0, sectionLength = this.sections.length; i < sectionLength; i++) {
+                                               //Each section set initialize left position
+                                               sectionStyle = this.sections[i].style;
+                                               sectionStyle.position = "absolute";
+                                               if (this.options.fillContent) {
+                                                       sectionStyle.width = this._sectionChangerWidth + "px";
+                                                       sectionStyle.height = this._sectionChangerHeight + "px";
+                                               }
+
+                                               if (this.orientation === Orientation.HORIZONTAL) {
+                                                       top = 0;
+                                                       left = calculateCustomLayout(this.orientation, this.sections, i);
+                                               } else {
+                                                       top = calculateCustomLayout(this.orientation, this.sections, i);
+                                                       left = 0;
+                                               }
+
+                                               sectionStyle.top = top + "px";
+                                               sectionStyle.left = left + "px";
+                                       }
+
+                               },
+
+                               _initBouncingEffect: function () {
+                                       var o = this.options;
+
+                                       if (!o.circular) {
+                                               this._super();
+                                       }
+                               },
+
+                               _translateScrollbar: function (x, y, duration, autoHidden) {
+                                       var self = this,
+                                               offset,
+                                               scrollbar = self.scrollbar;
+
+                                       if (scrollbar) {
+                                               if (self.orientation === Orientation.HORIZONTAL) {
+                                                       offset = -x + self.minScrollX;
+                                               } else {
+                                                       offset = -y + self.minScrollY;
+                                               }
+
+                                               scrollbar.translate(offset, duration, autoHidden);
+                                       }
+                               },
+
+                               _translateScrollbarWithPageIndex: function (pageIndex, duration) {
+                                       var offset;
+
+                                       if (!this.scrollbar) {
+                                               return;
+                                       }
+
+                                       offset = calculateCustomLayout(this.orientation, this.sections, this.activeIndex);
+
+                                       this.scrollbar.translate(offset, duration);
+                               },
+
+                               _initTabIndicator: function () {
+                                       var self = this,
+                                               tabElement = document.createElement("div"),
+                                               element = self.element,
+                                               tabIndicator = null;
+
+                                       self.tabIndicatorElement = tabElement;
+
+                                       element.parentNode.insertBefore(tabElement, element);
+
+                                       tabIndicator = new engine.instanceWidget(tabElement, "TabIndicator");
+                                       self.tabIndicator = tabIndicator;
+                                       tabIndicator.setSize(self.sections.length);
+                                       tabIndicator.setActive(self.activeIndex);
+                                       self.tabIndicatorHandler = function (event) {
+                                               this.tabIndicator.setActive(event.detail.active);
+                                       }.bind(self);
+                                       element.addEventListener(eventType.CHANGE, self.tabIndicatorHandler, false);
+                               },
+
+                               _clearTabIndicator: function () {
+                                       if (this.tabIndicator) {
+                                               this.element.parentNode.removeChild(this.tabIndicatorElement);
+                                               this.element.removeEventListener(eventType.CHANGE, this.tabIndicatorHandler, false);
+                                               this.tabIndicator.destroy();
+                                               this.tabIndicator = null;
+                                               this.tabIndicatorElement = null;
+                                               this.tabIndicatorHandler = null;
+                                       }
+                               },
+
+                               _resetLayout: function () {
+                                       var //scrollerStyle = this.scroller.style,
+                                               sectionStyle,
+                                               i,
+                                               sectionLength;
+
+                                       //scrollerStyle.width = "";
+                                       //scrollerStyle.height = "";
+                                       //this.scroller || this.scroller._resetLayout();
+
+                                       for (i = 0, sectionLength = this.sections.length; i < sectionLength; i++) {
+                                               sectionStyle = this.sections[i].style;
+
+                                               sectionStyle.position = "";
+                                               sectionStyle.width = "";
+                                               sectionStyle.height = "";
+                                               sectionStyle.top = "";
+                                               sectionStyle.left = "";
+                                       }
+
+                                       this._super();
+                               },
+
+                               _bindEvents: function () {
+                                       var self = this;
+
+                                       self._super();
+
+                                       if (self.scroller) {
+                                               ns.event.enableGesture(
+                                                       self.scroller,
+
+                                                       new ns.event.gesture.Swipe({
+                                                               orientation: self.orientation === Orientation.HORIZONTAL ?
+                                                                       gesture.Orientation.HORIZONTAL :
+                                                                       gesture.Orientation.VERTICAL
+                                                       })
+                                               );
+
+                                               utilsEvents.on(self.scroller,
+                                                       "swipe transitionEnd webkitTransitionEnd mozTransitionEnd msTransitionEnd oTransitionEnd", self);
+                                               if (self._ui.page) {
+                                                       utilsEvents.on(self._ui.page, "taufocusborder", self);
+                                               }
+                                       }
+
+                                       // disable tau rotaryScroller, this widget has own support for rotary event
+                                       ns.util.rotaryScrolling && ns.util.rotaryScrolling.lock();
+
+                                       document.addEventListener("rotarydetent", self, true);
+                               },
+
+                               _unbindEvents: function () {
+                                       var self = this;
+
+                                       self._super();
+
+                                       if (self.scroller) {
+                                               ns.event.disableGesture(self.scroller);
+                                               utilsEvents.off(self.scroller,
+                                                       "swipe transitionEnd webkitTransitionEnd mozTransitionEnd msTransitionEnd oTransitionEnd", self);
+                                               if (self._ui.page) {
+                                                       utilsEvents.off(self._ui.page, "taufocusborder", self);
+                                               }
+                                       }
+
+                                       document.removeEventListener("rotarydetent", self, true);
+
+                                       // disable tau rotaryScroller, this widget has own support for rotary event
+                                       ns.util.rotaryScrolling && ns.util.rotaryScrolling.unlock();
+                               },
+
+                               /**
+                                * This method manages events.
+                                * @method handleEvent
+                                * @param {Event} event
+                                * @member ns.widget.core.SectionChanger
+                                */
+                               handleEvent: function (event) {
+                                       this._super(event);
+
+                                       switch (event.type) {
+                                               case "swipe":
+                                               case "taufocusborder":
+                                                       this._change(event);
+                                                       break;
+                                               case "rotarydetent" :
+                                                       this._change(event, true);
+                                                       break;
+                                               case "webkitTransitionEnd":
+                                               case "mozTransitionEnd":
+                                               case "msTransitionEnd":
+                                               case "oTransitionEnd":
+                                               case "transitionEnd":
+                                                       if (event.target === this.scroller) {
+                                                               this._endScroll();
+                                                       }
+                                                       break;
+                                       }
+                               },
+
+                               _notifyChangedSection: function (index) {
+                                       var activeClass = this.options.activeClass,
+                                               sectionLength = this.sections.length,
+                                               i = 0,
+                                               section;
+
+                                       for (i = 0; i < sectionLength; i++) {
+                                               section = this.sections[i];
+                                               section.classList.remove(activeClass);
+                                               if (i === this.activeIndex) {
+                                                       section.classList.add(activeClass);
+                                               }
+                                       }
+
+                                       this.trigger(eventType.CHANGE, {
+                                               active: index
+                                       });
+                               },
+
+                               /**
+                                * Changes the currently active section element.
+                                * @method setActiveSection
+                                * @param {number} index
+                                * @param {number} [duration=0] For smooth scrolling,
+                                * the duration parameter must be in milliseconds.
+                                * @param {boolean} [direct=false] Whether section is set once directly (e.g. with bezel)
+                                *  or with touch events
+                                * @param {boolean} [reposition=true] Whether sections should be repositioned
+                                * @member ns.widget.core.SectionChanger
+                                */
+                               setActiveSection: function (index, duration, direct, reposition) {
+                                       var position = this.sectionPositions[index],
+                                               scrollbarDuration,
+                                               oldActiveIndex = this.activeIndex,
+                                               newX = 0,
+                                               newY = 0;
+
+                                       //default parameters
+                                       duration = duration || 0;
+                                       direct = !!direct;
+                                       if (reposition == undefined) {
+                                               reposition = true;
+                                       }
+
+                                       scrollbarDuration = duration;
+
+                                       if (this.orientation === Orientation.HORIZONTAL) {
+                                               newX = this._sectionChangerHalfWidth - calculateCenter(this.orientation, this.sections, position);
+
+                                       } else {
+                                               newY = this._sectionChangerHalfHeight - calculateCenter(this.orientation, this.sections, position);
+                                       }
+
+                                       if (this.beforeIndex - index > 1 || this.beforeIndex - index < -1) {
+                                               scrollbarDuration = 0;
+                                       }
+
+                                       // disable keyboard on latest section
+                                       if (this.activeIndex !== index && this.isKeyboardSupport === true) {
+                                               this.disableFocusableElements(this.sections[this.activeIndex]);
+                                       }
+
+                                       this.activeIndex = index;
+                                       this.beforeIndex = this.activeIndex;
+
+                                       if (newX !== this.scrollerOffsetX || newY !== this.scrollerOffsetY) {
+                                               if (direct !== false) {
+                                                       this.trigger(eventType.START);
+                                                       this.scrolled = true;
+                                               }
+
+                                               this._translate(newX, newY, duration);
+                                               this._translateScrollbarWithPageIndex(index, scrollbarDuration);
+                                       } else {
+                                               this._endScroll();
+                                       }
+
+                                       // notify changed section.
+                                       if (this.activeIndex !== oldActiveIndex) {
+                                               this._notifyChangedSection(this.activeIndex);
+                                       }
+
+                                       if (reposition) {
+                                               this._repositionSections(true);
+                                       }
+
+                               },
+
+                               /**
+                                * Gets the currently active section element's index.
+                                * @method getActiveSectionIndex
+                                * @return {number}
+                                * @member ns.widget.core.SectionChanger
+                                */
+                               getActiveSectionIndex: function () {
+                                       return this.activeIndex;
+                               },
+
+                               _start: function (e) {
+                                       this._super(e);
+
+                                       this.beforeIndex = this.activeIndex;
+                               },
+
+                               _move: function (event) {
+                                       var self = this,
+                                               changeThreshold = self.options.changeThreshold,
+                                               delta = self.orientation === Orientation.HORIZONTAL ? event.detail.deltaX : event.detail.deltaY,
+                                               oldActiveIndex = self.activeIndex,
+                                               beforeIndex = self.beforeIndex;
+
+                                       self._super(event);
+
+                                       if (self.scrolled) {
+                                               if (delta > changeThreshold) {
+                                                       self.activeIndex = self._calculateIndex(beforeIndex - 1);
+                                               } else if (delta < -changeThreshold) {
+                                                       self.activeIndex = self._calculateIndex(beforeIndex + 1);
+                                               } else {
+                                                       self.activeIndex = beforeIndex;
+                                               }
+
+                                               // notify changed section.
+                                               if (self.activeIndex !== oldActiveIndex) {
+                                                       self._notifyChangedSection(self.activeIndex);
+                                               }
+                                       }
+                               },
+
+                               _end: function () {
+                                       var self = this;
+
+                                       if (self.scrollbar) {
+                                               self.scrollbar.end();
+                                       }
+
+                                       if (self.enabled && !self.scrollCanceled && self.dragging) {
+                                               // bouncing effect
+                                               if (self.bouncingEffect) {
+                                                       self.bouncingEffect.dragEnd();
+                                               }
+
+                                               self.setActiveSection(self.activeIndex, self.options.animateDuration, false, false);
+                                               self.dragging = false;
+                                       }
+                               },
+
+                               /**
+                                * Changes the currently active section element.
+                                * @method _change
+                                * @param {event} event
+                                * @param {boolean} [direct=false]
+                                * @private
+                                */
+                               _change: function (event, direct) {
+                                       var self = this,
+                                               direction = event.detail.direction,
+                                               offset = direction === gesture.Direction.UP ||
+                                                       direction === gesture.Direction.LEFT ||
+                                                       direction === "CW" ? 1 : -1,
+                                               newIndex;
+
+                                       if (event.type === "taufocusborder") {
+                                               offset *= -1; // invert direction;
+                                       }
+
+                                       newIndex = self._calculateIndex(self.beforeIndex + offset);
+
+                                       direct = !!direct;
+
+                                       if (self.enabled && !self.scrollCanceled) {
+                                               // bouncing effect
+                                               if (self.bouncingEffect) {
+                                                       self.bouncingEffect.dragEnd();
+                                               }
+
+                                               if (self.activeIndex !== newIndex) {
+                                                       // disable keyboard on latest section
+                                                       if (self.isKeyboardSupport === true && self.sections) {
+                                                               self.disableFocusableElements(self.sections[self.activeIndex]);
+                                                               self.blurOnActiveElement();
+                                                       }
+                                                       self.activeIndex = newIndex;
+                                                       self._notifyChangedSection(newIndex);
+                                               }
+
+                                               self.setActiveSection(newIndex, self.options.animateDuration, direct, false);
+                                               self.dragging = false;
+                                       }
+                               },
+
+                               _endScroll: function () {
+                                       var self = this;
+
+                                       // enable keyboard focus on section at current index
+                                       if (this.isKeyboardSupport === true) {
+                                               self.enableDisabledFocusableElements(self.sections[self.activeIndex]);
+                                       }
+
+                                       if (!self.enabled || !self.scrolled || self.scrollCanceled) {
+                                               return;
+                                       }
+
+                                       self._repositionSections();
+                                       self._super();
+                               },
+
+                               _repositionSections: function (init) {
+                                       // if developer set circular option is true, this method used when webkitTransitionEnd event fired
+                                       var self = this,
+                                               sections = self.sections,
+                                               activeIndex = self.activeIndex,
+                                               orientation = self.orientation,
+                                               isHorizontal = orientation === Orientation.HORIZONTAL,
+                                               sectionLength = sections.length,
+                                               curPosition = self.sectionPositions[activeIndex],
+                                               centerPosition = Math.floor(sectionLength / 2),
+                                               circular = self.options.circular,
+                                               centerX = 0,
+                                               centerY = 0,
+                                               i,
+                                               sectionStyle,
+                                               sIdx,
+                                               top,
+                                               left,
+                                               newX,
+                                               newY;
+
+                                       if (isHorizontal) {
+                                               newX = -(calculateCenter(orientation, sections, (circular ? centerPosition : activeIndex)));
+                                               newY = 0;
+                                       } else {
+                                               newX = 0;
+                                               newY = -(calculateCenter(orientation, sections, (circular ? centerPosition : activeIndex)));
+                                       }
+
+                                       self._translateScrollbarWithPageIndex(activeIndex);
+
+                                       if (init || (curPosition === 0 || curPosition === sectionLength - 1)) {
+                                               if (isHorizontal) {
+                                                       centerX = self._sectionChangerHalfWidth + newX;
+                                               } else {
+                                                       centerY = self._sectionChangerHalfHeight + newY;
+                                               }
+                                               self._translate(centerX, centerY);
+
+                                               if (circular) {
+                                                       for (i = 0; i < sectionLength; i++) {
+                                                               sIdx = (sectionLength + activeIndex - centerPosition + i) % sectionLength;
+                                                               sectionStyle = sections[sIdx].style;
+
+                                                               self.sectionPositions[sIdx] = i;
+
+                                                               if (isHorizontal) {
+                                                                       top = 0;
+                                                                       left = calculateCustomLayout(orientation, sections, i);
+                                                               } else {
+                                                                       top = calculateCustomLayout(orientation, sections, i);
+                                                                       left = 0;
+                                                               }
+
+                                                               sectionStyle.top = top + "px";
+                                                               sectionStyle.left = left + "px";
+                                                       }
+                                               }
+                                       }
+                               },
+
+                               _calculateIndex: function (newIndex) {
+                                       var sectionLength = this.sections.length;
+
+                                       if (this.options.circular) {
+                                               newIndex = (sectionLength + newIndex) % sectionLength;
+                                       } else {
+                                               newIndex = newIndex < 0 ? 0 : (newIndex > sectionLength - 1 ? sectionLength - 1 : newIndex);
+                                       }
+
+                                       return newIndex;
+                               },
+
+                               _clear: function () {
+                                       this._clearTabIndicator();
+                                       this._super();
+                                       this.sectionPositions.length = 0;
+                               },
+
+                               _destroy: function () {
+                                       var element = this.element;
+
+                                       // clear dimensions set in _build
+                                       element.style.height = null;
+                                       element.style.width = null;
+                                       this._super();
+                               }
+                       });
+
+                       ns.widget.core.SectionChanger = SectionChanger;
+
+                       engine.defineWidget(
+                               "SectionChanger",
+                               "[data-role='section-changer'], .ui-section-changer",
+                               ["getActiveSectionIndex", "setActiveSection"],
+                               SectionChanger
+                       );
+                       }(window.document, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, define, ns */
+/**
+ * #Dimmer
+ *
+ * @example
+ *    <div class="ui-dimmer"></dimmer>
+ *
+ * @since 5.0
+ * @class ns.widget.core.Dimmer
+ * @extends ns.widget.core.BaseWidget
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+
+                               Dimmer = function () {
+                                       this.options = utilsObject.merge({}, Dimmer.defaults);
+                                       this.bulbMode = false;
+                                       this._observer = null;
+                                       this._observerCallback = this._checkStyleChange.bind(this);
+                                       this._refreshCallback = this.refresh.bind(this);
+                               },
+
+                               DOMUtils = ns.util.DOM,
+
+                               defaults = {
+                                       value: 50,
+                                       min: 0,
+                                       max: 100,
+                                       bulb: false,
+                                       options: "30:blue; 60:yellow; 100:red"
+                               },
+
+                               classes = {
+                                       UI_DIMMER: "ui-dimmer",
+                                       UI_DIMMER_BULB: "ui-dimmer-lightbulb",
+                                       UI_DIMMER_BULB_LIGHT: "ui-dimmer-lightbulb-light",
+                                       UI_DIMMER_TEXT: "ui-dimmer-text",
+                                       UI_DIMMER_HIDDEN: "ui-dimmer-hidden"
+                               },
+
+                               BaseWidget = ns.widget.BaseWidget,
+                               prototype = new BaseWidget();
+
+                       Dimmer.prototype = prototype;
+                       Dimmer.defaults = defaults;
+                       Dimmer.classes = classes;
+
+                       prototype._init = function (element) {
+                               var self = this,
+                                       observer = new MutationObserver(this._observerCallback);
+
+                               if (!element.getAttribute("value")) {
+                                       element.setAttribute("value", self.options.value);
+                               }
+
+                               observer.observe(element, {attributes: true});
+                               self._observer = observer;
+
+                               return element;
+                       };
+
+                       function rebuild(element, bulbMode) {
+                               var child = document.createElement("div"),
+                                       text = element.querySelector("." + classes.UI_DIMMER_TEXT),
+                                       light = element.querySelector("." + classes.UI_DIMMER_BULB_LIGHT),
+                                       elementCls = element.classList;
+
+                               if (child) {
+                                       if (bulbMode) {
+                                               text.classList.add(classes.UI_DIMMER_HIDDEN);
+                                               light.classList.remove(classes.UI_DIMMER_HIDDEN);
+                                       } else {
+                                               text.classList.remove(classes.UI_DIMMER_HIDDEN);
+                                               light.classList.add(classes.UI_DIMMER_HIDDEN);
+                                       }
+                               }
+
+                               if (bulbMode) {
+                                       elementCls.add(classes.UI_DIMMER_BULB);
+                               } else {
+                                       elementCls.remove(classes.UI_DIMMER_BULB);
+                               }
+                       }
+
+                       function processBulbMode(element) {
+                               return DOMUtils.getCSSProperty(element, "background-image", "none", "string") !==
+                                               "none";
+                       }
+
+                       prototype._checkStyleChange = function (mutationsList) {
+                               var self = this,
+                                       options = self.options,
+                                       refresh = self._refreshCallback;
+
+                               mutationsList.forEach(function (mutation) {
+                                       if (mutation.attributeName === "style") {
+                                               options.bulb = processBulbMode(mutation.target);
+                                               refresh();
+                                       }
+                               });
+                       };
+
+
+                       prototype._refresh = function () {
+                               var self = this;
+
+                               rebuild(self.element, self.options.bulb);
+                               self.value(self.options.value);
+                       };
+
+                       prototype._build = function (element) {
+                               var bulb = processBulbMode(element),
+                                       options = this.options,
+                                       textElement = element.querySelector("." + classes.UI_DIMMER_TEXT),
+                                       light = document.createElement("div");
+
+                               if (!textElement) {
+                                       textElement = document.createElement("span");
+                                       textElement.classList.add(classes.UI_DIMMER_TEXT);
+                                       element.appendChild(textElement);
+                               }
+                               light.classList.add(classes.UI_DIMMER_BULB_LIGHT);
+                               element.appendChild(light);
+
+                               if (!bulb) {
+                                       bulb = element.classList.contains(classes.UI_DIMMER_BULB);
+
+                                       if (!options.bulb) {
+                                               options.bulb = bulb;
+                                       }
+                               }
+
+                               rebuild(element, options.bulb);
+
+                               this._refreshValue(element);
+
+                               return element;
+                       };
+
+                       prototype._destroy = function () {
+                               this._observer.disconnect();
+                               this.element.innerHTML = "";
+                       };
+
+                       prototype._refreshValue = function (element) {
+                               var self = this,
+                                       options = self.options,
+                                       value = options.value,
+                                       min = options.min,
+                                       max = options.max,
+                                       textElement,
+                                       colors = [],
+                                       ranges = [],
+                                       opacity,
+                                       items,
+                                       itemArray,
+                                       lightElement,
+                                       i;
+
+                               element = element || self.element;
+                               textElement = element.querySelector(".ui-dimmer-text");
+
+                               if (!options.bulb) {
+                                       value = parseInt(value, 10);
+                                       opacity = value / max;
+                                       element.style.border = "60px solid rgba(0, 151, 216, " + opacity + ")";
+                                       textElement.innerHTML = value + "%";
+                                       return true;
+                               } else if (options.bulb && options.options) {
+                                       items = options.options.replace(/\s+/g, "").split(";").filter(function (item) {
+                                               return item && item.length > 0;
+                                       });
+
+                                       items.forEach(function (item) {
+                                               itemArray = item.split(":");
+                                               ranges.push(itemArray[0]);
+                                               colors.push(itemArray[1]);
+                                       });
+
+                                       lightElement = element.querySelector("." + classes.UI_DIMMER_BULB_LIGHT);
+                                       ranges.unshift(min);
+
+                                       for (i = 0; i < ranges.length; i++) {
+                                               if (i > 0 && value < ranges[i] && value > ranges[i - 1]) {
+                                                       lightElement.style.backgroundColor = colors[i - 1];
+                                                       return true;
+                                               }
+                                       }
+                               }
+                               return false;
+                       }
+
+                       prototype._setValue = function (element, value) {
+                               var self = this,
+                                       options = self.options;
+
+                               // Patch for BaseWidget.value
+                               if (!(element instanceof HTMLElement)) {
+                                       value = element;
+                                       element = self.element;
+                               }
+
+                               if (value < options.min) {
+                                       value = options.min;
+                               } else if (value > options.max) {
+                                       value = options.max;
+                               }
+
+                               options.value = value;
+                               element.setAttribute("value", value);
+
+                               self._refreshValue();
+
+                               return false;
+                       };
+
+                       prototype._setBulb = function (element, value) {
+                               this.options.bulb = value;
+
+                               return true;
+                       };
+
+                       prototype._getValue = function () {
+                               return parseInt(this.element.getAttribute("value"), 10);
+                       };
+
+                       ns.widget.core.Dimmer = Dimmer;
+                       ns.engine.defineWidget(
+                               "Dimmer",
+                               "." + classes.UI_DIMMER,
+                               [],
+                               Dimmer,
+                               "core"
+                       );
+                       }(window, window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Checkbox
+ * Checkbox component changes the default browser checkboxes to a form more adapted to the mobile
+ * environment.
+ *
+ * @since 2.4
+ * @class ns.widget.core.Checkbox
+ * @extends ns.widget.BaseWidget
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Checkbox
+ *
+ * ## HTML examples
+ *
+ * ### Basic use
+ *      @example template
+ *      <input type="checkbox"/>
+ *
+ * ### Checkbox with label
+ *      @example tau-checkbox
+ *      <input type="checkbox" name="${5:mycheck}" id="${3:check-test}" checked="${2:checked}"/>\n<label for="${4:check-test}">${1:Checkbox}</label>
+ *
+ * @class ns.widget.core.Checkbox
+ * @component-selector input[type="checkbox"]:not(.ui-slider-switch-input):not([data-role="toggleswitch"]):not(.ui-toggleswitch):not(.ui-switch-input), input.ui-checkbox
+ * @component-type standalone-component
+ * @component-attachable true
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               keyCodes = BaseKeyboardSupport.KEY_CODES,
+                               engine = ns.engine,
+                               eventUtils = ns.event,
+                               Checkbox = function () {
+                                       this.element = null;
+
+                                       BaseKeyboardSupport.call(this);
+                               },
+                               classes = {
+                                       checkbox: "ui-checkbox",
+                                       focus: "ui-checkbox-focus",
+                                       active: "ui-checkbox-active",
+                                       backwardAnimation: "ui-checkbox-backward-animation"
+                               },
+                               prototype = new BaseWidget();
+
+                       Checkbox.prototype = prototype;
+
+                       /**
+                        * Build Checkbox widget
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Checkbox
+                        * @instance
+                        */
+                       prototype._build = function (element) {
+                               if (element.getAttribute("type") === "checkbox") {
+                                       element.classList.add(classes.checkbox);
+                               }
+                               return element;
+                       };
+
+                       /**
+                        * Returns the value of checkbox
+                        * @method _getValue
+                        * @member ns.widget.core.Checkbox
+                        * @return {?string}
+                        * @protected
+                        */
+                       prototype._getValue = function () {
+                               return this.element.value;
+                       };
+
+                       /**
+                        * Set value to the checkbox
+                        * @method _setValue
+                        * @param {string} value
+                        * @member ns.widget.core.Checkbox
+                        * @return {ns.widget.core.Checkbox}
+                        * @protected
+                        */
+                       prototype._setValue = function (value) {
+                               this.element.value = value;
+                       };
+
+                       /**
+                        * Set focus on widget
+                        * @method _focus
+                        * @member ns.widget.core.Checkbox
+                        * @protected
+                        */
+                       prototype._focus = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               element.focus();
+                       };
+
+                       /**
+                        * Blurs focus from widget
+                        * @method _blur
+                        * @member ns.widget.core.Checkbox
+                        * @protected
+                        */
+                       prototype._blur = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               element.blur();
+                       };
+
+                       /**
+                        * Checkbox element focus callback
+                        * @method _onFocus
+                        * @member ns.widget.core.Checkbox
+                        * @protected
+                        */
+                       prototype._onFocus = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       element.classList.add(classes.focus);
+                               }
+                       };
+
+                       /**
+                        * Checkbox element blur callback
+                        * @method _onBlur
+                        * @member ns.widget.core.Checkbox
+                        * @protected
+                        */
+                       prototype._onBlur = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       element.classList.remove(classes.focus);
+                               }
+                       };
+
+                       /**
+                        * Checkbox element touch start callback
+                        * @method _onTouchStart
+                        * @member ns.widget.core.Checkbox
+                        * @protected
+                        */
+                       prototype._onTouchStart = function () {
+                               this.element.classList.add(classes.active);
+                       };
+
+                       /**
+                        * Checkbox element touch end callback
+                        * @method _onTouchEnd
+                        * @member ns.widget.core.Checkbox
+                        * @protected
+                        */
+                       prototype._onTouchEnd = function () {
+                               this.element.classList.remove(classes.active);
+                       };
+
+                       /**
+                        * Checkbox element keyup callback
+                        * @method _onKeyUp
+                        * @param {Event} event
+                        * @member ns.widget.core.Checkbox
+                        * @protected
+                        */
+                       prototype._onKeyUp = function (event) {
+                               var self = this,
+                                       element = self.element;
+
+                               if (event.keyCode === keyCodes.enter) {
+                                       eventUtils.trigger(element, "input");
+                                       element.checked = !element.checked;
+                                       eventUtils.trigger(element, "change");
+                               }
+                       }
+
+                       prototype._onAnimationEnd = function (event) {
+                               event.target.classList.toggle(classes.backwardAnimation, event.target.checked);
+                       };
+
+                       /**
+                        * Bind events to widgets
+                        * @method _bindEvents
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Checkbox
+                        * @protected
+                        */
+                       prototype._bindEvents = function (element) {
+                               var self = this;
+
+                               self._focusCallbackBound = self._onFocus.bind(self);
+                               self._blurCallbackBound = self._onBlur.bind(self);
+                               self._keyupCallbackBound = self._onKeyUp.bind(self);
+                               self._onTouchStart = self._onTouchStart.bind(self);
+                               self._onTouchEnd = self._onTouchEnd.bind(self);
+
+                               element.addEventListener("focus", self._focusCallbackBound, false);
+                               element.addEventListener("blur", self._blurCallbackBound, false);
+                               element.addEventListener("keyup", self._keyupCallbackBound, false);
+                               element.addEventListener("vmousedown", self._onTouchStart, false);
+                               element.addEventListener("vmouseup", self._onTouchEnd, false);
+                               eventUtils.on(element, "animationend animationEnd webkitAnimationEnd", self._onAnimationEnd, false);
+                       }
+
+                       /**
+                        * Unbinds events from widget
+                        * @method _unbindEvents
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Checkbox
+                        * @protected
+                        */
+                       prototype._unbindEvents = function (element) {
+                               var self = this;
+
+                               element.removeEventListener("focus", self._focusCallbackBound, false);
+                               element.removeEventListener("blur", self._blurCallbackBound, false);
+                               element.removeEventListener("keyup", self._keyupCallbackBound, false);
+                               element.removeEventListener("vmousedown", self._onTouchStart, false);
+                               element.removeEventListener("vmouseup", self._onTouchEnd, false);
+                       }
+
+                       // definition
+                       ns.widget.core.Checkbox = Checkbox;
+
+                       BaseKeyboardSupport.registerActiveSelector("input[type='checkbox'], input.ui-checkbox");
+
+                       engine.defineWidget(
+                               "Checkbox",
+                               "input[type='checkbox']:not(.ui-slider-switch-input):not([data-role='toggleswitch']):not([data-role='on-off-switch'])" +
+                               ":not(.ui-toggleswitch):not(.ui-toggle-switch):not(.ui-on-off-switch), input.ui-checkbox",
+                               [],
+                               Checkbox,
+                               "core",
+                               false,
+                               false,
+                               HTMLInputElement
+                       );
+
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Radio
+ *
+ *     @example template tau-radio
+ *         <input type="radio"/>
+ *
+ * @class ns.widget.core.Radio
+ * @component-selector input[type=radio]
+ * @component-type standalone-component
+ * @since 2.4
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               KEY_CODES = BaseKeyboardSupport.KEY_CODES,
+                               Radio = function () {
+                                       BaseKeyboardSupport.call(self);
+                                       this.element = null;
+                               },
+                               classes = {
+                                       /**
+                                        * Standard radio widget
+                                        * @style ui-radio
+                                        * @member ns.widget.core.Radio
+                                        */
+                                       radio: "ui-radio",
+                                       focus: "ui-radio-focus",
+                                       backwardAnimation: "ui-radio-backward-animation"
+                               },
+                               events = ns.event,
+                               prototype = new BaseWidget();
+
+                       Radio.prototype = prototype;
+
+                       /**
+                        * Build Radio widget
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.Radio
+                        * @instance
+                        */
+                       prototype._build = function (element) {
+                               if (element.getAttribute("type") === "radio") {
+                                       element.classList.add(classes.radio);
+                               }
+
+                               return element;
+                       };
+
+                       /**
+                        * Focus callback
+                        * @protected
+                        * @member ns.widget.Radio
+                        */
+                       prototype._onFocus = function () {
+                               var element = this.element;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       element.focus();
+                                       element.classList.add(classes.focus)
+                               }
+                       }
+
+                       /**
+                        * Blur callback
+                        * @protected
+                        * @member ns.widget.Radio
+                        */
+                       prototype._onBlur = function () {
+                               var element = this.element;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       element.blur();
+                                       element.classList.remove(classes.focus)
+                               }
+                       }
+
+                       /**
+                        * KeyUp callback
+                        * @protected
+                        * @param {Event} event
+                        * @member ns.widget.Radio
+                        */
+                       prototype._onKeyUp = function (event) {
+                               var element = this.element;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       if (event.keyCode === KEY_CODES.enter) {
+                                               element.checked = true;
+                                               events.trigger(element, "change");
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Handle events
+                        * @protected
+                        * @member ns.widget.Radio
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "focus":
+                                               self._onFocus(event);
+                                               break;
+                                       case "blur":
+                                               self._onBlur(event);
+                                               break;
+                                       case "keyup":
+                                               self._onKeyUp(event);
+                                               break;
+                                       case "animationend":
+                                       case "animationEnd":
+                                       case "webkitAnimationEnd":
+                                               self._onAnimationEnd(event);
+                                               break;
+                               }
+                       }
+
+                       prototype._onAnimationEnd = function (event) {
+                               event.target.classList.toggle(classes.backwardAnimation, event.target.checked);
+                       };
+
+                       /**
+                        * Binds events to a Radio widget
+                        * @method _bindEvents
+                        * @member ns.widget.core.Radio
+                        * @protected
+                        */
+                       prototype._bindEvents = function (element) {
+                               events.on(element, "focus blur keyup animationend animationEnd webkitAnimationEnd", this, false);
+                       }
+
+                       /**
+                        * Unbinds events from a Radio widget
+                        * @method _bindEvents
+                        * @member ns.widget.core.Radio
+                        * @protected
+                        */
+                       prototype._unbindEvents = function (element) {
+                               events.off(element, "focus blur keyup animationend animationEnd webkitAnimationEnd", this, false);
+                       };
+
+                       /**
+                        * Returns the value of radio
+                        * @method _getValue
+                        * @member ns.widget.Radio
+                        * @return {?string}
+                        * @protected
+                        */
+                       prototype._getValue = function () {
+                               return this.element.value;
+                       };
+
+                       /**
+                        * Set value to the radio
+                        * @method _setValue
+                        * @param {string} value
+                        * @member ns.widget.Radio
+                        * @return {ns.widget.Radio}
+                        * @protected
+                        */
+                       prototype._setValue = function (value) {
+                               this.element.value = value;
+                       };
+
+                       // definition
+                       ns.widget.core.Radio = Radio;
+                       engine.defineWidget(
+                               "Radio",
+                               "input[type='radio'], input.ui-radio",
+                               [],
+                               Radio,
+                               "core",
+                               false,
+                               false,
+                               HTMLInputElement
+                       );
+
+                       BaseKeyboardSupport.registerActiveSelector("input[type='radio'], input.ui-radio");
+
+                       }(window.document, ns));
+
+/*global ns, define */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Document cookie Utility
+ * Utility to menage session data in cookie
+ * @class ns.util.util
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var /**
+                               * Write value to session for indicated storage name
+                               * @method writeToCookie
+                               * @param {string} storageName
+                               * @param {string} value
+                               * @param {Date} [expires]
+                               * @member ns.util.cookie
+                               * @static
+                               * @private
+                               */
+                               writeToCookie = function (storageName, value, expires) {
+                                       var storageValue = "";
+
+                                       value = window.encodeURIComponent(value);
+                                       storageValue = storageName + "=" + value;
+                                       if (expires && expires instanceof Date) {
+                                               storageValue += ";expires=" + expires.toUTCString();
+                                       }
+
+                                       document.cookie = storageValue;
+                               },
+
+                               /**
+                                * Return value corresponding to storage name
+                                * @method readFromCookie
+                                * @param {string} storageName
+                                * @return {string}
+                                * @member ns.util.cookie
+                                * @static
+                                * @private
+                                */
+                               readFromCookie = function (storageName) {
+                                       var entries = document.cookie.split(";"),
+                                               value = "";
+
+                                       value = entries.filter(function (entry) {
+                                               return entry.indexOf(storageName + "=") > -1;
+                                       })[0];
+
+                                       if (value) {
+                                               value = window.decodeURIComponent(
+                                                       value.trim().replace(storageName + "=", "")
+                                               );
+                                       }
+                                       return value;
+                               };
+
+                       ns.util.cookie = {
+                               /**
+                                * Return value corresponding to storage name
+                                * @method readFromCookie
+                                * @param {string} storageName
+                                * @return {string}
+                                * @member ns.util.cookie
+                                * @static
+                                */
+                               readFromCookie: readFromCookie,
+
+                               /**
+                               * Write value to session for indicated storage name
+                               * @method writeToCookie
+                               * @param {string} storageName
+                               * @param {string} value
+                               * @param {Date} [expires]
+                               * @member ns.util.cookie
+                               * @static
+                               */
+                               writeToCookie: writeToCookie
+                       };
+                       }(window, window.document, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Panel
+ * Panel is component that can have header, content, footer, listview and so on like the page component.
+ *
+ * Panel has been made that developer can implement to multi panel in one page.
+ * But, Panel don't need to implement in one html file. Panel can be existed other html files.
+ * PanelChanger controlled Panel lifecycle so If you implement to Panel in PanelChanger, you can experience UX that multi page existed in one page.
+ *
+ * @class ns.widget.core.Panel
+ * @extends ns.widget.BaseWidget
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               events = ns.event,
+                               classes = {
+                                       /**
+                                        * Standard panel widget
+                                        * @style ui-panel
+                                        * @member ns.widget.core.Panel
+                                        */
+                                       PANEL: "ui-panel",
+                                       /**
+                                        * Set panel widget as active
+                                        * @style ui-panel-active
+                                        * @member ns.widget.core.Panel
+                                        */
+                                       ACTIVE_PANEL: "ui-panel-active"
+                               },
+                               EVENT_TYPE = {
+                                       BEFORE_CREATE: "panelbeforecreate",
+                                       CREATE: "panelcreate",
+                                       BEFORE_SHOW: "panelbeforeshow",
+                                       SHOW: "panelshow",
+                                       BEFORE_HIDE: "panelbeforehide",
+                                       HIDE: "panelhide",
+                                       CHANGE: "panelchange"
+                               },
+                               Panel = function () {
+                               },
+                               prototype = new BaseWidget();
+
+                       Panel.eventType = EVENT_TYPE;
+                       Panel.classes = classes;
+                       Panel.prototype = prototype;
+
+                       /**
+                        * Build Panel component
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} Returns built element
+                        * @member ns.widget.core.Panel
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               var routePanel = ns.router.Router.getInstance().getRoute("panel");
+
+                               element.classList.add(classes.PANEL);
+                               routePanel.setActive(element);
+
+                               return element;
+                       };
+
+                       /**
+                        * Destroy Panel component
+                        * @method _destroy
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} Returns built element
+                        * @member ns.widget.core.Panel
+                        * @protected
+                        */
+                       prototype._destroy = function (element) {
+                               events.trigger(element, EVENT_TYPE.HIDE);
+                       };
+                       // definition
+                       ns.widget.core.Panel = Panel;
+
+                       engine.defineWidget(
+                               "Panel",
+                               "[data-role='panel'], .ui-panel",
+                               [],
+                               Panel,
+                               "core"
+                       );
+                       }(window.document, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * # Panel Changer
+ * Panel changer and panel component provide multi page layout in a page component.
+ *
+ * PanelChanger managed panel life-cycle and routing. So, If you want to use panel likes page,
+ * you should wrap the pages as PanelChanger component.
+ *
+ * @since 2.4
+ * @class ns.widget.core.PanelChanger
+ * @component-selector .ui-panel-changer, [data-role]="panel-changer"
+ * @extends ns.widget.BaseWidget
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               selectors = ns.util.selectors,
+                               object = ns.util.object,
+                               cookie = ns.util.cookie,
+                               engine = ns.engine,
+                               page = ns.widget.core.Page,
+                               panel = ns.widget.core.Panel,
+                               events = ns.event,
+                               classes = {
+                                       PANEL_CHANGER: "ui-panel-changer",
+                                       PAGE: page.classes.uiPage,
+                                       PANEL: panel.classes.PANEL,
+                                       ACTIVE_PANEL: panel.classes.ACTIVE_PANEL,
+                                       HEADER: "ui-header",
+                                       FOOTER: "ui-footer",
+                                       PRE_IN: "pre-in",
+                                       IN: "-in",
+                                       OUT: "-out"
+                               },
+                               PanelChanger = function () {
+                                       var self = this;
+
+                                       self._ui = {};
+                                       self.options = {};
+                                       self.eventType = {};
+                                       self._animating = false;
+                                       self._animationClasses = {};
+                                       self.history = [];
+                               },
+                               DEFAULT = {
+                                       ANIMATE: "slide",
+                                       STORAGE_NAME: "panelhistory"
+                               },
+                               prototype = new BaseWidget();
+
+                       PanelChanger.default = DEFAULT;
+                       PanelChanger.classes = classes;
+                       PanelChanger.prototype = prototype;
+
+                       /**
+                        * Configure PanelChanger component
+                        * @method _configure
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._configure = function () {
+                               var self = this;
+
+                               object.merge(self.options, {
+                                       animationType: DEFAULT.ANIMATE,
+                                       manageHistory: true
+                               });
+                               object.merge(self.eventType, panel.eventType);
+                       };
+
+                       /**
+                        * Build PanelChanger component
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} element
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               element.classList.add(classes.PANEL_CHANGER);
+
+                               return element;
+                       };
+
+                       /**
+                        * Init PanelChanger component
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} element
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui;
+
+                               ui.page = selectors.getClosestByClass(element, classes.PAGE);
+                               ui.header = ui.page.querySelector("." + classes.HEADER);
+                               ui.footer = ui.page.querySelector("." + classes.FOOTER);
+                               ui.activePanel = ui.page.querySelector("." + classes.ACTIVE_PANEL);
+                               if (!ui.activePanel) {
+                                       ui.activePanel = ui.page.querySelector("[data-role='panel'], .ui-panel");
+                                       ui.activePanel.classList.add(classes.ACTIVE_PANEL);
+                               }
+                               ui.activePanel.style.display = "block";
+                               self._direction = "forward";
+                               cookie.writeToCookie(DEFAULT.STORAGE_NAME, JSON.stringify([]));
+                               self.history.push(ui.activePanel.id);
+                               cookie.writeToCookie(DEFAULT.STORAGE_NAME, JSON.stringify(self.history));
+                               self._animationType = self.options.animationType;
+                               this._initLayout();
+                               return element;
+                       };
+
+                       /**
+                        * InitLayout PanelChanger component
+                        * @method _initLayout
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._initLayout = function () {
+                               var self = this,
+                                       element = self.element,
+                                       ui = self._ui,
+                                       pageOffsetHeight = ui.page ? ui.page.offsetHeight : 0,
+                                       headerOffsetHeight = ui.header ? ui.header.offsetHeight : 0,
+                                       footerOffsetHeight = ui.footer ? ui.footer.offsetHeight : 0;
+
+                               element.style.height = pageOffsetHeight - headerOffsetHeight - footerOffsetHeight + "px";
+                       };
+                       /**
+                        * Bind events on PanelChanger component
+                        * @method _bindEvents
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._bindEvents = function (element) {
+                               bindEvents.call(this, element);
+                       };
+
+                       /**
+                        * Change panel
+                        * @method _changePanel
+                        * @param {string} address
+                        * @param {string} animationType
+                        * @param {string} direction
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._changePanel = function (address, animationType, direction) {
+                               var self = this,
+                                       request = new XMLHttpRequest(),
+                                       url = address ? address.split(/[#|?]+/)[0] : null;
+
+                               if (animationType) {
+                                       self._animationType = animationType;
+                               }
+                               self._direction = direction;
+                               request.responseType = "document";
+                               request.open("GET", url);
+                               request.addEventListener("error", self._loadError);
+                               request.addEventListener("load", function (event) {
+                                       var request = event.target;
+
+                                       if (request.readyState === 4) {
+                                               if (request.status === 200 || (request.status === 0 && request.responseXML)) {
+                                                       self._loadSuccess(address, request.responseXML, direction);
+                                               } else {
+                                                       self._loadError();
+                                               }
+                                       }
+                               });
+                               request.send();
+                       };
+
+                       /**
+                        * AJAX loadsuccess event handler
+                        * @method _loadSuccess
+                        * @param {string} href address string
+                        * @param {XML} xml element
+                        * @param {string} direction
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._loadSuccess = function (href, xml, direction) {
+                               var self = this,
+                                       element = self.element,
+                                       id = href.substring(href.lastIndexOf("#")),
+                                       eventType = self.eventType,
+                                       ui = self._ui,
+                                       panel = id.length > 1 ? element.querySelector(id) : null,
+                                       panelStyle,
+                                       i,
+                                       len,
+                                       transformCacheValue;
+
+                               if (!panel && id.length > 1) {
+                                       panel = xml.querySelector(id) || xml.querySelector("[data-role='panel'], .ui-panel");
+                               }
+
+
+                               if (!panel) {
+                                       ns.warn("Panel is not existed");
+                                       return;
+                               }
+
+                               panelStyle = panel.style;
+                               panelStyle.display = "block";
+                               transformCacheValue = panelStyle.transform;
+                               panelStyle.transform = "translate(-9999px, -9999px)";
+
+                               element.appendChild(panel);
+                               ui.toPanel = panel;
+                               events.trigger(panel, eventType.BEFORE_CREATE);
+                               engine.createWidgets(element);
+                               events.trigger(panel, eventType.CREATE);
+                               events.trigger(panel, eventType.BEFORE_SHOW);
+                               events.trigger(ui.activePanel, eventType.BEFORE_HIDE);
+                               panel.classList.add(classes.PRE_IN);
+                               panelStyle.display = "none";
+                               panelStyle.transform = transformCacheValue;
+
+                               self.history = JSON.parse(cookie.readFromCookie(DEFAULT.STORAGE_NAME) || "[]");
+                               if (direction === "forward") {
+                                       self.history.push(panel.getAttribute("id"));
+                                       cookie.writeToCookie(DEFAULT.STORAGE_NAME, JSON.stringify(self.history));
+                               } else {
+                                       len = self.history.length - 1;
+                                       for (i = self.history.indexOf(panel.id); i < len; i++) {
+                                               self.history.pop();
+                                       }
+                                       cookie.writeToCookie(DEFAULT.STORAGE_NAME, JSON.stringify(self.history));
+                               }
+
+                               self._show();
+                       };
+
+                       /**
+                        * Show next panel component
+                        * @method _show
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._show = function () {
+                               var self = this,
+                                       toPanel = self._ui.toPanel,
+                                       fromPanel = self._ui.activePanel,
+                                       type = self._animationType,
+                                       animationClasses = self._animationClasses;
+
+                               self._animating = true;
+                               fromPanel.classList.remove(classes.ACTIVE_PANEL);
+                               toPanel.style.display = "block";
+                               animationClasses.IN = type + classes.IN;
+                               animationClasses.OUT = type + classes.OUT;
+
+                               fromPanel.classList.add(animationClasses.OUT);
+                               toPanel.classList.add(animationClasses.IN);
+
+                               if (type === "none") {
+                                       self._onAnimationEnd();
+                               }
+                       };
+
+                       /**
+                        * Loaderror event handler
+                        * @method _loadError
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._loadError = function () {
+                               ns.warn("We can't load AJAX")
+                       };
+
+                       /**
+                        * Bind events on this component
+                        * @method bindEvents
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.PanelChanger
+                        * @private
+                        */
+                       function bindEvents(element) {
+                               var self = this;
+
+                               events.on(element, "vclick", self, false);
+                               events.prefixedFastOn(element, "animationEnd", self, false);
+                       }
+
+                       /**
+                        * Bind events on PanelChanger component
+                        * @method _bindEvents
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._bindEvents = function (element) {
+                               bindEvents.call(this, element);
+                       };
+
+                       /**
+                        * Click event handler
+                        * @method _onClick
+                        * @param {Event} event
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._onClick = function (event) {
+                               var self = this,
+                                       link = event.target.tagName.toLowerCase() === "a" ? event.target : selectors.getClosestByTag(event.target, "A"),
+                                       href;
+
+                               if (link && !self._animating && !link.getAttribute("data-rel")) {
+                                       href = link.getAttribute("href");
+                                       self._changePanel(href, self.options.animationType, "forward");
+                                       event.preventDefault();
+                               }
+                       };
+
+                       /**
+                        * animationEnd event handler
+                        * @method _onAnimationEnd
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._onAnimationEnd = function () {
+                               var self = this,
+                                       element = self.element,
+                                       toPanel = self._ui.toPanel,
+                                       activePanel = self._ui.activePanel,
+                                       animationClasses = self._animationClasses;
+
+                               if (!self._animating) {
+                                       return;
+                               }
+                               activePanel.style.display = "none";
+                               activePanel.classList.remove(animationClasses.OUT);
+                               toPanel.classList.add(classes.ACTIVE_PANEL);
+                               toPanel.classList.remove(classes.PRE_IN);
+                               toPanel.classList.remove(animationClasses.IN);
+
+                               events.trigger(activePanel, self.eventType.HIDE);
+                               events.trigger(toPanel, self.eventType.SHOW);
+                               events.trigger(element, self.eventType.CHANGE, {
+                                       fromPanel: activePanel,
+                                       toPanel: toPanel,
+                                       direction: self._direction
+                               });
+                               self._ui.activePanel = toPanel;
+                               self._animating = false;
+                       };
+
+                       /**
+                        * Bind pageBeforeShow event
+                        * @method _onPagebeforeshow
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._onPagebeforeshow = function () {
+                               var routePanel = ns.router.Router.getInstance().getRoute("panel");
+
+                               routePanel.setActive(this._ui._activePanel);
+                       };
+
+                       /**
+                        * Unbind events on this component
+                        * @method unBindEvents
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.PanelChanger
+                        * @private
+                        */
+                       function unBindEvents(element) {
+                               var self = this;
+
+                               events.off(element, "vclick", self, false);
+                               events.prefixedFastOff(element, "animationEnd", self, false);
+                       }
+
+                       /**
+                        * handleEvent
+                        * @method bindEvents
+                        * @param {Event} event
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "vclick":
+                                               self._onClick(event);
+                                               break;
+                                       case "webkitAnimationEnd":
+                                       case "mozAnimationEnd":
+                                       case "msAnimationEnd":
+                                       case "oAnimationEnd":
+                                       case "animationend":
+                                               self._onAnimationEnd(event);
+                                               break;
+                                       case "pagebeforeshow":
+                                               self._onPagebeforeshow(event);
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * Change panel method
+                        * @method changePanel
+                        * @param {string} address
+                        * @param {string} animationType
+                        * @param {string} direction
+                        * @member ns.widget.core.PanelChanger
+                        * @public
+                        */
+                       prototype.changePanel = function (address, animationType, direction) {
+                               this._changePanel(address, animationType, direction);
+                       };
+
+                       /**
+                        * Destroy panel component
+                        * @method _destroy
+                        * @member ns.widget.core.PanelChanger
+                        * @protected
+                        */
+                       prototype._destroy = function () {
+                               var self = this;
+
+                               self._ui = null;
+                               self.options = null;
+                               self._eventType = null;
+                               unBindEvents(self.element);
+                       };
+                       // definition
+                       ns.widget.core.PanelChanger = PanelChanger;
+
+                       engine.defineWidget(
+                               "PanelChanger",
+                               "[data-role='panel-changer'], .ui-panel-changer",
+                               ["changePanel"],
+                               PanelChanger,
+                               "core"
+                       );
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Page Indicator
+ * PageIndicator component presents as a dot-typed indicator.
+ *
+ * @since 2.4
+ * @class ns.widget.core.PageIndicator
+ * @component-selector [data-role="page-indicator"], .ui-page-indicator
+ * @component-type standalone-component
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+
+                               PageIndicator = function () {
+                                       var self = this;
+
+                                       self._activeIndex = null;
+                                       self.options = {};
+                               },
+                               classes = {
+                                       /**
+                                        * Standard page indicator widget
+                                        * @style ui-page-indicator
+                                        * @member ns.widget.core.PageIndicator
+                                        */
+                                       indicator: "ui-page-indicator",
+                                       /**
+                                        * Set dots of page indicator to be active
+                                        * @style ui-page-indicator-active
+                                        * @member ns.widget.core.PageIndicator
+                                        */
+                                       indicatorActive: "ui-page-indicator-active",
+                                       /**
+                                        * Create items for page indicator widget
+                                        * @style ui-page-indicator-item
+                                        * @member ns.widget.core.PageIndicator
+                                        */
+                                       indicatorItem: "ui-page-indicator-item",
+                                       /**
+                                        * Set style of page indicator dots to dashed
+                                        * @style ui-page-indicator-dashed
+                                        * @member ns.widget.core.PageIndicator
+                                        */
+                                       indicatorDashed: "ui-page-indicator-dashed",
+                                       /**
+                                        * Set page indicator to set dots in linear order
+                                        * @style ui-page-indicator-linear
+                                        * @member ns.widget.core.PageIndicator
+                                        */
+                                       linearIndicator: "ui-page-indicator-linear",
+                                       /**
+                                        * Set page indicator to set dots in circular order
+                                        * @style ui-page-indicator-circular
+                                        * @member ns.widget.core.PageIndicator
+                                        */
+                                       circularIndicator: "ui-page-indicator-circular"
+                               },
+                               maxDots = {
+                                       IN_CIRCLE: 60,
+                                       IN_LINEAR: 5
+                               },
+                               layoutType = {
+                                       LINEAR: "linear",
+                                       CIRCULAR: "circular"
+                               },
+                               DISTANCE_FROM_EDGE = 8,
+
+                               prototype = new BaseWidget();
+
+                       PageIndicator.classes = classes;
+
+                       prototype._configure = function () {
+                               /**
+                                * Options for widget.
+                                * @property {Object} options
+                                * @property {number} [options.maxPage=null] Maximum number of dots(pages) in indicator.
+                                * @property {number} [options.numberOfPages=null] Number of pages to be linked to PageIndicator.
+                                * @property {string} [options.layout="linear"] Layout type of page indicator.
+                                * @property {number} [options.intervalAngle=6] angle between each dot in page indicator.
+                                * @property {string} [options.appearance="dashed"] style of the page indicator "dotted" "dashed"
+                                * @member ns.widget.core.PageIndicator
+                                */
+                               this.options = {
+                                       maxPage: null,
+                                       numberOfPages: null,
+                                       layout: "linear",
+                                       intervalAngle: 6,
+                                       appearance: "dashed"
+                               };
+                       };
+                       /**
+                        * Build PageIndicator
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.core.PageIndicator
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       options = self.options;
+
+                               self._createIndicator(element);
+                               if (options.layout === layoutType.CIRCULAR) {
+                                       self._circularPositioning(element);
+                               }
+                               if (options.appearance === "dashed") {
+                                       element.classList.add(classes.indicatorDashed);
+                               }
+                               return element;
+                       };
+
+                       /**
+                        * Create HTML elements for PageIndicator
+                        * @method _createIndicator
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.PageIndicator
+                        */
+                       prototype._createIndicator = function (element) {
+                               var self = this,
+                                       i,
+                                       len,
+                                       maxPage,
+                                       span,
+                                       numberOfPages = self.options.numberOfPages;
+
+                               if (numberOfPages === null) {
+                                       ns.error("build error: numberOfPages is null");
+                                       return;
+                               }
+
+                               self.options.layout = self.options.layout.toLowerCase();
+
+                               if (self.options.layout === layoutType.CIRCULAR) {
+                                       element.classList.remove(classes.linearIndicator);
+                                       element.classList.add(classes.circularIndicator);
+                               } else {
+                                       element.classList.remove(classes.circularIndicator);
+                                       element.classList.add(classes.linearIndicator);
+                               }
+
+                               maxPage = self._getMaxPage();
+
+                               len = numberOfPages < maxPage ? numberOfPages : maxPage;
+
+                               for (i = 0; i < len; i++) {
+                                       span = document.createElement("span");
+                                       span.classList.add(classes.indicatorItem);
+
+                                       element.appendChild(span);
+                               }
+                       };
+
+                       /**
+                        * Make circular positioned indicator
+                        * @method _circularPositioning
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.PageIndicator
+                        */
+                       prototype._circularPositioning = function (element) {
+                               var self = this,
+                                       items = element.children,
+                                       numberOfDots = items.length,
+                                       intervalAngle = parseFloat(self.options.intervalAngle),
+                                       translatePixel,
+                                       style,
+                                       i;
+
+                               translatePixel = element.offsetWidth / 2 - DISTANCE_FROM_EDGE;
+
+                               for (i = 0; i < numberOfDots; i++) {
+                                       style = "rotate(" + (i * intervalAngle - 90 - (numberOfDots - 1) * intervalAngle * 0.5) + "deg) translate(" +
+                                               translatePixel + "px) ";
+
+                                       items[i].style.transform = style;
+                               }
+
+                       };
+
+                       /**
+                        * Return maximum number of dots(pages) in indicator
+                        * @method _getMaxPage
+                        * @protected
+                        * @member ns.widget.core.PageIndicator
+                        */
+                       prototype._getMaxPage = function () {
+                               var self = this,
+                                       options = self.options,
+                                       maxPage;
+
+                               if (options.layout === layoutType.CIRCULAR) {
+                                       maxPage = options.maxPage || maxDots.IN_CIRCLE;
+                               } else {
+                                       maxPage = options.maxPage || maxDots.IN_LINEAR;
+                               }
+                               return maxPage;
+                       };
+
+                       /**
+                        * Remove contents of HTML elements for PageIndicator
+                        * @method _removeIndicator
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.PageIndicator
+                        */
+                       prototype._removeIndicator = function (element) {
+                               element.textContent = "";
+                       };
+
+                       /**
+                        * This method sets a dot to active state.
+                        * @method setActive
+                        * @param {number} position index to be active state.
+                        * @member ns.widget.core.PageIndicator
+                        */
+                       prototype.setActive = function (position) {
+                               var self = this,
+                                       dotIndex = position,
+                                       elPageIndicatorItems = self.element.children,
+                                       maxPage,
+                                       numberOfPages = parseInt(self.options.numberOfPages, 10),
+                                       middle,
+                                       numberOfCentralDotPages = 0,
+                                       indicatorActive = classes.indicatorActive,
+                                       previousActive;
+
+                               if (position === null || position === undefined) {
+                                       return;
+                               }
+
+                               self._activeIndex = position;
+                               maxPage = self._getMaxPage();
+                               middle = window.parseInt(maxPage / 2, 10);
+
+                               if (numberOfPages > maxPage) {
+                                       numberOfCentralDotPages = numberOfPages - maxPage;
+                               } else if (isNaN(numberOfPages)) {
+                                       ns.error("setActive error: numberOfPages is not a number");
+                                       return;
+                               } else if (numberOfPages === 0) {
+                                       return;
+                               }
+
+                               previousActive = self.element.querySelector("." + indicatorActive);
+                               if (previousActive) {
+                                       previousActive.classList.remove(indicatorActive);
+                               }
+
+                               if ((middle < position) && (position <= (middle + numberOfCentralDotPages))) {
+                                       dotIndex = middle;
+                               } else if (position > (middle + numberOfCentralDotPages)) {
+                                       dotIndex = position - numberOfCentralDotPages;
+                               }
+
+                               elPageIndicatorItems[dotIndex].classList.add(indicatorActive);
+                       };
+
+                       /**
+                        * Refresh widget structure
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.core.PageIndicator
+                        */
+                       prototype._refresh = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               self._removeIndicator(element);
+                               self._createIndicator(element);
+                               if (self.options.layout === layoutType.CIRCULAR) {
+                                       self._circularPositioning(element);
+                               }
+                       };
+
+                       /**
+                        * Destroy widget
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.core.PageIndicator
+                        */
+                       prototype._destroy = function () {
+                               this._removeIndicator(this.element);
+                       };
+
+                       PageIndicator.prototype = prototype;
+
+                       ns.widget.core.PageIndicator = PageIndicator;
+
+                       engine.defineWidget(
+                               "PageIndicator",
+                               "[data-role='page-indicator'], .ui-page-indicator",
+                               ["setActive"],
+                               PageIndicator,
+                               "core"
+                       );
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Slider
+ * Slider component changes the range-type browser input to sliders.
+ *
+ * ##Default selectors
+ * In default all **INPUT** tags with type equals _range_  and _data-role=slider_ are changed to TAU sliders.
+ *
+ * ###HTML Examples
+ *
+ *         @example
+ *              <input type="range" name="slider-1" id="slider" value="60" min="0" max="100">
+ *
+ * ###Manual constructor
+ * For manual creation of slider widget you can use constructor of widget
+ *
+ *         @example
+ *              <input id="slider">
+ *              <script>
+ *                  var sliderElement = document.getElementById("slider"),
+ *                      slider;
+ *
+ *                  slider = tau.widget.Slider(sliderElement);
+ *
+ *                  // You can make slider component for TizenSlider component name,
+ *                  // for example, tau.widget.TizenSlider(sliderElement).
+ *                  // But, TizenSlider component name will be deprecated since tizen 2.4
+ *                  // because we don't recommend this method.
+ *              </script>
+ *
+ * @since 2.0
+ * @class ns.widget.core.Slider
+ * @component-selector .ui-slider [data-type]="slider"
+ * @extends ns.widget.BaseWidget
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               /**
+                        * @property {Object} Widget Alias for {@link ns.widget.BaseWidget}
+                        * @member ns.widget.core.Drawer
+                        * @private
+                        * @static
+                        */
+                       var BaseWidget = ns.widget.BaseWidget,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               engine = ns.engine,
+                               objectMerge = ns.util.object.merge,
+                               events = ns.event,
+                               /**
+                                * Widget options
+                                * @property {string} [options.type="continues"] Slider type. 'continues', 'level-bar'
+                                * @property {boolean} [options.disabled=false] Slider disabled mode. true or false
+                                * @property {number} [min=0] minimum value of Slider
+                                * @property {number} [max=10] maximum value of Slider
+                                * @property {number} [step=1] step specifies the granularity that the value must adhere to
+                                **/
+                               defaults = {
+                                       type: "continues",
+                                       orientation: "horizontal",
+                                       expand: false,
+                                       warning: false,
+                                       warningLevel: 0,
+                                       disabled: false,
+                                       toggle: "",
+                                       min: 0,
+                                       max: 10,
+                                       step: 1,
+                                       labels: false
+                               },
+                               unsupportedOptions = ["orientation", "expand", "warning", "warningLevel", "toggle"],
+                               Slider = function () {
+                                       var self = this;
+
+                                       self.options = objectMerge({}, defaults);
+                                       BaseKeyboardSupport.call(self);
+
+                                       self._ui = {
+                                               scale: null
+                                       };
+                               },
+                               classes = {
+                                       SLIDER: "ui-slider",
+                                       SLIDER_VALUE: "ui-slider-value",
+                                       SLIDER_HANDLER: "ui-slider-handler",
+                                       SLIDER_DISABLED: "ui-disabled",
+                                       SLIDER_HANDLER_VALUE: "ui-slider-handler-value",
+                                       SLIDER_FOCUS: "ui-slider-focus",
+                                       SLIDER_BAR: "ui-slider-bar",
+                                       SLIDER_ACTIVE: "ui-slider-active",
+                                       TRACK: "ui-slider-handler-track",
+                                       SPACE_BEFORE: "ui-slider-before-space",
+                                       SPACE_AFTER: "ui-slider-after-space",
+                                       SLIDER_HAS_LABELS: "ui-slider-has-labels",
+                                       LABEL: "ui-slider-label",
+                                       LABEL_MIN: "ui-slider-label-min",
+                                       LABEL_MAX: "ui-slider-label-max"
+                               },
+                               prototype = new BaseWidget();
+
+                       Slider.prototype = prototype;
+                       Slider.classes = classes;
+
+                       /**
+                        * Bind events
+                        * @method bindEvents
+                        * @param {Object} self
+                        * @member ns.widget.core.Slider
+                        * @private
+                        * @static
+                        */
+                       function bindEvents(self) {
+                               events.on(self.element, "input change vmouseup vmousedown", self, false);
+
+                               if (self.isKeyboardSupport) {
+                                       events.on(self.element, "focus, blur, keyup", self, false);
+                               }
+                       }
+
+                       /**
+                        * unBind events
+                        * @method unbindEvents
+                        * @param {Object} self
+                        * @member ns.widget.core.Slider
+                        * @private
+                        * @static
+                        */
+                       function unbindEvents(self) {
+                               events.off(self.element, "input change vmouseup vmousedown", self, false);
+
+                               if (self.isKeyboardSupport) {
+                                       events.off(self.element, "focus, blur, keyup", self, false);
+                               }
+                       }
+
+                       /**
+                        * Method changes look of scale for Slider widget when type is level bar
+                        * @method _updateLevelBar
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._updateLevelBar = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       scale = ui.scale,
+                                       options = self.options,
+                                       numberOfDots = Math.round((options.max - options.min) / options.step) + 1,
+                                       currentDots = scale.children.length,
+                                       delta = numberOfDots - currentDots,
+                                       dot,
+                                       i;
+
+                               // modify DOM
+                               if (delta > 0) {
+                                       // add
+                                       for (i = 0; i < delta; i++) {
+                                               dot = document.createElement("div");
+                                               dot.classList.add("ui-slider-scale-dot");
+                                               scale.appendChild(dot);
+                                       }
+                               } else if (delta < 0) {
+                                       // remove redundant dots
+                                       delta = -delta;
+                                       for (i = 0; i < delta; i++) {
+                                               scale.removeChild(scale.lastElementChild);
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Method is called when "type" option has change
+                        * @method _setType
+                        * @member ns.widget.core.Slider
+                        * @param {HTMLElement} element element parameter is required by BaseWidget
+                        * @param {string} value
+                        * @protected
+                        */
+                       prototype._setType = function (element, value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       scale = ui.scale,
+                                       containerElement = ui.containerElement;
+
+                               if (value === "level-bar") {
+                                       // create element
+                                       if (!scale) {
+                                               scale = document.createElement("div");
+                                               scale.classList.add("ui-slider-scale");
+                                               containerElement.appendChild(scale);
+                                               ui.scale = scale;
+                                       }
+                                       // update dots
+                                       self._updateLevelBar();
+                               } else {
+                                       if (scale) {
+                                               containerElement.remove(scale);
+                                               ui.scale = null;
+                                       }
+                               }
+
+                               containerElement.classList.toggle("ui-slider-level-bar", value === "level-bar");
+
+                               self.options.type = value;
+                       }
+
+                       /**
+                        * Method is called when "labels" option has change
+                        * @method _setLabels
+                        * @member ns.widget.core.Slider
+                        * @param {HTMLElement} element element parameter is required by BaseWidget
+                        * @param {string} value
+                        * @protected
+                        */
+                       prototype._setLabels = function (element, value) {
+                               var self = this;
+
+                               if (value) {
+                                       if (!self._ui.labelMin.innerText) {
+                                               self._ui.labelMin.innerText = self.options.min;
+                                       }
+                                       if (!self._ui.labelMax.innerText) {
+                                               self._ui.labelMax.innerText = self.options.max;
+                                       }
+                               }
+                               self._ui.containerElement.classList.toggle(classes.SLIDER_HAS_LABELS, value);
+                               self.options.labels = value;
+                       }
+
+                       /**
+                        * Build structure of Slider component
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} Returns built element
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       containerElement = document.createElement("div"),
+                                       barElement = document.createElement("div"),
+                                       valueElement = document.createElement("div"),
+                                       handlerElement = document.createElement("div"),
+                                       handlerTrack = document.createElement("div"),
+                                       beforeSpace = document.createElement("div"),
+                                       afterSpace = document.createElement("div"),
+                                       labelMin = document.createElement("div"),
+                                       labelMax = document.createElement("div");
+
+                               containerElement.classList.add(classes.SLIDER);
+
+                               barElement.classList.add(classes.SLIDER_BAR);
+                               valueElement.classList.add(classes.SLIDER_VALUE);
+                               barElement.appendChild(valueElement);
+
+                               handlerElement.classList.add(classes.SLIDER_HANDLER);
+                               handlerTrack.classList.add(classes.TRACK);
+                               beforeSpace.classList.add(classes.SPACE_BEFORE);
+                               afterSpace.classList.add(classes.SPACE_AFTER);
+
+                               labelMin.classList.add(classes.LABEL);
+                               labelMax.classList.add(classes.LABEL);
+                               labelMin.classList.add(classes.LABEL_MIN);
+                               labelMax.classList.add(classes.LABEL_MAX);
+
+                               handlerTrack.appendChild(beforeSpace);
+                               handlerTrack.appendChild(handlerElement);
+                               handlerTrack.appendChild(afterSpace);
+
+                               containerElement.appendChild(handlerTrack);
+                               containerElement.appendChild(barElement);
+                               containerElement.appendChild(labelMin);
+                               containerElement.appendChild(labelMax);
+
+                               element.parentNode.appendChild(containerElement);
+                               ui.barElement = barElement;
+                               ui.valueElement = valueElement;
+                               ui.handlerElement = handlerElement;
+                               ui.containerElement = containerElement;
+                               ui.beforeSpace = beforeSpace;
+                               ui.afterSpace = afterSpace;
+                               ui.labelMin = labelMin;
+                               ui.labelMax = labelMax;
+
+                               element.parentNode.replaceChild(containerElement, element);
+                               containerElement.appendChild(element);
+
+                               if (self.isKeyboardSupport) {
+                                       self.preventFocusOnElement(element);
+                                       containerElement.setAttribute("data-focus-lock", "true");
+                                       containerElement.setAttribute("tabindex", "0");
+                               }
+
+                               return element;
+                       };
+
+                       /**
+                        * Update Slider properties from widget options
+                        * @method _updateProperties
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._updateProperties = function () {
+                               var self = this,
+                                       options = self.options,
+                                       attrValue = parseFloat(self.element.getAttribute("value"));
+
+                               self._min = options.min;
+                               self._max = options.max;
+                               self._minValue = self._min;
+                               self._maxValue = self._max;
+                               self._interval = self._max - self._min;
+
+                               self._value = attrValue ? attrValue : parseFloat(self.element.value);
+                               self._previousValue = self._value;
+                       };
+
+                       /**
+                        * init Slider component
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} Returns built element
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self._warnAboutUnsupportedOptions();
+                               self._updateProperties();
+
+                               self._setDisabled(element);
+                               self._locked = false;
+
+                               self._initLayout();
+                               return element;
+                       };
+
+                       prototype._warnAboutUnsupportedOptions = function () {
+                               var options = this.options;
+
+                               unsupportedOptions.forEach(function (option) {
+                                       if (options[option] !== defaults[option]) {
+                                               ns.warn("The " + option + " option has no effect on Slider widget");
+                                       }
+                               });
+                       }
+
+                       /**
+                        * init layout of Slider component
+                        * @method _initLayout
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._initLayout = function () {
+                               var self = this,
+                                       ui = self._ui;
+
+                               self._setType(self.element, self.options.type);
+                               self._setLabels(self.element, self.options.labels);
+
+                               self._containerElementWidth = ui.containerElement.offsetWidth;
+
+                               self._setValue(self._value);
+                       };
+
+                       /**
+                        * Set value of Slider normal mode
+                        * @method _setNormalValue
+                        * @param {number} value
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._setNormalValue = function (value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       percentValue;
+
+                               // position of handle element
+                               percentValue = (value - self._min) / (self._max - self._min) * 100;
+                               ui.beforeSpace.style["width"] = percentValue + "%";
+                               ui.afterSpace.style["width"] = (100 - percentValue) + "%";
+                               ui.valueElement.style["width"] = percentValue + "%";
+                       };
+
+                       /**
+                        * Set value of Slider
+                        * @method _setValue
+                        * @param {number} value
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._setValue = function (value) {
+                               var self = this,
+                                       element = self.element,
+                                       floatValue;
+
+                               self._previousValue = self._value;
+
+                               if (value < self._min) {
+                                       value = self._min;
+                               } else if (value > self._max) {
+                                       value = self._max;
+                               }
+
+                               floatValue = parseFloat(value);
+
+                               self._setNormalValue(value);
+
+                               if (self._previousValue !== floatValue) {
+                                       element.setAttribute("value", floatValue);
+                                       element.value = floatValue;
+                                       self._value = floatValue;
+
+                                       //events.trigger(element, "input");
+                               }
+                       };
+
+                       prototype._getValue = function () {
+                               return this._value;
+                       };
+
+                       prototype._getContainer = function () {
+                               return this._ui.containerElement;
+                       }
+
+                       prototype._setDisabled = function (element) {
+                               var self = this,
+                                       options = self.options;
+
+                               if (options.disabled === true || element.disabled) {
+                                       self._disable(element);
+                               } else {
+                                       self._enable(element);
+                               }
+                       };
+
+                       prototype._enable = function (element) {
+                               if (element) {
+                                       this.options.disabled = false;
+                                       if (this._ui.containerElement) {
+                                               this._ui.containerElement.classList.remove(classes.SLIDER_DISABLED);
+                                       }
+                               }
+                       };
+
+                       prototype._disable = function (element) {
+                               if (element) {
+                                       this.options.disabled = true;
+                                       if (this._ui.containerElement) {
+                                               this._ui.containerElement.classList.add(classes.SLIDER_DISABLED);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Bind events to Slider
+                        * @method _bindEvents
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._bindEvents = function () {
+                               bindEvents(this);
+                       };
+
+                       /**
+                        * Bind event handlers
+                        * @method handleEvent
+                        * @param {Event} event
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this,
+                                       eventType = event.type;
+
+                               if (!this.options.disabled) {
+                                       switch (eventType) {
+                                               case "input" :
+                                               case "change" :
+                                                       self._setValue(self.element.value);
+                                                       break;
+                                               case "vmousedown":
+                                                       self._onTouchStart(event);
+                                                       break;
+                                               case "vmouseup":
+                                                       self._onTouchEnd(event);
+                                                       break;
+                                               // case "focus":
+                                               //      self._onFocus(event);
+                                               //      break;
+                                               // case "blur":
+                                               //      self._onBlur(event);
+                                               //      break;
+                                               case "keyup":
+                                                       self._onKeyUp(event);
+                                                       break;
+                                       }
+                               }
+                       };
+
+                       prototype._onTouchStart = function () {
+                               this._ui.containerElement.classList.add(classes.SLIDER_ACTIVE);
+                       };
+
+                       prototype._onTouchEnd = function () {
+                               this._ui.containerElement.classList.remove(classes.SLIDER_ACTIVE);
+                       };
+
+                       // prototype._onFocus = function () {
+                       //      var container = this._ui.containerElement.parentElement;
+
+                       //      container && container.classList.add("ui-listview-item-focus");
+                       // };
+
+                       // prototype._onBlur = function () {
+                       //      var container = this._ui.containerElement.parentElement;
+
+                       //      container && container.classList.remove("ui-listview-item-focus");
+                       // };
+
+                       prototype._decreaseValue = function () {
+                               var self = this;
+
+                               self._setValue(self._value - (parseFloat(self.element.step) || 1));
+                       };
+
+                       prototype._increaseValue = function () {
+                               var self = this;
+
+                               self._setValue(self._value + (parseFloat(self.element.step) || 1));
+                       };
+
+                       // prototype._lockKeyboard = function () {
+                       //      var self = this,
+                       //              listview = utilSelector.getClosestBySelector(self.element, ".ui-listview"),
+                       //              listviewWidget = engine.getBinding(listview, "Listview");
+
+                       //      self._locked = true;
+                       //      listviewWidget.saveKeyboardSupport();
+                       //      listviewWidget.disableKeyboardSupport();
+                       //      self.enableKeyboardSupport();
+                       //      self._ui.containerElement.classList.add(classes.SLIDER_FOCUS);
+                       // };
+
+                       // prototype._unlockKeyboard = function () {
+                       //      var self = this,
+                       //              listview = utilSelector.getClosestBySelector(self.element, ".ui-listview"),
+                       //              listviewWidget = engine.getBinding(listview, "Listview");
+
+                       //      self._locked = false;
+                       //      listviewWidget.restoreKeyboardSupport();
+                       //      listviewWidget.enableKeyboardSupport();
+                       //      self.disableKeyboardSupport();
+                       //      self._ui.containerElement.classList.remove(classes.SLIDER_FOCUS);
+                       // };
+
+                       prototype._onKeyUp = function (event) {
+                               var self = this,
+                                       KEY_CODES = BaseKeyboardSupport.KEY_CODES;
+
+                               if (self._locked) {
+                                       switch (event.keyCode) {
+                                               // case KEY_CODES.escape :
+                                               // case KEY_CODES.enter :
+                                               //      self._unlockKeyboard();
+                                               //      break;
+                                               case KEY_CODES.left :
+                                                       self._decreaseValue();
+                                                       break;
+                                               case KEY_CODES.right :
+                                                       self._increaseValue();
+                                                       break;
+                                       }
+                               } else {
+                                       // switch (event.keyCode) {
+                                       //      case KEY_CODES.enter :
+                                       //              self._lockKeyboard();
+                                       //              break;
+                                       // }
+                               }
+                       };
+
+                       /**
+                        * Refresh to Slider component
+                        * @method refresh
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._refresh = function () {
+                               var self = this;
+
+                               self._updateProperties()
+                               self._setDisabled(self.element);
+                               self._initLayout();
+                       };
+
+                       /**
+                        * Destroy Slider component
+                        * @method _destroy
+                        * @member ns.widget.core.Slider
+                        * @protected
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       containerElement = self._ui.containerElement;
+
+                               unbindEvents(self);
+                               if (containerElement.parentNode) {
+                                       containerElement.parentNode.removeChild(containerElement);
+                               }
+                               self._ui = null;
+                               self._options = null;
+                       };
+
+                       ns.widget.core.Slider = Slider;
+                       engine.defineWidget(
+                               "Slider",
+                               "input[data-role='slider'], input[type='range'], input[data-type='range']",
+                               [
+                                       "value"
+                               ],
+                               Slider,
+                               "core"
+                       );
+
+                       BaseKeyboardSupport.registerActiveSelector("input[data-role='slider'], input[type='range'], input[data-type='range'], .ui-slider-handler");
+
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * #Progress namespace
+ * Namespace with progress.
+ * @author Heeju Joo <heeju.joo@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               ns.widget.core.progress = ns.widget.core.progress || {};
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * #type namespace
+ * Namespace with types of Progress
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @class ns.widget.core.progress.type
+ * @internal
+ */
+(function (window, ns) {
+       "use strict";
+                               /** @namespace ns.widget.core */
+                       ns.widget.core.progress.type = ns.widget.core.progress.type || {};
+                       }(window, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Progress type Interface
+ * Interface for type of progress
+ * @internal
+ * @class ns.widget.core.progress.type.interface
+ */
+(function (document, ns) {
+       "use strict";
+       
+                       ns.widget.core.progress.type.interface = {
+                               /**
+                                * Init DOM for progress
+                                * @method build
+                                * @static
+                                * @member ns.widget.core.progress.type.interface
+                                */
+                               build: function (/*Progress*/) {
+                               },
+                               /**
+                                * Init Style for progress
+                                * @method init
+                                * @static
+                                * @member ns.widget.core.progress.type.interface
+                                */
+                               init: function (/*Progress*/) {
+                               },
+                               /**
+                                * Init Style for progress
+                                * @method refresh
+                                * @static
+                                * @member ns.widget.core.progress.type.interface
+                                */
+                               refresh: function (/*Progress*/) {
+
+                               },
+                               /**
+                                * Init Style for progress
+                                * @method changeValue
+                                * @static
+                                * @member ns.widget.core.progress.type.interface
+                                */
+                               changeValue: function (/*Progress*/) {
+
+                               },
+                               /**
+                                * Init Style for progress
+                                * @method destroy
+                                * @static
+                                * @member ns.widget.core.progress.type.interface
+                                */
+                               destroy: function (/*Progress*/) {
+
+                               }
+                       };
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Indeterminate Bar Type
+ * indeterminateBar type support for Progress widget.
+ * @internal
+ * @class ns.widget.core.progress.type.indeterminate
+ * @extends ns.widget.core.progress.type.interface
+ */
+(function (document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               type = ns.widget.core.progress.type,
+                               typeInterface = type.interface,
+                               classes = {
+                                       uiIndeterminatebar: "ui-indeterminate-bar",
+                                       uiIndeterminatebarIndeterminate: "ui-indeterminate-bar-indeterminate"
+                               };
+
+                       function paintProgressStyle(progress) {
+                               var ui = progress._ui,
+                                       options = progress.options,
+                                       percentValue = (options.value * 100) / (options.max - options.min);
+
+                               ui.indeterminateBarElement.style.width = percentValue + "%";
+                       }
+
+                       type.indeterminatebar = utilsObject.merge({}, typeInterface, {
+                               build: function (progress, element) {
+                                       var ui = {},
+                                               indeterminateElement = element,
+                                               indeterminateBarElement;
+
+                                       indeterminateBarElement = document.createElement("div");
+
+                                       indeterminateElement.classList.add(classes.uiIndeterminatebar);
+                                       indeterminateBarElement.classList.add(classes.uiIndeterminatebarIndeterminate);
+
+                                       indeterminateElement.appendChild(indeterminateBarElement);
+
+                                       ui.indeterminateBarElement = indeterminateBarElement;
+
+                                       progress._ui = ui;
+
+                                       return indeterminateElement;
+                               },
+
+                               init: function (progress, element) {
+                                       var ui = progress._ui,
+                                               indeterminateElement = element;
+
+                                       ui.indeterminateBarElement = ui.indeterminateBarElement || indeterminateElement.querySelector("." + classes.uiIndeterminatebarActivity);
+
+                                       paintProgressStyle(progress);
+                               },
+
+                               refresh: function (progress) {
+                                       paintProgressStyle(progress);
+                               },
+
+                               changeValue: function (progress) {
+                                       paintProgressStyle(progress);
+                               }
+                       });
+
+                       }(window.document, ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #indeterminateCircle Type
+ * indeterminateCircle type support for Progress widget.
+ * @internal
+ * @class ns.widget.core.progress.type.indeterminatecircle
+ * @extends ns.widget.core.progress.type.interface
+ * @author Kornelia Kobiela    <k.kobiela@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               type = ns.widget.core.progress.type,
+                               typeInterface = type.interface,
+                               classes = {
+                                       uiIndeterminateCircle: "ui-indeterminate-circle",
+                                       uiIndeterminateCircleSmallTitle: "ui-indeterminate-circle-small-title",
+                                       uiIndeterminateCircleSmall: "ui-indeterminate-circle-small",
+                                       uiIndeterminateCircleMedium: "ui-indeterminate-circle-medium",
+                                       uiIndeterminateCircleLarge: "ui-indeterminate-circle-large"
+                               };
+
+                       function resetIndeterminateCircleClasses(element, optionSize) {
+                               if (!element.classList.contains(classes.uiIndeterminateCircle)) {
+                                       element.classList.add(classes.uiIndeterminateCircle);
+                               }
+
+                               element.classList.remove(classes.uiIndeterminateCircleSmallTitle);
+                               element.classList.remove(classes.uiIndeterminateCircleSmall);
+                               element.classList.remove(classes.uiIndeterminateCircleMedium);
+                               element.classList.remove(classes.uiIndeterminateCircleLarge);
+
+                               switch (optionSize) {
+                                       case "small-title":
+                                               element.classList.add(classes.uiIndeterminateCircleSmallTitle);
+                                               break;
+                                       case "small":
+                                               element.classList.add(classes.uiIndeterminateCircleSmall);
+                                               break;
+                                       case "medium":
+                                               element.classList.add(classes.uiIndeterminateCircleMedium);
+                                               break;
+                                       case "large":
+                                               element.classList.add(classes.uiIndeterminateCircleLarge);
+                                               break;
+                                       default:
+                                               element.classList.add(classes.uiIndeterminateCircleMedium);
+                               }
+                       }
+
+                       type.indeterminatecircle = utilsObject.merge({}, typeInterface, {
+                               build: function () {
+                               },
+                               init: function (progress, element) {
+                                       var options = progress.options,
+                                               indeterminateCircleSize = options.size;
+
+
+                                       resetIndeterminateCircleClasses(element, indeterminateCircleSize);
+                               },
+                               refresh: function (progress) {
+                                       var element = progress.element,
+                                               indeterminateCircleSize = progress.options.size;
+
+                                       resetIndeterminateCircleClasses(element, indeterminateCircleSize);
+
+                               }
+                       });
+
+                       }(window.document, ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #progressBar Type
+ * progressBar type support for Progress widget.
+ * @internal
+ * @class ns.widget.core.progress.type.progressbar
+ * @extends ns.widget.core.progress.type.interface
+ */
+(function (document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               type = ns.widget.core.progress.type,
+                               typeInterface = type.interface,
+
+                               classes = {
+                                       uiProgressbar: "ui-progress-bar",
+                                       uiProgressbarValue: "ui-progress-bar-value",
+                                       uiProgressbarValueBg: "ui-progress-bar-value-bg",
+                                       uiProgressbarLabelsTop: "ui-progress-bar-labels-top",
+                                       uiProgressbarLabelsBottom: "ui-progress-bar-labels-bottom",
+                                       labelCurrentValue: "ui-progress-current-value",
+                                       labelMinValue: "ui-progress-min-value",
+                                       labelMaxValue: "ui-progress-max-value"
+                               },
+
+                               createAnimationFrame = function (duration, call1) {
+                                       return [
+                                               {
+                                                       start: 0,
+                                                       end: 800,
+                                                       callback: function (t, end) {
+                                                               call1.call(this, t, end);
+                                                       }
+                                               }
+                                       ];
+                               };
+
+                       function setAriaValues(element, options) {
+                               //set Aria value
+                               element.setAttribute("aria-valuenow", options.value);
+                               element.setAttribute("aria-valuemin", options.min);
+                               element.setAttribute("aria-valuemax", options.max);
+                       }
+
+                       function paintProgressStyle(progress) {
+                               var ui = progress._ui,
+                                       options = progress.options,
+                                       percentValue = (options.value * 100) / (options.max - options.min);
+
+                               ui.progressBarValueElement.style.width = percentValue + "%";
+                       }
+
+                       function updateLabels(progress) {
+                               var ui = progress._ui,
+                                       options = progress.options;
+
+                               // update labels
+                               if (ui.labelCurrentValue) {
+                                       ui.labelCurrentValue.textContent = options.value;
+                               }
+                               if (ui.labelMinValue) {
+                                       ui.labelMinValue.textContent = options.min;
+                               }
+                               if (ui.labelMaxValue) {
+                                       ui.labelMaxValue.textContent = options.max;
+                               }
+                       }
+
+                       type.bar = utilsObject.merge({}, typeInterface, {
+                               build: function (progress, element) {
+                                       var ui = {},
+                                               progressBarValueElement,
+                                               progressBarValueBg,
+                                               labelsTop,
+                                               labelsBottom;
+
+                                       element.classList.add(classes.uiProgressbar);
+
+                                       progressBarValueElement = document.createElement("div");
+                                       progressBarValueElement.classList.add(classes.uiProgressbarValue);
+                                       progressBarValueBg = document.createElement("div");
+                                       progressBarValueBg.classList.add(classes.uiProgressbarValueBg);
+                                       labelsTop = document.createElement("div");
+                                       labelsTop.classList.add(classes.uiProgressbarLabelsTop);
+                                       labelsBottom = document.createElement("div");
+                                       labelsBottom.classList.add(classes.uiProgressbarLabelsBottom);
+
+                                       progressBarValueBg.appendChild(progressBarValueElement);
+                                       element.appendChild(labelsTop);
+                                       element.appendChild(progressBarValueBg);
+                                       element.appendChild(labelsBottom);
+
+                                       ui.progressBarValueElement = progressBarValueElement;
+                                       ui.progressBarValueBg = progressBarValueBg;
+                                       ui.labelsTop = labelsTop;
+                                       ui.labelsBottom = labelsBottom;
+
+                                       progress._ui = ui;
+                                       return element;
+                               },
+
+                               init: function (progress, element) {
+                                       var ui = progress._ui,
+                                               options = progress.options,
+                                               labelsTop = [],
+                                               labelsBottom = [];
+
+                                       // find labels and append to widget
+                                       labelsTop = [].slice.call(
+                                               element.querySelectorAll(".ui-progress-bar-label-right-top"));
+                                       labelsBottom = [].slice.call(
+                                               element.querySelectorAll(".ui-progress-bar-label-left-bottom, .ui-progress-bar-label-right-bottom")
+                                       );
+                                       // try to find labels from outside widget (old api)
+                                       labelsTop = labelsTop.concat([].slice.call(
+                                               element.parentElement.querySelectorAll(".ui-progress ~ .ui-progress-bar-label-right-top")));
+                                       labelsBottom = labelsBottom.concat([].slice.call(
+                                               element.parentElement.querySelectorAll(".ui-progress ~ .ui-progress-bar-label-left-bottom, .ui-progress ~ .ui-progress-bar-label-right-bottom")));
+
+                                       labelsTop.forEach(function (label) {
+                                               ui.labelsTop.appendChild(label);
+                                       });
+                                       labelsBottom.forEach(function (label) {
+                                               ui.labelsBottom.appendChild(label);
+                                       });
+
+                                       ui.progressBarValueElement = ui.progressBarValueElement || element.querySelector("." + classes.uiProgressbarValue);
+
+                                       // labels
+                                       ui.labelCurrentValue = element.querySelector("." + classes.labelCurrentValue);
+                                       ui.labelMinValue = element.querySelector("." + classes.labelMinValue);
+                                       ui.labelMaxValue = element.querySelector("." + classes.labelMaxValue);
+
+                                       setAriaValues(element, options);
+                                       paintProgressStyle(progress);
+                                       updateLabels(progress);
+                               },
+
+                               refresh: function (progress) {
+                                       setAriaValues(progress.element, progress.options);
+                                       paintProgressStyle(progress);
+                                       updateLabels(progress);
+                               },
+
+                               changeValue: function (progress, oldValue, newValue) {
+                                       var duration = 1850,
+                                               valueElement = progress._ui.progressBarValueElement,
+                                               oldPercentValue = (oldValue * 100) / (progress.options.max - progress.options.min),
+                                               newPercentValue = (newValue * 100) / (progress.options.max - progress.options.min),
+                                               animationFrames;
+
+                                       if (!progress._isAnimating) {
+                                               animationFrames = createAnimationFrame(duration, function (t, end) {
+                                                       valueElement.style.width = oldPercentValue + ((newPercentValue - oldPercentValue) * t / end) + "%";
+                                               });
+                                               progress._animate(duration, function (t) {
+                                                       animationFrames.forEach(function (animation) {
+                                                               if (t >= animation.start && t <= animation.end) {
+                                                                       animation.callback(t - animation.start, animation.end - animation.start);
+                                                               } else if (t > animation.end) {
+                                                                       animation.callback(1, 1);
+                                                               }
+                                                       });
+                                               }, function () {
+                                                       if (progress.options.value !== newValue) {
+                                                               type.bar.changeValue(progress, newValue, progress.options.value);
+                                                       }
+                                               });
+                                       }
+                                       updateLabels(progress);
+                               },
+
+                               destroy: function (self, element) {
+                                       var ui = self._ui;
+
+                                       [].slice.call(ui.labelsTop.children).forEach(function (child) {
+                                               element.appendChild(child);
+                                       });
+                                       [].slice.call(ui.labelsBottom.children).forEach(function (child) {
+                                               element.appendChild(child);
+                                       });
+
+                                       ui.progressBarValueBg.parentElement.removeChild(ui.progressBarValueBg);
+                                       ui.labelsTop.parentElement.removeChild(ui.labelsTop);
+                                       ui.labelsBottom.parentElement.removeChild(ui.labelsBottom);
+                                       return true;
+                               }
+                       });
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #progressCircle Type
+ * progressCircle type support for Progress widget.
+ * @internal
+ * @class ns.widget.core.progress.type.progresscircle
+ * @extends ns.widget.core.progress.type.interface
+ */
+(function (document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               doms = ns.util.DOM,
+                               type = ns.widget.core.progress.type,
+                               typeInterface = type.interface,
+                               classes = {
+                                       uiProgressCircle: "ui-progress-circle",
+                                       uiProgressCircleBg: "ui-progress-circle-bg",
+                                       uiProgressCircleValue: "ui-progress-circle-value",
+                                       uiProgressCircleValueLeft: "ui-progress-circle-value-left",
+                                       uiProgressCircleValueRight: "ui-progress-circle-value-right",
+                                       uiProgressCircleHalf: "ui-progress-circle-half"
+                               };
+
+                       /* make widget refresh with new value */
+                       function paintProgressCircle(self) {
+                               var options = self.options,
+                                       percentValue = (options.value * 100) / (options.max - options.min),
+                                       rotateValue,
+                                       ui = self._ui;
+
+                               if (percentValue >= 50) {
+                                       ui.progressValue.classList.add(classes.uiProgressCircleHalf);
+                               } else {
+                                       ui.progressValue.classList.remove(classes.uiProgressCircleHalf);
+                               }
+
+                               rotateValue = 360 * (percentValue / 100);
+
+                               ui.progressValueLeft.style.webkitTransform = "rotate3d(0.0, 0.0, 1.0, " + rotateValue + "deg)";
+                       }
+
+                       function setProgressBarSize(self) {
+                               var progressSize = self.options.size,
+                                       sizeToNumber = parseFloat(progressSize),
+                                       ui = self._ui;
+
+                               if (!isNaN(sizeToNumber)) {
+                                       ui.progressContainer.style.fontSize = progressSize + "px";
+                                       ui.progressContainer.style.width = progressSize + "px";
+                                       ui.progressContainer.style.height = progressSize + "px";
+                               } else {
+                                       switch (progressSize) {
+                                               case "full":
+                                               case "large":
+                                               case "medium":
+                                               case "small":
+                                                       ui.progressContainer.classList.add("ui-progress-circle-" + progressSize);
+                                                       break;
+                                       }
+                                       ui.progressContainer.style.fontSize = doms.getCSSProperty(ui.progressContainer, "width", 0, "float") + "px";
+                               }
+                       }
+
+                       function resetDOM(ui) {
+                               ui.progressValue.classList.remove(classes.uiProgressbarHalf);
+                               ui.progressValueLeft.style.webkitTransform = "";
+                       }
+
+                       type.circle = utilsObject.merge({}, typeInterface, {
+                               build: function (progress, element) {
+                                       var ui = {},
+                                               progressElement = element,
+                                               progresscircleBg,
+                                               progresscircleValue,
+                                               progresscircleValueLeft,
+                                               progresscircleValueRight;
+
+                                       ui.progressContainer = progressElement;
+                                       ui.progressValueBg = progresscircleBg = document.createElement("div");
+                                       ui.progressValue = progresscircleValue = document.createElement("div");
+                                       ui.progressValueLeft = progresscircleValueLeft = document.createElement("div");
+                                       ui.progressValueRight = progresscircleValueRight = document.createElement("div");
+
+                                       // set classNames of progresscircle DOMs.
+                                       progressElement.className = classes.uiProgressCircle;
+                                       progresscircleBg.className = classes.uiProgressCircleBg;
+                                       progresscircleValue.className = classes.uiProgressCircleValue;
+                                       progresscircleValueLeft.className = classes.uiProgressCircleValueLeft;
+                                       progresscircleValueRight.className = classes.uiProgressCircleValueRight;
+
+                                       progresscircleValue.appendChild(progresscircleValueLeft);
+                                       progresscircleValue.appendChild(progresscircleValueRight);
+                                       progressElement.appendChild(progresscircleValue);
+                                       progressElement.appendChild(progresscircleBg);
+
+                                       progress._ui = ui;
+                                       return element;
+                               },
+
+                               init: function (progress, element) {
+                                       var ui = progress._ui;
+
+                                       ui.progressContainer = ui.progressContainer || element;
+                                       ui.progressValueBg = ui.progressValueBg || element.querySelector("." + classes.uiProgressCircleBg);
+                                       ui.progressValue = ui.progressValue || element.querySelector("." + classes.uiProgressCircleValue);
+                                       ui.progressValueLeft = ui.progressValueLeft || element.querySelector("." + classes.uiProgressCircleValueLeft);
+                                       ui.progressValueRight = ui.progressValueRight || element.querySelector("." + classes.uiProgressCircleValueRight);
+
+                                       setProgressBarSize(progress);
+                                       paintProgressCircle(progress);
+                               },
+
+                               refresh: function (progress) {
+                                       resetDOM(progress._ui);
+                                       setProgressBarSize(progress);
+                                       paintProgressCircle(progress);
+                               },
+
+                               changeValue: function (progress) {
+                                       paintProgressCircle(progress);
+                               }
+                       });
+
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Progress
+ * Progress component shows that an operation is in progress.
+ *
+ * #Crete widget
+ *
+ * Shows a control that indicates the progress percentage of an on-going operation by circular shape.
+ *
+ *     @example template tau-progress
+ *         <div class="ui-progress" data-type="bar" data-max="100" data-value="60">
+ *            <span class="ui-current-value"> times</span>
+ *                </div>
+ *
+ *
+ * ##Set and Get the value
+ * You can set or get the value with the value() method
+ *
+ * @since 2.0
+ * @class ns.widget.core.progress.Progress
+ * @component-selector .ui-circle-progress, .ui-progress
+ * @extends ns.widget.BaseWidget
+ * @author Heeju Joo <heeju.joo@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+       
+                       var BaseWidget = ns.widget.BaseWidget,
+                               events = ns.event,
+                               engine = ns.engine,
+                               util = ns.util,
+                               selectors = ns.util.selectors,
+                               utilsObject = ns.util.object,
+                               Page = ns.widget.core.Page,
+                               eventType = {
+                                       /**
+                                        * Event is triggered when value of widget is changing.
+                                        * @event change
+                                        * @member ns.widget.mobile.ProgressBar
+                                        */
+                                       CHANGE: "change"
+                               },
+
+                               progressType = {
+                                       PROGRESS_BAR: "bar",
+                                       PROGRESS_CIRCLE: "circle",
+                                       INDETERMINATE_BAR: "indeterminatebar",
+                                       INDETERMINATE_CIRCLE: "indeterminatecircle"
+                               },
+
+                               circleSize = {
+                                       SMALL_HEADER: "small-header",
+                                       SMALL: "small",
+                                       MEDIUM: "medium",
+                                       LARGE: "large",
+                                       FULL: "full"
+                               },
+                               /**
+                                * Progress constructor
+                                * @method Progress
+                                */
+                               Progress = function () {
+                                       var self = this;
+
+                                       self.options = utilsObject.merge({}, Progress.defaults);
+                                       self._ui = {};
+                                       self._type = null;
+                                       self._progress = null;
+                                       self._isAnimating = false;
+                                       self._callbacks = {};
+                               },
+                               /**
+                                * Dictionary object containing commonly used widget classes
+                                * @property {Object} classes
+                                * @member ns.widget.core.progress.Progress
+                                * @private
+                                * @static
+                                * @readonly
+                                */
+                               classes = {
+                                       uiProgress: "ui-progress"
+                               },
+                               defaults = {
+                                       type: progressType.PROGRESS_BAR,
+                                       size: circleSize.MEDIUM,
+                                       value: 100,
+                                       min: 0,
+                                       max: 100
+                               },
+
+                               prototype = new BaseWidget();
+
+                       Progress.prototype = prototype;
+                       Progress.classes = classes;
+                       Progress.events = eventType;
+                       Progress.defaults = defaults;
+
+                       /**
+                        * Build structure of Progress component
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.progress.Progress
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       options = self.options;
+
+                               self._type = options.type;
+
+                               element.classList.add(classes.uiProgress);
+                               self._progress = ns.widget.core.progress.type[options.type];
+                               self._progress.build(self, element);
+
+                               return element;
+                       };
+
+                       /**
+                        * Initialization of Progress component
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.progress.Progress
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self._progress.init(self, element);
+                               element.setAttribute("value", self.options.value);
+
+                               return element;
+                       };
+
+                       /**
+                        * Refresh of Progress
+                        * @method _refresh
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.progress.Progress
+                        * @protected
+                        */
+                       prototype._refresh = function (element) {
+                               var self = this,
+                                       options = self.options;
+
+                               if (self._type !== options.type) {
+                                       self._destroy();
+                                       return ns.widget.Progress(element, {type: options.type});
+                               } else {
+                                       self._progress.refresh(self);
+                                       self._setValue(self.options.value);
+                               }
+
+                               return element;
+                       };
+
+                       prototype._setValue = function (value) {
+                               var self = this,
+                                       options = self.options,
+                                       element = self.element;
+
+                               self._oldValue = options.value;
+
+
+                               if (typeof value === "number") {
+                                       value = Math.min(options.max, Math.max(options.min, value));
+                                       // value changed
+                                       if (value !== self._oldValue) {
+                                               options.value = value;
+                                               if (!self.isCustomElement) {
+                                                       element.setAttribute("data-value", value);
+                                               }
+                                               element.setAttribute("value", value);
+                                               events.trigger(element, eventType.CHANGE);
+                                               self._progress.changeValue(self, self._oldValue, value);
+                                       }
+                                       return true;
+                               }
+                               return false;
+                       };
+
+                       /**
+                        * Return value of progress
+                        * @return {number}
+                        * @private
+                        */
+                       prototype._getValue = function () {
+                               return parseInt(this.element.getAttribute("value"), 10);
+                       };
+
+                       prototype._animate = function (duration, progressCallback, finishCallback) {
+                               var self = this,
+                                       startTime = null,
+                                       step = function (timeStamp) {
+                                               var currentTimeGap = 0;
+
+                                               if (startTime === null) {
+                                                       startTime = timeStamp;
+                                               }
+                                               currentTimeGap = timeStamp - startTime;
+
+                                               progressCallback(currentTimeGap);
+
+                                               if (self._isAnimating && duration > currentTimeGap) {
+                                                       util.requestAnimationFrame(step);
+                                               } else {
+                                                       self._isAnimating = false;
+                                                       finishCallback();
+                                               }
+                                       };
+
+                               self._isAnimating = true;
+
+                               util.requestAnimationFrame(step);
+                       };
+
+                       /**
+                        * Callback on event pagebeforeshow
+                        * @method pageBeforeShow
+                        * @param {ns.widget.core.progress.Progress} self
+                        * @private
+                        * @member ns.widget.core.progress.Progress
+                        */
+                       function pageBeforeShow(self) {
+                               self.refresh();
+                       }
+
+                       /**
+                        * Bind events to Progress
+                        * @method _bindEvents
+                        * @member ns.widget.core.progress.Progress
+                        * @protected
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       element = self.element,
+                                       page = selectors.getClosestByClass(element, Page.classes.uiPage);
+
+                               self._ui.page = page;
+
+                               self._callbacks.onPageBeforeShow = pageBeforeShow.bind(null, self);
+                               page.addEventListener(Page.events.BEFORE_SHOW, self._callbacks.onPageBeforeShow, false);
+                       };
+
+                       prototype._unbindEvents = function () {
+                               var self = this;
+
+                               if (self._callbacks.onPageBeforeShow) {
+                                       self._ui.page.removeEventListener(
+                                               Page.events.BEFORE_SHOW,
+                                               self._callbacks.onPageBeforeShow,
+                                               false);
+                               }
+                       };
+
+                       /**
+                        * Destroys Progress component
+                        * @method _destroy
+                        * @member ns.widget.core.progress.Progress
+                        * @protected
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               this._unbindEvents();
+
+                               if (!self._progress.destroy(self, element)) {
+                                       while (element.firstChild) {
+                                               element.removeChild(element.firstChild);
+                                       }
+                               }
+
+                               self._ui = null;
+                               self._oldValue = null;
+
+                               return element;
+                       };
+
+                       ns.widget.core.progress.Progress = Progress;
+
+                       engine.defineWidget(
+                               "Progress",
+                               "[data-role='progress'], .ui-progress",
+                               [],
+                               Progress,
+                               "core"
+                       );
+
+                       return Progress;
+                       }(window.document, ns));
+
+/*global ns, define */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Card
+ *
+ * @class ns.widget.core.Card
+ * @extends ns.widget.BaseWidget
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               /**
+                                * Local alias for ns.event
+                                * @property {Object} eventUtils Alias for {@link ns.event}
+                                * @member ns.widget.core.Card
+                                * @static
+                                * @private
+                                */
+                               eventUtils = ns.event,
+                               classes = {
+                                       /**
+                                        * Standard widget
+                                        * @style ui-card
+                                        * @member ns.widget.core.Card
+                                        */
+                                       CARD: "ui-card"
+                               },
+                               Card = function () {
+                                       this._ui = {};
+                                       this.options = {
+                                               src: ""
+                                       }
+                               },
+                               // regexp for filename in URL string
+                               URL_FILE_REGEXP = /([^/])+$/,
+                               // selectors used by this module
+                               selectors = {
+                                       LINKS: "link[href]",
+                                       IMAGES: "img[src]"
+                               },
+                               prototype = new BaseWidget();
+
+                       Card.classes = classes;
+                       Card.prototype = prototype;
+
+                       /**
+                        * Build Card component
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} Returns built element
+                        * @member ns.widget.core.Card
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               element.classList.add(classes.CARD);
+
+                               return element;
+                       };
+
+                       /**
+                        * Init Card component
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} Returns built element
+                        * @member ns.widget.core.Card
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var router = ns.router.Router.getInstance();
+
+                               if (this.options.src !== "") {
+                                       router.open(this.options.src, {
+                                               rel: "card",
+                                               card: this
+                                       });
+                               }
+
+                               return element;
+                       };
+
+                       /**
+                       * This method adds an element as a card content.
+                       * @method _include
+                       * @param {HTMLElement} content content an element to add
+                       * @return {HTMLElement}
+                       * @member ns.widget.core.Card
+                       * @protected
+                       */
+                       prototype._include = function (content, options) {
+                               var element = this.element,
+                                       links,
+                                       images,
+                                       relativePath,
+                                       relativeFile,
+                                       urlObject;
+
+                               if (!content.parentNode || content.ownerDocument !== document) {
+                                       // load styles.css
+                                       links = content.querySelectorAll(selectors.LINKS);
+                                       links.forEach(function (link) {
+                                               if (link.href.indexOf(ns.util.path.parseLocation(options.url).domain) === 0) {
+                                                       urlObject = ns.util.path.parseLocation(options.url);
+                                                       relativeFile = link.href.replace(urlObject.domain, "").replace(urlObject.directory, "");
+                                                       ns.util.load.cssSync(link.href, function (styleElement) {
+                                                               ns.util.load.addElementToHead(styleElement, true);
+                                                       }, function (xhrObj, xhrStatus) {
+                                                               ns.warn("There was a problem when loading, status: " + xhrStatus);
+                                                       });
+                                               }
+                                               link.parentElement.removeChild(link);
+                                       });
+
+                                       // evaluate scripts
+                                       content = ns.util.importEvaluateAndAppendElement(content, element);
+
+                                       // make images urls relative to base dir
+                                       if (options && options.url) {
+                                               urlObject = ns.util.path.parseLocation(options.url);
+                                               relativePath = options.url.replace(URL_FILE_REGEXP, "");
+
+                                               images = content.querySelectorAll(selectors.IMAGES);
+                                               images.forEach(function (source) {
+                                                       if (source.src.indexOf(ns.util.path.parseLocation(options.url).domain) === 0) {
+                                                               relativeFile = source.src.replace(urlObject.domain, "").replace(urlObject.directory, "");
+                                                               source.src = relativePath + relativeFile;
+                                                       }
+                                               });
+                                       }
+                               }
+                               return content;
+                       };
+
+                       prototype.changeContent = function (content, options) {
+                               var self = this;
+
+                               if (self.element.parentElement) {
+                                       content = self._include(content, options);
+                                       ns.engine.createWidgets(content);
+                                       eventUtils.trigger(content, "cardcontentchange");
+                               } else {
+                                       eventUtils.trigger(content, "cardcontentabort");
+                               }
+
+                       };
+
+                       /**
+                        * Destroy Card component
+                        * @method _destroy
+                        * @member ns.widget.core.Card
+                        * @protected
+                        */
+                       prototype._destroy = function () {
+                               this._unbindEvents();
+                       };
+
+                       // definition
+                       ns.widget.core.Card = Card;
+
+                       engine.defineWidget(
+                               "Card",
+                               ".ui-card",
+                               [],
+                               Card,
+                               "core"
+                       );
+                       }(window.document, ns));
+
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global define, ns */
+/**
+ *
+ * @since 1.2
+ * @class ns.widget.core.Appbar
+ * @extends ns.widget.core.BaseWidget
+ * @author Pawel Kaczmarczyk <p.kaczmarczy@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               utilsEvents = ns.event,
+                               utilSelectors = ns.util.selectors,
+                               Page = ns.widget.core.Page,
+                               min = Math.min,
+                               max = Math.max,
+                               nominalHeights = {
+                                       COLLAPSED: 56,
+                                       EXPANDED: 56
+                               },
+                               states = {
+                                       EXPANDED: "EXPANDED",
+                                       COLLAPSED: "COLLAPSED",
+                                       DRAGGING: "DRAGGING"
+                               },
+                               SCREEN_HEIGHT_LIMIT_FOR_EXPANDING = 579,
+                               Appbar = function () {
+                                       var self = this;
+
+                                       self.options = utilsObject.merge({}, Appbar.defaults);
+                                       self._ui = {
+                                               titleContainer: null,
+                                               leftIconsContainer: null,
+                                               actionButtonsContainer: null,
+                                               page: null,
+                                               selectAll: null,
+                                               bottomBar: null,
+                                               instantContainers: []
+                                       };
+                                       self._expandedHeight = nominalHeights.EXPANDED;
+                                       self._appbarState = states.COLLAPSED;
+                                       self._dragStartingHeight = 0;
+                                       self._currentHeight = 0;
+                                       self._instantContainersHeight = 0;
+                                       self._scrolledToTop = true;
+                                       self._lockExpanding = false;
+                                       self._calculateExtendedHight();
+                               },
+                               BaseWidget = ns.widget.BaseWidget,
+                               prototype = new BaseWidget(),
+                               classPrefix = "ui-appbar",
+                               classes = {
+                                       title: classPrefix + "-title",
+                                       leftIconsContainer: classPrefix + "-left-icons-container",
+                                       actionButtonsContainer: classPrefix + "-action-buttons-container",
+                                       instantContainer: classPrefix + "-container",
+                                       titleContainer: classPrefix + "-title-container",
+                                       hasMultilineTitle: classPrefix + "-has-multiline",
+                                       hasSubtitle: classPrefix + "-has-subtitle",
+                                       expanded: classPrefix + "-expanded",
+                                       dragging: classPrefix + "-dragging",
+                                       controlsContainer: classPrefix + "-controls-container",
+                                       expandedTitleContainer: classPrefix + "-expanded-title-container",
+                                       animationFast: classPrefix + "-animation-fast",
+                                       selectAll: "ui-label-select-all",
+                                       bottomBar: "ui-bottom-bar",
+                                       hidden: "ui-hidden"
+                               },
+                               containersProperties = {
+                                       leftIconsContainer: {
+                                               selector: "." + classes.leftIconsContainer,
+                                               class: classes.leftIconsContainer,
+                                               position: 0
+                                       },
+                                       titleContainer: {
+                                               selector: "." + classes.titleContainer,
+                                               class: classes.titleContainer,
+                                               position: 1
+                                       },
+                                       actionButtonsContainer: {
+                                               selector: "." + classes.actionButtonsContainer,
+                                               class: classes.actionButtonsContainer,
+                                               position: 2
+                                       }
+                               },
+                               selectors = {
+                                       IS_CHECKED: ".ui-listview li > input[type='checkbox']:checked",
+                                       IS_NOT_CHECKED: ".ui-listview li > input[type='checkbox']:not(:checked)"
+                               },
+                               defaults = {
+                                       titleType: "singleLine", // "multiline", "subtitle"
+                                       expandingEnabled: true,
+                                       animation: true
+                               };
+
+                       Appbar.prototype = prototype;
+                       Appbar.defaults = defaults;
+                       Appbar.classes = classes;
+                       Appbar.selector = ".ui-appbar,.ui-header,header,[data-role='header']";
+
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self._initExpandedContainer(element);
+
+                               self._setAnimation(element, self.options.animation);
+                               self._appbarState = states.COLLAPSED;
+                               self._validateExpanding();
+
+                               self._ui.page = utilSelectors.getClosestBySelector(element, Page.selector);
+                               self._ui.selectAll = element.querySelector("." + classes.selectAll + " input[type='checkbox']");
+                               self._ui.bottomBar = self._ui.page.querySelector("." + classes.bottomBar);
+                       };
+
+                       /**
+                        * Build the widget
+                        * @method _build
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               var self = this;
+
+                               self._createContainers(element);
+                               self._findInstantContainers(element);
+                               self._readTitleType(element);
+                               self._setTitleType(element, self.options.titleType);
+                               return element;
+                       };
+
+                       prototype._calculateInstantContainers = function (element) {
+                               var self = this,
+                                       instantContainersHeight = 0;
+
+                               // calculate instant containers height
+                               element.style.height = "auto";
+                               self._ui.instantContainers.forEach(function (container) {
+                                       instantContainersHeight += container.offsetHeight;
+                               });
+
+                               return instantContainersHeight;
+                       };
+
+                       prototype._updateAppbarDimensions = function (element) {
+                               var self = this,
+                                       instantContainersHeight = self._instantContainersHeight,
+                                       controlsContainer = self._ui.controlsContainer;
+
+                               // increase height of appbar and change bottom possition of control container
+                               if (instantContainersHeight > 0) {
+                                       self._calculateExtendedHight();
+                                       self._expandedHeight += instantContainersHeight;
+                                       self._currentHeight += instantContainersHeight;
+                                       if (controlsContainer) {
+                                               controlsContainer.style.bottom = instantContainersHeight + "px";
+                                       }
+                                       self._instantContainersHeight = instantContainersHeight
+                               }
+
+                               // set initial height of collapsed appbar
+                               element.style.height = nominalHeights.COLLAPSED + self._instantContainersHeight + "px";
+                       };
+
+                       /**
+                        * Method set new height of appbar if instant container exists
+                        * @param {HTMLElement} element
+                        * @method _findInstantContainers
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._findInstantContainers = function (element) {
+                               var self = this;
+
+                               self._ui.instantContainers = [].slice.call(element.querySelectorAll("." + classes.instantContainer));
+
+                               self._instantContainersHeight = self._calculateInstantContainers(element);
+                               self._updateAppbarDimensions(element);
+                       };
+
+                       /**
+                        * Add Html element as instant container
+                        * @param {HTMLElement} container
+                        * @method addInstantContainer
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype.addInstantContainer = function (container) {
+                               var self = this;
+
+                               if (container && container instanceof HTMLElement) {
+                                       container.classList.add(classes.instantContainer);
+                                       self.element.appendChild(container);
+                                       self.refresh();
+                               } else {
+                                       ns.warn("AppBar: method addInstantContainer needs argument");
+                               }
+                       }
+
+                       /**
+                        * Remove instant container
+                        * @param {HTMLElement} container
+                        * @method removeInstantContainer
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype.removeInstantContainer = function (container) {
+                               var self = this;
+
+                               if (container && container instanceof HTMLElement) {
+                                       if (container.parentElement) {
+                                               container.parentElement.removeChild(container);
+                                               self.refresh();
+                                       }
+                               } else {
+                                       ns.warn("AppBar: method removeInstantContainer needs argument");
+                               }
+                       }
+
+                       /**
+                        * Refresh the widget
+                        * @method _refresh
+                        * @member ns.widget.core.Appbar
+                        * @param {HTMLElement} element
+                        * @protected
+                        */
+                       prototype._refresh = function (element) {
+                               var self = this;
+
+                               element = element || self.element;
+                               self._findInstantContainers(element);
+                               self._ui.instantContainers.forEach(function (container) {
+                                       ns.engine.createWidgets(container);
+                               });
+                       };
+
+                       /**
+                        * Method calculates and set nominal height of extended AppBar
+                        * depend of screen height.
+                        * Height of expanded AppBar is needed by handler of drag event
+                        * @method _calculateExtendedHight
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._calculateExtendedHight = function () {
+                               var self = this,
+                                       screenHeight = window.screen.height,
+                                       screenWidth = window.screen.width,
+                                       bottomMarginHeight = 12;
+
+                               if (screenHeight >= 580 && screenHeight < 960 && screenWidth > screenHeight) { // lanscape
+                                       self._expandedHeight = screenHeight * 0.3 - bottomMarginHeight;
+                               } else if (screenHeight >= 580 && screenHeight < 960 && screenWidth <= screenHeight) { // portrait
+                                       self._expandedHeight = screenHeight * 0.3967 - bottomMarginHeight;
+                               } else if (screenHeight >= 960) {
+                                       self._expandedHeight = screenHeight * 0.25 - bottomMarginHeight;
+                               } else {
+                                       self._expandedHeight = nominalHeights.EXPANDED;
+                               }
+                       };
+
+                       /**
+                        * Init expanded container
+                        * Find expanded container or create if not exists yet
+                        * @method _initExpandedContainer
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._initExpandedContainer = function (element) {
+                               var ui = this._ui,
+                                       expandedTitleContainer = element.querySelector("." + classes.expandedTitleContainer);
+
+                               if (!expandedTitleContainer) {
+                                       expandedTitleContainer = document.createElement("div")
+                                       expandedTitleContainer.classList.add(classes.expandedTitleContainer);
+
+                                       // clone titles to expanded container if not existed before
+                                       [].slice.call(ui.titleContainer.children).forEach(function (node) {
+                                               expandedTitleContainer.appendChild(node.cloneNode(true));
+                                       });
+                               }
+
+                               ui.expandedTitleContainer = expandedTitleContainer;
+                               element.insertBefore(expandedTitleContainer, ui.controlsContainer);
+                       };
+
+                       /**
+                        * Method that creates containers (or finds ones if already exists)
+                        * for different sections of appbar widgets
+                        * @method _createContainers
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._createContainers = function (element) {
+                               var ui = this._ui;
+
+                               ui.controlsContainer = document.createElement("div")
+                               ui.controlsContainer.classList.add(classes.controlsContainer);
+                               element.appendChild(ui.controlsContainer);
+
+                               Object.keys(containersProperties).forEach(function (containerName) {
+                                       var config = containersProperties[containerName],
+                                               container = element.querySelector(config.selector);
+
+                                       if (!container) {
+                                               container = document.createElement("div");
+                                               container.classList.add(config.class);
+                                               element.appendChild(container);
+                                       }
+                                       ui[containerName] = container;
+                               });
+
+                               // All of the containers should be placed inside controls container and in specific order
+                               Object.keys(containersProperties).sort(function (a, b) {
+                                       return containersProperties[a].position - containersProperties[b].position;
+                               }).forEach(function (key) {
+                                       ui.controlsContainer.appendChild(ui[key]);
+                               });
+                       };
+
+                       /**
+                        * Binds event listeners
+                        * @method _bindEvents
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this;
+
+                               ns.event.enableGesture(self._ui.page,
+                                       new ns.event.gesture.Drag());
+
+                               utilsEvents.on(
+                                       self._ui.page,
+                                       "scrollboundary drag dragstart dragend scrollstart change pagebeforeshow popupshow popuphide",
+                                       self);
+                               window.addEventListener("resize", self, false);
+                       };
+
+                       /**
+                        * Handle event
+                        * @method handleEvent
+                        * @param {Event} event
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "scrollboundary":
+                                               self._onScrollBoundary(event);
+                                               break;
+                                       case "drag":
+                                               self._onDrag(event);
+                                               break;
+                                       case "dragstart":
+                                               self._onDragStart(event);
+                                               break;
+                                       case "dragend":
+                                               self._onDragEnd(event);
+                                               break;
+                                       case "scrollstart":
+                                               self._onScrollStart(event);
+                                               break;
+                                       case "change":
+                                               self._onChange(event);
+                                               break;
+                                       case "pagebeforeshow":
+                                               self._onPageBeforeShow();
+                                               break;
+                                       case "popupshow":
+                                               self._onPopupShow();
+                                               break;
+                                       case "popuphide":
+                                               self._onPopupHide();
+                                               break;
+                                       case "resize":
+                                               self._onResize();
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * PageBeforeShow event handler
+                        * @method _onPageBeforeShow
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onPageBeforeShow = function () {
+                               var self = this,
+                                       ui = self._ui;
+
+                               if (ui.selectAll) {
+                                       self._triggerSelectAll();
+                                       if (ui.bottomBar) {
+                                               self._toggleBottomBar(!!ui.page.querySelector(selectors.IS_CHECKED));
+                                       }
+                                       self._updateTitle();
+                               }
+                       };
+
+                       /**
+                        * PopupShow event handler
+                        * @method _onPopupShow
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onPopupShow = function () {
+                               this.options.expandingEnabled = false;
+                       };
+
+                       /**
+                        * PopupHide event handler
+                        * @method _onPopupHide
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onPopupHide = function () {
+                               this.options.expandingEnabled = true;
+                       };
+
+                       /**
+                        * Scrollstart event handler
+                        * @method _onScrollStart
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onScrollStart = function () {
+                               this._scrolledToTop = false;
+                       }
+
+                       /**
+                        * Scrollstart event handler
+                        * @method _onScrollStart
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onScrollBoundary = function (event) {
+                               var self = this,
+                                       direction = event && event.detail && event.detail.direction;
+
+                               self._scrolledToTop = (direction === "top");
+                               utilsEvents.one(self._ui.page, "scrollstart", self._onScrollStart.bind(self));
+                       };
+
+                       /**
+                        * Dragstart event handler
+                        * @method _onDragStart
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onDragStart = function (event) {
+                               var self = this;
+
+                               if (!self._lockExpanding && self.options.expandingEnabled && (
+                                       (event.detail.direction === "down" && self._appbarState == states.COLLAPSED && self._scrolledToTop) ||
+                                       (event.detail.direction === "up" && self._appbarState == states.EXPANDED))) {
+
+                                       self._appbarState = states.DRAGGING;
+                                       self.element.classList.add(classes.dragging);
+                                       self._dragStartingHeight = self.element.getBoundingClientRect().height;
+
+                                       // trigger appbarDragStart Event - page should disable scrolling module
+                                       self._expandedTitleHeight = 0;
+                                       [].slice.call(self._ui.expandedTitleContainer.children).forEach(function (item) {
+                                               self._expandedTitleHeight += item.offsetHeight;
+                                       });
+                               }
+                       };
+
+                       /**
+                        * Set opacity level of title during the drag of content
+                        * @method _setTitlesOpacity
+                        * @param {boolean} expandLevel
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._setTitlesOpacity = function (expandLevel) {
+                               var self = this,
+                                       ui = self._ui,
+                                       mainTitle = ui.titleContainer,
+                                       expandedTitle = ui.expandedTitleContainer;
+
+                               mainTitle.style.opacity = 1 - expandLevel;
+                               expandedTitle.style.opacity = expandLevel;
+                       };
+
+                       /**
+                        * Expand AppBar
+                        * @method expand
+                        * @member ns.widget.core.Appbar
+                        * @public
+                        */
+                       prototype.expand = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               element.style.height = self._expandedHeight + "px";
+                               element.classList.add(classes.expanded);
+                               self._appbarState = states.EXPANDED;
+                               self._setTitlesOpacity(1);
+                               utilsEvents.trigger(element, "appbarexpanded");
+                       };
+
+                       /**
+                        * Animation transition end event handler
+                        * @method _onTransitionEnd
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onTransitionEnd = function () {
+                               /**
+                                * After the AppBar expanding or collapsing
+                                * the size of Page content will be changed
+                                * so Page should be refreshed to better fit
+                                * to new available space.
+                                */
+                               utilsEvents.trigger(this.element, "appbartransitionend");
+                       };
+
+                       /**
+                        * Collapse AppBar
+                        * @method collapse
+                        * @member ns.widget.core.Appbar
+                        * @public
+                        */
+                       prototype.collapse = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               self._currentHeight = self._instantContainersHeight;
+                               element.style.height = nominalHeights.COLLAPSED + self._instantContainersHeight + "px";
+
+                               element.classList.remove(classes.expanded);
+                               self._appbarState = states.COLLAPSED;
+                               self._setTitlesOpacity(0);
+                               utilsEvents.trigger(element, "appbarcollapsed");
+
+                               utilsEvents.one(element,
+                                       "transitionend transitionEnd webkitTransitionEnd",
+                                       self._onTransitionEnd.bind(self), false);
+                       };
+
+                       /**
+                        * Lock/Unlock AppBar expanding
+                        * Developer can temporarily locks AppBar expanding,
+                        * eg. when a widget in page content requires it
+                        * @method lockExpanding
+                        * @param {boolean} lock
+                        * @member ns.widget.core.Appbar
+                        * @public
+                        */
+                       prototype.lockExpanding = function (lock) {
+                               this._lockExpanding = !!lock;
+                       };
+
+                       /**
+                        * Dragend event handler
+                        * @method _onDragEnd
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onDragEnd = function () {
+                               var self = this,
+                                       threshold
+
+                               if (!self._lockExpanding && self.options.expandingEnabled) {
+                                       threshold = (nominalHeights.COLLAPSED + self._expandedHeight) / 2;
+                                       self.element.classList.remove(classes.dragging);
+
+                                       if (self._currentHeight > threshold) {
+                                               self.expand();
+                                       } else {
+                                               self.collapse();
+                                       }
+
+                                       // trigger appbarDragStart Event - page should enable scrolling back again
+                                       // appbar resized event should be triggered (in order to inform Page about content height change)
+                               }
+                       };
+
+                       /**
+                        * Drag event handler
+                        * @method _onDrag
+                        * @param {Event} event
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onDrag = function (event) {
+                               var self = this,
+                                       deltaY = event && event.detail && event.detail.deltaY,
+                                       totalHeight = self._dragStartingHeight + ((deltaY !== undefined) ? deltaY : 0),
+                                       totalMovement = 0;
+
+                               if (!self._lockExpanding && self._appbarState === states.DRAGGING) {
+                                       totalHeight = min(totalHeight, self._expandedHeight);
+                                       totalHeight = max(totalHeight, nominalHeights.COLLAPSED);
+
+                                       if (self._currentHeight !== totalHeight) {
+                                               self._currentHeight = totalHeight;
+                                               self.element.style.height = totalHeight + "px";
+
+                                               totalMovement = totalHeight - nominalHeights.COLLAPSED;
+
+                                               if (totalMovement > self._expandedTitleHeight) {
+                                                       self._setTitlesOpacity(totalMovement / (self._expandedHeight - nominalHeights.COLLAPSED));
+                                               } else {
+                                                       self._setTitlesOpacity(0);
+                                               }
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Verification and enable/disable AppBar expanding
+                        * depending on the screen height
+                        * @method _validateExpanding
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._validateExpanding = function () {
+                               var self = this;
+
+                               if (window.screen.height <= SCREEN_HEIGHT_LIMIT_FOR_EXPANDING) {
+                                       self._lockExpanding = true;
+                               } else {
+                                       self._lockExpanding = false;
+                               }
+                       }
+
+                       /**
+                        * Resize event handler
+                        * Widget has to check if new screen height allows to widget expanding
+                        * @method _onResize
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onResize = function () {
+                               this._validateExpanding();
+                       };
+
+                       /**
+                        * Method triggers "select-all" event
+                        * @method _triggerSelectAll
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._triggerSelectAll = function () {
+                               var self = this;
+
+                               utilsEvents.trigger(self.element, "select-all", {checked: self._ui.selectAll.checked});
+                       };
+
+                       /**
+                        * Toggle state of checkbox "All"
+                        * @method _toggleSelectAll
+                        * @param {boolean} checked
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._toggleSelectAll = function (checked) {
+                               var selectAll = this._ui.selectAll;
+
+                               if (selectAll) {
+                                       selectAll.checked = checked;
+                                       if (checked) {
+                                               selectAll.setAttribute("checked", "checked");
+                                       } else {
+                                               selectAll.removeAttribute("checked");
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Toggle visibility of BottomBar
+                        * @method _toggleBottomBar
+                        * @param {boolean} visible
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._toggleBottomBar = function (visible) {
+                               this._ui.bottomBar.classList.toggle(classes.hidden, !visible);
+                       };
+
+                       /**
+                        * Method returns number of checkboxes in state checked
+                        * @method _getNumberOfChecked
+                        * @member ns.widget.core.Appbar
+                        * @return {number}
+                        * @protected
+                        */
+                       prototype._getNumberOfChecked = function () {
+                               return this._ui.page.querySelectorAll(selectors.IS_CHECKED).length;
+                       };
+
+                       /**
+                        * Handler for "change" event
+                        * @method _onChange
+                        * @param {Event} event
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._onChange = function (event) {
+                               var target = event.target,
+                                       self = this,
+                                       ui = self._ui,
+                                       page = self._ui.page;
+
+                               // update bottom bar visibility if options selectAll in AppBar exists
+                               if (ui.selectAll && target.tagName === "INPUT") {
+                                       if (target === ui.selectAll) {
+                                               self._triggerSelectAll();
+                                       } else {
+                                               self._toggleSelectAll(!page.querySelector(selectors.IS_NOT_CHECKED));
+                                       }
+
+                                       if (ui.bottomBar) {
+                                               self._toggleBottomBar(!!page.querySelector(selectors.IS_CHECKED));
+                                       }
+                                       if (ui.selectAll) {
+                                               self._updateTitle();
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Update AppBar title according to number of selected items
+                        * @method _updateTitle
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._updateTitle = function () {
+                               var titles = [].slice.call(this.element.querySelectorAll("." + classes.title)),
+                                       numberOfSelectedItems = this._getNumberOfChecked();
+
+                               titles.forEach(function (title) {
+                                       title.textContent = numberOfSelectedItems === 0 ?
+                                               "Select items" :
+                                               numberOfSelectedItems + " selected";
+                               });
+                       };
+
+                       /**
+                        * Unbinds event listeners
+                        * @method _unbindEvents
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._unbindEvents = function () {
+                               var self = this;
+
+                               utilsEvents.off(
+                                       self._ui.page,
+                                       "scrollboundary drag dragstart dragend scrollstart change pagebeforeshow popupshow popuphide",
+                                       self);
+                               window.removeEventListener("resize", self, false);
+                       };
+
+                       /**
+                        * Destroys the widget
+                        * @method _destroy
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._destroy = function () {
+                               var self = this;
+
+                               self._unbindEvents();
+                               // restore title elements if they're moved during build
+                       };
+
+                       /**
+                        * Method that detects title style
+                        * @method _readTitleType
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._readTitleType = function () {
+                               var self = this,
+                                       titleContainer = self._ui.titleContainer;
+
+                               if (titleContainer.classList.contains(classes.hasMultilineTitle)) {
+                                       self.options.titleType = "multiline";
+                               }
+                               if (titleContainer.classList.contains(classes.hasSubtitle)) {
+                                       self.options.titleType = "subtitle";
+                               }
+                       };
+
+                       /**
+                        * Method that sets styling for title
+                        * @method _setTitleType
+                        * @param {HTMLElement} element
+                        * @param {string} titleType
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._setTitleType = function (element, titleType) {
+                               var self = this,
+                                       titleContainer = self._ui.titleContainer;
+
+                               titleContainer.classList.remove(classes.hasMultilineTitle, classes.hasSubtitle);
+
+                               switch (titleType) {
+                                       case "multiline":
+                                               titleContainer.classList.add(classes.hasMultilineTitle);
+                                               break;
+                                       case "subtitle":
+                                               titleContainer.classList.add(classes.hasSubtitle);
+                                               break;
+                                       case "singleLine":
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * Set expanding option
+                        * @method _setExpandingEnabled
+                        * @param {HTMLElement} element
+                        * @param {boolean} enabled
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._setExpandingEnabled = function (element, enabled) {
+                               var self = this;
+
+                               if (self.options.expandingEnabled !== enabled) {
+                                       self.options.expandingEnabled = enabled;
+                                       if (!enabled && self._appbarState !== states.COLLAPSED) {
+                                               self.collapse();
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Set animation option
+                        * @method _setAnimation
+                        * @param {HTMLElement} element
+                        * @param {boolean} enabled
+                        * @member ns.widget.core.Appbar
+                        * @protected
+                        */
+                       prototype._setAnimation = function (element, enabled) {
+                               this.options.animation = enabled;
+                               element.classList.toggle(classes.animationFast, !enabled);
+                       };
+
+                       ns.widget.core.Appbar = Appbar;
+                       ns.engine.defineWidget(
+                               "Appbar",
+                               Appbar.selector,
+                               [],
+                               Appbar,
+                               "core"
+                       );
+                       }(window, window.document, ns));
+
+/*global window, define, ns */
+/*
+* Copyright (c) 2019 Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.1 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/* #Interactive 3D
+* Interactive 3D widget is using the r-type library to show 3D model.
+* It is included at the libs folder. If you want to use the Interactive 3D,
+* you have to add the r-type library in your project.
+*
+* <script src="tau/libs/r-type.min.js></script>"
+*
+* @example
+* <div class="ui-i3d"></div>
+*
+* @since 5.5
+* @class ns.widget.core.Interactive3D
+* @extends ns.widget.BaseWidget
+* @author Hunseop Jeong <hs85.jeong@samsung.com>
+*/
+(function (window, document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               Interactive3D = function () {
+                                       this._ui = {};
+                               },
+                               allowAttributes = [
+                                       "width", "height", "position", "scale", "rotation", "controls",
+                                       "autoplay", "light", "src", "show", "hide", "mtl"
+                               ],
+                               prototype = new BaseWidget();
+
+                       Interactive3D.prototype = prototype;
+
+                       /**
+                       * Init widget
+                       * @method _init
+                       * @param {HTMLElement} element
+                       * @return {HTMLElement} Returns built element
+                       * @member ns.widget.core.Interactive3D
+                       * @protected
+                       */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self.observer = new MutationObserver(self._attributeChange.bind(this));
+                               self.observer.observe(element, {attributes: true});
+
+                               return element;
+                       }
+
+                       /**
+                       * Observe whether the attribute changes
+                       * @method _attributeChange
+                       * @param {Object[]} mutationList
+                       * @member ns.widget.core.Interactive3D
+                       * @protected
+                       */
+                       prototype._attributeChange = function (mutationList) {
+                               var self = this;
+
+                               mutationList.forEach(function (mutation) {
+                                       var attributeName = mutation.attributeName,
+                                               target;
+
+                                       if (allowAttributes.indexOf(attributeName) !== -1) {
+                                               target = mutation.target;
+
+                                               if (target.hasAttribute(attributeName)) {
+                                                       self._ui.rType.setAttribute(attributeName, target.attributes[attributeName].value);
+                                               } else {
+                                                       self._ui.rType.removeAttribute(attributeName);
+                                               }
+                                       }
+                               });
+                       };
+
+                       /**
+                       * Build widget structure
+                       * @method _build
+                       * @param {HTMLElement} element
+                       * @return {HTMLElement} Returns built element
+                       * @member ns.widget.core.Interactive3D
+                       * @protected
+                       */
+                       prototype._build = function (element) {
+                               var rType = document.createElement("r-type"),
+                                       attributes = element.attributes,
+                                       i;
+
+                               for (i = 0; i < attributes.length; i++) {
+                                       if (allowAttributes.indexOf(attributes[i].name) !== -1) {
+                                               rType.setAttribute(attributes[i].name, attributes[i].value);
+                                       }
+                               }
+
+                               this._ui.rType = rType;
+                               element.appendChild(rType);
+
+                               return element;
+                       };
+
+                       /**
+                       * Destroys Interactive 3D widget
+                       * @method _destroy
+                       * @member ns.widget.core.Interactive3D
+                       * @protected
+                       */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       rType = ui.rType;
+
+                               if (rType && rType.parentNode) {
+                                       rType.parentNode.removeChild(rType);
+                               }
+
+                               this.observer.disconnect();
+                       };
+
+                       ns.widget.core.Interactive3D = Interactive3D;
+
+                       engine.defineWidget(
+                               "Interactive3D",
+                               ".ui-i3d",
+                               [],
+                               Interactive3D,
+                               "core"
+                       );
+                       }(window, window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * #CoverFlow
+ * Cover flow widget is using the jQuery.Flipster library for cover flow
+ * effect.
+ * It is included at the libs folder. If you want to use the CoverFlow,
+ * you have to add the jQuery.Flipster library in your project after jQuery.
+ *
+ * <script src="tau/mobile/js/jquery.min.js"></script>
+ * <script src="tau/libs/jquery.flipster.min.js></script>"
+ *
+ * @example
+ * <div class="ui-coverflow"></div>
+ *
+ * @since 5.5
+ * @class ns.widget.core.CoverFlow
+ * @extends ns.widget.BaseWidget
+ * @author Dohyung Lim <delight.lim@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+
+                               CoverFlow = function () {
+                                       this.options = utilsObject.merge({}, CoverFlow.defaults);
+                                       this.observer = null;
+                               },
+
+                               defaults = { value: "coverflow" },
+
+                               BaseWidget = ns.widget.BaseWidget,
+                               prototype = new BaseWidget();
+
+                       CoverFlow.prototype = prototype;
+                       CoverFlow.defaults = defaults;
+
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               if (!element.getAttribute("value")) {
+                                       element.setAttribute("value", self.options.value);
+                               }
+
+                               self.observer = new MutationObserver(self._checkEffectChange.bind(this));
+                               self.observer.observe(element, {attributes: true});
+
+                               return element;
+                       };
+
+                       prototype._checkEffectChange = function (mutationsList) {
+                               mutationsList.forEach(function (mutation) {
+                                       if (mutation.attributeName === "data-effect" && this.element.getAttribute("data-effect")) {
+                                               this.options.value = this.element.getAttribute("data-effect");
+                                               this._refresh();
+                                       }
+                               }.bind(this));
+                       };
+
+                       prototype._refresh = function () {
+                               var self = this;
+
+                               self._setValue(self.options.value);
+                       }
+
+                       prototype._setValue = function (value) {
+                               this.ui = {};
+                               this.ui.$element = window.jQuery(this.element).flipster({
+                                       style: value,
+                                       spacing: -0.5
+                               });
+                       }
+
+                       prototype._build = function (element) {
+                               if (element.getAttribute("data-effect")) {
+                                       this.options.value = element.getAttribute("data-effect");
+                               }
+
+                               this.ui = {};
+                               if (window.jQuery && typeof window.jQuery.fn.flipster === "function") {
+                                       this.ui.$element = window.jQuery(element).flipster({
+                                               style: this.options.value,
+                                               spacing: -0.5
+                                       });
+                               } else {
+                                       ns.warn("JQuery or flipster.js not exists");
+                               }
+                               return element;
+                       };
+
+                       prototype._destroy = function () {
+                               this.observer.disconnect();
+                       }
+
+                       ns.engine.defineWidget(
+                               "CoverFlow",
+                               ".ui-coverflow",
+                               [],
+                               CoverFlow,
+                               "core"
+                       );
+                       }(window, window.document, ns));
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, define, ns */
+/*
+ * #Graph
+ *
+ * Graph widget are using external libraries:
+ * http://cdn.jsdelivr.net/d3js/3.5.17/d3.min.js
+ * http://cdn.jsdelivr.net/npm/taucharts@1/build/production/tauCharts.min.js
+ * These libraries are not part of TAU source code.
+ * These libraries are attached to project but references should be added in a application
+ *
+ * <script src="tau/libs/d3.min.js" charset="utf-8"></script>
+ * <script src="tau/libs/tauCharts.min.js" type="text/javascript"></script>
+ * <link rel="stylesheet" type="text/css" href="tau/libs/tauCharts.min.css">
+ *
+ * @example
+ *     <div class="ui-graph"></div>
+ *
+ * <div class="ui-graph"
+ *      data-graph="scatterplot"
+ *      data-color="#FF0000"
+ *      data-xlabel="x label"
+ *      data-ylabel="y label"
+ * ></div>
+ *
+ * @since 5.0
+ * @class ns.widget.core.Graph
+ * @extends ns.widget.core.BaseWidget
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               MODE_INTERMITTENT = "intermittent",
+                               MODE_CONTINUOUS = "continuous",
+
+                               xAxis = "x",
+                               yAxis = "y",
+
+                               TIME_AXIS_X = xAxis,
+                               TIME_AXIS_Y = yAxis,
+                               TIME_AXIS_NONE = "none",
+
+                               graphTypes = {
+                                       stackedBar: "stacked-bar",
+                                       line: "line",
+                                       stackedArea: "stacked-area",
+                                       scatterplot: "scatterplot",
+                                       bar: "bar"
+                               },
+
+                               defaults = {
+                                       graph: graphTypes.line,
+                                       color: "#0097D8",
+                                       xlabel: "",
+                                       ylabel: "",
+                                       axisXType: "time",
+                                       axisYType: "linear",
+                                       mode: MODE_INTERMITTENT,
+                                       value: [],
+                                       timeAxis: TIME_AXIS_X, // only when one value supplied
+                                       groupKey: "label",
+                                       legend: false
+                               },
+
+                               Graph = function () {
+                                       var self = this;
+
+                                       self.options = utilsObject.merge({}, Graph.defaults);
+
+                                       self.data = [];
+                                       self.size = "";
+                                       self._initialData = true;
+                                       self.split = "formula";
+                                       self.guide = {
+                                               color: {
+                                                       brewer: [defaults.color]
+                                               },
+                                               showGridLines: "xy",
+                                               x: {
+                                                       nice: false,
+                                                       label: {
+                                                               text: defaults.xlabel
+                                                       }
+                                               },
+                                               y: {
+                                                       nice: false,
+                                                       label: {
+                                                               text: defaults.ylabel
+                                                       }
+                                               }
+                                       };
+                                       self.dimensions = {
+                                               x: {
+                                                       type: "order",
+                                                       scale: "time"
+                                               },
+                                               y: {
+                                                       type: "order",
+                                                       scale: "linear"
+                                               }
+                                       };
+                                       self.chart = null;
+                               },
+
+                               addLibText = "Please, include tauCharts library (https://www.taucharts.com/).",
+
+                               classes = {
+                                       graphContainer: "ui-graph"
+                               },
+
+                               BaseWidget = ns.widget.BaseWidget,
+                               prototype = new BaseWidget();
+
+                       Graph.prototype = prototype;
+                       Graph.defaults = defaults;
+                       Graph.MODE = {
+                               INTERMITTENT: MODE_INTERMITTENT,
+                               CONTINUOS: MODE_CONTINUOUS
+                       };
+                       Graph.TIME_AXIS = {
+                               X: TIME_AXIS_X,
+                               Y: TIME_AXIS_Y,
+                               NONE: TIME_AXIS_NONE
+                       };
+
+                       prototype._newChart = function (element) {
+                               var self = this,
+                                       data = null;
+
+                               self.element.innerHTML = "";
+                               self._rebuildCache();
+                               data = self._prepareChartData();
+                               self.chart = new window.tauCharts.Chart({
+                                       data: [],
+                                       type: self.options.graph,
+                                       x: xAxis,
+                                       y: yAxis,
+                                       color: "label",
+                                       size: self.size,
+                                       split: self.split,
+                                       guide: self.guide,
+                                       dimensions: self.dimensions,
+                                       plugins: (self.options.legend) ? [window.tauCharts.api.plugins.get("legend")] : []
+                               });
+
+                               self.chart.renderTo(element);
+
+                               self._updateChart(data);
+                       };
+
+                       prototype._setChartAxis = function (identifier) {
+                               var self = this,
+                                       axisDimensions = self.dimensions[identifier],
+                                       axisType = self.options["axis" + identifier.toUpperCase() + "Type"];
+
+                               axisDimensions.type = "order";
+                               switch (axisType) {
+                                       case "time":
+                                       case "index":
+                                               axisDimensions.scale = "time";
+                                               self.guide[identifier].tickFormat = "day";
+                                               break;
+                                       case "order":
+                                               axisDimensions.scale = "ordinal";
+                                               break;
+                                       case "linear":
+                                               axisDimensions.scale = "linear";
+                                               break;
+                               }
+                       }
+
+                       prototype._init = function (element) {
+                               var self = this,
+                                       oldData = [],
+                                       guide = self.guide;
+
+                               self.options.color = (typeof self.options.color === "string") ?
+                                       self.options.color.split(",") :
+                                       self.options.color;
+                               guide.color.brewer = self.options.color;
+                               guide.x.label.text = self.options.xlabel;
+                               guide.y.label.text = self.options.ylabel;
+
+                               self._setChartAxis("x");
+                               self._setChartAxis("y");
+
+                               self.data.length = 0;
+                               // get chart data from data-value attribute
+                               if (self.options.value) {
+                                       try {
+                                               oldData = JSON.parse(self.options.value);
+                                       } catch (e) { }
+
+                                       if (oldData.length > 0) {
+                                               //self.data = self.data.concat(oldData);
+                                               oldData.forEach(function (data) {
+                                                       self._addData(data);
+                                               });
+                                               self._initialData = true;
+                                       }
+                               } else {
+                                       self._addData(0);
+                                       self._initialData = true;
+                               }
+
+                               // create chart widget
+                               self._newChart(element);
+
+                               return element;
+                       };
+
+                       prototype._build = function (element) {
+                               var self = this;
+
+                               if (!window.tauCharts) {
+                                       console.warn(addLibText);
+                                       return null;
+                               }
+
+                               self._createDivElement(element, classes.graphContainer);
+                               return element;
+                       };
+
+                       prototype._addData = function (value) {
+                               var now = Date.now(),
+                                       valueObject = {
+                                               time: now,
+                                               value: value,
+                                               cache: null
+                                       },
+                                       self = this;
+
+                               if (self._initialData) { // remove initial data
+                                       self.data = [];
+                                       self._initialData = false;
+                               }
+
+                               valueObject.cache = self._map(valueObject, self.data.length);
+                               self.data.push(valueObject);
+                       };
+
+                       prototype._map = function (valueObject, index) {
+                               var dataset = [],
+                                       value = valueObject.value,
+                                       time = valueObject.time,
+                                       timeAxis = this.options.timeAxis,
+                                       axisXType = this.options.axisXType,
+                                       groupKey = this.options.groupKey,
+                                       label,
+                                       x = 0,
+                                       y = 0;
+
+                               // Convert data to array [x, y]
+                               if (typeof value === "object") {
+                                       // if data object has "x" and "y" property
+                                       if (value.x !== undefined) {
+                                               dataset.push(value.x);
+                                               if (value.y !== undefined) {
+                                                       dataset.push(value.y);
+                                               }
+                                               if (value[groupKey] !== undefined) {
+                                                       dataset.push(value[groupKey]);
+                                               }
+                                       } else {
+                                               // data object has other keys
+                                               Object.keys(value).forEach(function (key) {
+                                                       dataset.push(value[key]);
+                                               });
+                                       }
+                               } else {
+                                       // value is single value;
+                                       dataset = [value];
+                               }
+
+                               // convert array [x, y] to object {x: x, y: y}
+                               if (dataset.length === 1) {
+                                       switch (axisXType) {
+                                               case "time":
+                                                       if (timeAxis === TIME_AXIS_X) {
+                                                               y = parseFloat(dataset[0]) || 0;
+                                                               x = time;
+                                                       } else {
+                                                               x = parseFloat(dataset[0]) || 0;
+                                                               if (timeAxis === TIME_AXIS_Y) {
+                                                                       y = time;
+                                                               }
+                                                       }
+                                                       break;
+                                               case "index":
+                                                       x = index;
+                                                       y = parseFloat(dataset[0]) || 0;
+                                                       break;
+                                       }
+                                       label = "Series 1";
+                               } else {
+                                       switch (axisXType) {
+                                               case "index":
+                                                       x = index;
+                                                       y = parseFloat(dataset[0]) || 0;
+                                                       break;
+                                               default:
+                                                       x = parseFloat(dataset[0]) || 0;
+                                                       y = parseFloat(dataset[1]) || 0;
+                                                       break;
+                                       }
+                                       label = dataset[dataset.length - 1];
+                               }
+
+                               return {
+                                       x: x,
+                                       y: y,
+                                       label: label
+                               }
+                       }
+
+                       prototype._rebuildCache = function () {
+                               var self = this;
+
+                               self.data.forEach(function (value, index) {
+                                       value.cache = self._map(value, index);
+                               });
+                       };
+
+                       prototype._prepareChartData = function () {
+                               return this.data.map(function (value) {
+                                       return value.cache;
+                               })
+                       };
+
+                       prototype._updateChart = function (data) {
+                               var self = this;
+
+                               if (self.options.mode === MODE_INTERMITTENT) {
+                                       data.length = 0;
+                               }
+
+                               self.chart.setData(data);
+
+                               self.element.setAttribute(
+                                       "data-value",
+                                       JSON.stringify(data)
+                               );
+                       };
+
+                       prototype._setOneValue = function (value) {
+                               var self = this;
+
+                               self._addData(value),
+                               self._updateChart(self._prepareChartData());
+
+                               return false;
+                       }
+
+                       prototype._setValue = function (value) {
+                               var dataset = Array.isArray(value) ? value : [value],
+                                       result = true,
+                                       self = this;
+
+                               dataset.forEach(function (val) {
+                                       if (!self._setOneValue(val) && result) {
+                                               result = false;
+                                       }
+                               });
+
+                               return result;
+                       };
+
+                       prototype._getValue = function () {
+                               return this.data;
+                       };
+
+                       prototype._createDivElement = function (
+                                       parentElement, className) {
+                               var newElement = document.createElement("div");
+
+                               newElement.classList.add(className);
+
+                               parentElement.appendChild(newElement);
+                       };
+
+                       prototype._refresh = function () {
+                               var self = this;
+
+                               self.guide = {
+                                       color: {
+                                               brewer: (typeof self.options.color === "string") ?
+                                                       self.options.color.split(",") :
+                                                       self.options.color
+                                       },
+                                       x: {
+                                               label: {
+                                                       text: self.options.xlabel
+                                               }
+                                       },
+                                       y: {
+                                               label: {
+                                                       text: self.options.ylabel
+                                               }
+                                       }
+                               };
+                               self._newChart(self.element);
+
+                       }
+
+                       ns.widget.core.Graph = Graph;
+
+                       ns.engine.defineWidget(
+                               "Graph",
+                               ".ui-graph", [],
+                               Graph,
+                               "core"
+                       );
+                       }(window, window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Popup
+ * Popup component supports 2 pop-ups: the position-to-window pop-up (like a system pop-up), and the context pop-up.
+ *
+ * @since 2.0
+ * @author Hyunkook Cho <hk0713.cho@samsung.com>
+ * @class ns.widget.core.Popup
+ * @component-selector .ui-popup, [data-role]="popup"
+ * @extends ns.widget.core.BaseWidget
+ */
+(function () {
+       "use strict";
+                               /**
+                        * Alias for {@link ns.widget.BaseWidget}
+                        * @property {Function} BaseWidget
+                        * @member ns.widget.core.Popup
+                        * @private
+                        */
+                       var BaseWidget = ns.widget.BaseWidget,
+                               /**
+                                * Alias for class ns.engine
+                                * @property {ns.engine} engine
+                                * @member ns.widget.core.Popup
+                                * @private
+                                */
+                               engine = ns.engine,
+                               /**
+                                * Alias for class ns.util.object
+                                * @property {Object} objectUtils
+                                * @member ns.widget.core.Popup
+                                * @private
+                                */
+                               objectUtils = ns.util.object,
+                               /**
+                                * Alias for class ns.util.deferred
+                                * @property {Object} UtilDeferred
+                                * @member ns.widget.core.Popup
+                                * @private
+                                */
+                               UtilDeferred = ns.util.deferred,
+                               /**
+                                * Alias for class ns.util.selectors
+                                * @property {Object} utilSelector
+                                * @member ns.widget.core.Popup
+                                * @private
+                                */
+                               utilSelector = ns.util.selectors,
+                               /**
+                                * Alias for class ns.event
+                                * @property {Object} eventUtils
+                                * @member ns.widget.core.Popup
+                                * @private
+                                */
+                               eventUtils = ns.event,
+                               /**
+                                * Alias for Router, loose requirement
+                                * @property {ns.router.Router} Router
+                                * @member ns.widget.core.Popup
+                                * @private
+                                */
+                               Router = ns.router && ns.router.Router,
+
+                               /**
+                                * Alias for BaseKeyBoard Support
+                                * @property {ns.widget.core.BaseKeyboardSupport} BaseKeyboardSupport
+                                * @member ns.widget.core.Popup
+                                * @private
+                                */
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+
+                               /**
+                                * Alias for class ns.widget.core.Page
+                                * @property {ns.router.Router} Router
+                                * @member ns.widget.core.Popup
+                                * @private
+                                */
+                               Page = ns.widget.core.Page,
+
+                               POPUP_SELECTOR = "[data-role='popup'], .ui-popup",
+
+                               /**
+                                * Object with default options
+                                * @property {Object} defaults
+                                * @property {string} [options.transition="none"] Sets the default transition for the popup.
+                                * @property {string} [options.positionTo="window"] Sets the element relative to which the popup will be centered.
+                                * @property {boolean} [options.dismissible=true] Sets whether to close popup when a popup is open to support the back button.
+                                * @property {boolean} [options.overlay=true] Sets whether to show overlay when a popup is open.
+                                * @property {boolean|string} [options.header=false] Sets content of header.
+                                * @property {boolean|string} [options.footer=false] Sets content of footer.
+                                * @property {string} [options.content=null] Sets content of popup.
+                                * @property {string} [options.overlayClass=""] Sets the custom class for the popup background, which covers the entire window.
+                                * @property {string} [options.closeLinkSelector="a[data-rel='back']"] Sets selector for close buttons in popup.
+                                * @property {boolean} [options.history=true] Sets whether to alter the url when a popup is open to support the back button.
+                                * @member ns.widget.core.Popup
+                                * @static
+                                */
+                               defaults = {
+                                       transition: "none",
+                                       dismissible: true,
+                                       overlay: true,
+                                       header: false,
+                                       footer: false,
+                                       content: null,
+                                       overlayClass: "",
+                                       closeLinkSelector: "[data-rel='back']",
+                                       history: null,
+                                       closeAfter: null
+                               },
+                               states = {
+                                       DURING_OPENING: 0,
+                                       OPENED: 1,
+                                       DURING_CLOSING: 2,
+                                       CLOSED: 3
+                               },
+                               CLASSES_PREFIX = "ui-popup",
+                               /**
+                                * Dictionary for popup related css class names
+                                * @property {Object} classes
+                                * @member ns.widget.core.Popup
+                                * @static
+                                */
+                               /**
+                                * Toast style of popup with graphic
+                                * @style ui-popup-toast-graphic
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                               classes = {
+                               /**
+                                * Style for normal popup widget
+                                * @style ui-popup
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                                       popup: CLASSES_PREFIX,
+                               /**
+                                * Set style for active popup widget
+                                * @style ui-popup-active
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                                       active: CLASSES_PREFIX + "-active",
+                               /**
+                                * Set style for overlay popup widget
+                                * @style ui-popup-overlay
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                                       overlay: CLASSES_PREFIX + "-overlay",
+                               /**
+                                * Set header for popup widget
+                                * @style ui-popup-header
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                                       header: CLASSES_PREFIX + "-header",
+                               /**
+                                * Set footer for popup widget
+                                * @style ui-popup-footer
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                                       footer: CLASSES_PREFIX + "-footer",
+                               /**
+                                * Set content for popup widget
+                                * @style ui-popup-content
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                                       content: CLASSES_PREFIX + "-content",
+                               /**
+                                * Style for wrapper of popup widget
+                                * @style ui-popup-wrapper
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                                       wrapper: CLASSES_PREFIX + "-wrapper",
+                               /**
+                                * Toast style of popup
+                                * @style ui-popup-toast
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                                       toast: CLASSES_PREFIX + "-toast",
+                               /**
+                                * Small toast style of popup
+                                * @style ui-popup-toast-small
+                                * @member ns.widget.core.Popup
+                                * @wearable
+                                */
+                                       toastSmall: CLASSES_PREFIX + "-toast-small",
+                                       build: "ui-build",
+                                       overlayShown: CLASSES_PREFIX + "-overlay-shown"
+                               },
+                               /**
+                                * Dictionary for popup related selectors
+                                * @property {Object} selectors
+                                * @member ns.widget.core.Popup
+                                * @static
+                                */
+                               selectors = {
+                                       header: "." + classes.header,
+                                       content: "." + classes.content,
+                                       footer: "." + classes.footer
+                               },
+                               EVENTS_PREFIX = "popup",
+                               /**
+                                * Dictionary for popup related events
+                                * @property {Object} events
+                                * @member ns.widget.core.Popup
+                                * @static
+                                */
+                               events = {
+                                       /**
+                                        * Triggered when the popup has been created in the DOM (via ajax or other) but before all widgets have had an opportunity to enhance the contained markup.
+                                        * @event popupshow
+                                        * @member ns.widget.core.Popup
+                                        */
+                                       show: EVENTS_PREFIX + "show",
+                                       /**
+                                        * Triggered on the popup after the transition animation has completed.
+                                        * @event popuphide
+                                        * @member ns.widget.core.Popup
+                                        */
+                                       hide: EVENTS_PREFIX + "hide",
+                                       /**
+                                        * Triggered on the popup we are transitioning to, before the actual transition animation is kicked off.
+                                        * @event popupbeforeshow
+                                        * @member ns.widget.core.Popup
+                                        */
+                                       /* eslint-disable camelcase */
+                                       // we can't change this in this moment because this is part of API
+                                       before_show: EVENTS_PREFIX + "beforeshow",
+                                       /**
+                                        * Triggered on the popup we are transitioning to, before the actual transition animation is kicked off, animation has started.
+                                        * @event popuptransitionstart
+                                        * @member ns.widget.core.Popup
+                                        */
+                                       transition_start: EVENTS_PREFIX + "transitionstart",
+                                       /**
+                                        * Triggered on the popup we are transitioning away from, before the actual transition animation is kicked off.
+                                        * @event popupbeforehide
+                                        * @member ns.widget.core.Popup
+                                        */
+                                       before_hide: EVENTS_PREFIX + "beforehide"
+                                       /* eslint-enable camelcase */
+                               },
+
+                               Popup = function () {
+                                       var self = this,
+                                               ui = {};
+
+                                       self.selectors = selectors;
+                                       self.options = objectUtils.merge({}, Popup.defaults);
+                                       self.storedOptions = null;
+                                       /**
+                                        * Popup state flag
+                                        * @property {0|1|2|3} [state=null]
+                                        * @member ns.widget.core.Popup
+                                        * @private
+                                        */
+                                       self.state = states.CLOSED;
+
+                                       ui.overlay = null;
+                                       ui.header = null;
+                                       ui.footer = null;
+                                       ui.content = null;
+                                       ui.container = null;
+                                       ui.wrapper = null;
+                                       self._ui = ui;
+
+                                       // event callbacks
+                                       self._callbacks = {};
+                               },
+
+                               prototype = new BaseWidget();
+
+                       Popup.classes = classes;
+                       Popup.events = events;
+                       Popup.defaults = defaults;
+                       Popup.selector = POPUP_SELECTOR;
+
+                       /**
+                        * Build the content of popup
+                        * @method _buildContent
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._buildContent = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       selectors = self.selectors,
+                                       options = self.options,
+                                       content = ui.content || element.querySelector(selectors.content),
+                                       footer = ui.footer || element.querySelector(selectors.footer),
+                                       elementChildren = [].slice.call(element.childNodes),
+                                       elementChildrenLength = elementChildren.length,
+                                       i,
+                                       node;
+
+                               if (!content) {
+                                       content = document.createElement("div");
+                                       content.className = classes.content;
+                                       for (i = 0; i < elementChildrenLength; ++i) {
+                                               node = elementChildren[i];
+                                               if (node !== ui.footer && node !== ui.header) {
+                                                       content.appendChild(node);
+                                               }
+                                       }
+                                       if (typeof options.content === "string") {
+                                               content.innerHTML = options.content;
+                                       }
+                                       element.insertBefore(content, footer);
+                               }
+                               content.classList.add(classes.content);
+                               ui.content = content;
+                       };
+
+                       /**
+                        * Build the header of popup
+                        * @method _buildHeader
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._buildHeader = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       selectors = self.selectors,
+                                       content = ui.content || element.querySelector(selectors.content),
+                                       header = ui.header || element.querySelector(selectors.header);
+
+                               if (!header && options.header !== false) {
+                                       header = document.createElement("div");
+                                       header.className = classes.header;
+                                       if (typeof options.header !== "boolean") {
+                                               header.innerHTML = options.header;
+                                       }
+                                       element.insertBefore(header, content);
+                               }
+                               if (header) {
+                                       header.classList.add(classes.header);
+                               }
+                               ui.header = header;
+                       };
+
+                       /**
+                        * Set the header of popup.
+                        * This function is called by function "option" when the option "header" is set.
+                        * @method _setHeader
+                        * @param {HTMLElement} element
+                        * @param {boolean|string} value
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._setHeader = function (element, value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       header = ui.header;
+
+                               if (header) {
+                                       header.parentNode.removeChild(header);
+                                       ui.header = null;
+                               }
+                               self.options.header = value;
+                               self._buildHeader(ui.container);
+                       };
+
+                       /**
+                        * Build the footer of popup
+                        * @method _buildFooter
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._buildFooter = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       footer = ui.footer || element.querySelector(self.selectors.footer);
+
+                               if (!footer && options.footer !== false) {
+                                       footer = document.createElement("div");
+                                       footer.className = classes.footer;
+                                       if (typeof options.footer !== "boolean") {
+                                               footer.innerHTML = options.footer;
+                                       }
+                                       element.appendChild(footer);
+                               }
+                               if (footer) {
+                                       footer.classList.add(classes.footer);
+                               }
+                               ui.footer = footer;
+                       };
+
+                       /**
+                        * Set the footer of popup.
+                        * This function is called by function "option" when the option "footer" is set.
+                        * @method _setFooter
+                        * @param {HTMLElement} element
+                        * @param {boolean|string} value
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._setFooter = function (element, value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       footer = ui.footer;
+
+                               if (footer) {
+                                       footer.parentNode.removeChild(footer);
+                                       ui.footer = null;
+                               }
+                               self.options.footer = value;
+                               self._buildFooter(ui.container);
+                       };
+
+                       /**
+                        * Build structure of Popup widget
+                        * @method _build
+                        * @param {HTMLElement} element of popup
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.Popup
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       wrapper,
+                                       child = element.firstChild,
+                                       elementClassList = element.classList;
+
+                               // set class for element
+                               elementClassList.add(classes.popup);
+
+                               if (elementClassList.contains(classes.toastSmall)) {
+                                       elementClassList.add(classes.toast);
+                               }
+
+                               // create wrapper
+                               wrapper = document.createElement("div");
+                               wrapper.classList.add(classes.wrapper);
+                               ui.wrapper = wrapper;
+                               ui.container = wrapper;
+                               // move all children to wrapper
+                               while (child) {
+                                       wrapper.appendChild(child);
+                                       child = element.firstChild;
+                               }
+                               // add wrapper and arrow to popup element
+                               element.appendChild(wrapper);
+
+                               // build header, footer and content
+                               self._buildHeader(ui.container);
+                               self._buildFooter(ui.container);
+                               self._buildContent(ui.container);
+
+                               // set overlay
+                               self._setOverlay(element, self.options.overlay);
+
+                               return element;
+                       };
+
+                       /**
+                        * Set overlay
+                        * @method _setOverlay
+                        * @param {HTMLElement} element
+                        * @param {boolean} enable
+                        * @protected
+                        * @member ns.widget.Popup
+                        */
+                       prototype._setOverlay = function (element, enable) {
+                               var self = this,
+                                       overlayClass = self.options.overlayClass,
+                                       ui = self._ui,
+                                       overlay = ui.overlay;
+
+                               // if this popup is not connected with slider,
+                               // we create overlay, which is invisible when
+                               // the value of option overlay is false
+                               /// @TODO: get class from widget
+                               if (!element.classList.contains("ui-slider-popup") && !element.classList.contains(classes.toast)) {
+                                       // create overlay
+                                       if (!overlay) {
+                                               overlay = document.createElement("div");
+
+                                               if (element.parentNode) {
+                                                       element.parentNode.insertBefore(overlay, element);
+                                               } else {
+                                                       ns.warn("Popup is creating on element outside DOM");
+                                               }
+
+                                               ui.overlay = overlay;
+                                       }
+                                       overlay.className = classes.overlay + (overlayClass ? " " + overlayClass : "");
+                                       if (enable) {
+                                               overlay.style.opacity = "";
+                                       } else {
+                                               // if option is set on "false", the overlay is not visible
+                                               overlay.style.opacity = 0;
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Returns the state of the popup
+                        * @method _isActive
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._isActive = function () {
+                               var state = this.state;
+
+                               return state === states.DURING_OPENING || state === states.OPENED;
+                       };
+
+                       /**
+                        * Returns true if popup is already opened and visible
+                        * @method _isActive
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._isOpened = function () {
+                               return this.state === states.OPENED;
+                       };
+
+                       /**
+                        * Init widget
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       selectors = self.selectors,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       elementClassList = self.element.classList;
+
+                               ui.header = ui.header || element.querySelector(selectors.header);
+                               ui.footer = ui.footer || element.querySelector(selectors.footer);
+                               ui.content = ui.content || element.querySelector(selectors.content);
+                               ui.wrapper = ui.wrapper || element.querySelector("." + classes.wrapper);
+                               ui.container = ui.wrapper || element;
+
+                               ui.page = utilSelector.getClosestByClass(element, Page.classes.uiPage) || window;
+                               ui.pageContent = (typeof ui.page.querySelector === "function") ?
+                                       ui.page.querySelector("." + Page.classes.uiContent) : null;
+
+                               if (elementClassList.contains(classes.toast)) {
+                                       options.closeAfter = options.closeAfter || 2000;
+                               }
+                               // if option history is not set in constructor or in HTML
+                               if (options.history === null) {
+                                       // for toast we set false for other true
+                                       options.history = !elementClassList.contains(classes.toast);
+                               }
+                       };
+
+                       /**
+                        * Set the state of the popup
+                        * @method _setActive
+                        * @param {boolean} active
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._setActive = function (active) {
+                               var self = this,
+                                       activeClass = classes.active,
+                                       elementClassList = self.element.classList,
+                                       route = Router && Router.getInstance().getRoute("popup"),
+                                       options;
+
+                               // NOTE: popup's options object is stored in window.history at the router module,
+                               // and this window.history can't store DOM element object.
+                               options = objectUtils.merge({}, self.options, {positionTo: null, link: null});
+
+                               // set state of popup and add proper class
+                               if (active) {
+                                       // set global variable
+                                       if (route) {
+                                               route.setActive(self, options);
+                                       }
+                                       // add proper class
+                                       elementClassList.add(activeClass);
+                                       // set state of popup   358
+                                       self.state = states.OPENED;
+                               } else {
+                                       // no popup is opened, so set global variable on "null"
+                                       if (route) {
+                                               route.setActive(null, options);
+                                       }
+                                       // remove proper class
+                                       elementClassList.remove(activeClass);
+                                       // set state of popup
+                                       self.state = states.CLOSED;
+                               }
+
+                               if (self._ui.content.scrollHeight > self._ui.content.clientHeight) {
+                                       self._ui.footer.classList.add("bottomDivider");
+                               }
+                       };
+
+                       /**
+                        * Scroll event
+                        * @method _onScroll
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._onScroll = function () {
+                               var self = this,
+                                       content = self._ui.content;
+
+                               if (content.scrollTop === 0) {
+                                       self._ui.header.classList.remove("topDivider");
+                                       self._ui.footer.classList.add("bottomDivider");
+                               } else if (content.scrollHeight - content.clientHeight === content.scrollTop) {
+                                       self._ui.header.classList.add("topDivider");
+                                       self._ui.footer.classList.remove("bottomDivider");
+                               } else {
+                                       self._ui.header.classList.add("topDivider");
+                                       self._ui.footer.classList.add("bottomDivider");
+                               }
+                       }
+
+                       /**
+                        * Bind events
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this;
+
+                               eventUtils.on(self._ui.page, "pagebeforehide", self, false);
+                               eventUtils.on(window, "resize", self, false);
+                               eventUtils.on(document, "vclick", self, false);
+                               eventUtils.on(self._ui.content, "scroll", self, false);
+                       };
+
+
+                       /**
+                        * Unbind events
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._unbindEvents = function () {
+                               var self = this;
+
+                               eventUtils.off(self._ui.page, "pagebeforehide", self, false);
+                               eventUtils.off(window, "resize", self, false);
+                               eventUtils.off(document, "vclick", self, false);
+                               eventUtils.off(self._ui.content, "scroll", self, false);
+                       };
+
+                       /**
+                        * Layouting popup structure
+                        * @method layout
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._layout = function () {
+                       };
+
+                       /**
+                        * Open the popup
+                        * @method open
+                        * @param {Object=} [options]
+                        * @param {string=} [options.transition] options.transition
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype.open = function (options) {
+                               var self = this,
+                                       newOptions,
+                                       onClose = self.close.bind(self);
+
+
+                               if (!self._isActive()) {
+                                       /*
+                                        * Some passed options on open need to be kept until popup closing.
+                                        * For example, transition parameter should be kept for closing animation.
+                                        * On the other hand, fromHashChange or x, y parameter should be removed.
+                                        * We store options and restore them on popup closing.
+                                        */
+                                       self._storeOpenOptions(options);
+
+                                       newOptions = objectUtils.merge(self.options, options);
+                                       if (!newOptions.dismissible) {
+                                               ns.router.Router.getInstance().lock();
+                                       }
+
+
+                                       if (newOptions.closeAfter > 0) {
+                                               if (self.element.classList.contains(classes.toast)) {
+                                                       newOptions.transition = "fade";
+                                               }
+                                               self._show(newOptions);
+
+                                               self._closeTimeout = window.setTimeout(onClose, newOptions.closeAfter);
+                                       } else {
+                                               self._show(newOptions);
+                                       }
+                               }
+                       };
+
+
+                       /**
+                        * Close the popup
+                        * @method close
+                        * @param {Object=} [options]
+                        * @param {string=} [options.transition]
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype.close = function (options) {
+                               var self = this,
+                                       newOptions = objectUtils.merge(self.options, options);
+
+                               if (self._isActive()) {
+                                       clearTimeout(self._closeTimeout);
+                                       if (!newOptions.dismissible) {
+                                               ns.router.Router.getInstance().unlock();
+                                       }
+                                       self._hide(newOptions);
+                               }
+                       };
+
+                       /**
+                        * Store Open options.
+                        * @method _storeOpenOptions
+                        * @param {Object} options
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._storeOpenOptions = function (options) {
+                               var self = this,
+                                       oldOptions = self.options,
+                                       storedOptions = {},
+                                       key;
+
+                               for (key in options) {
+                                       if (options.hasOwnProperty(key)) {
+                                               storedOptions[key] = oldOptions[key];
+                                       }
+                               }
+
+                               self.storedOptions = storedOptions;
+                       };
+
+                       /**
+                        * Restore Open options and remove some unnecessary ones.
+                        * @method _storeOpenOptions
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._restoreOpenOptions = function () {
+                               var self = this,
+                                       options = self.options,
+                                       propertiesToRemove = ["x", "y", "fromHashChange"];
+
+                               // we restore opening values of all options
+                               options = objectUtils.merge(options, self.storedOptions);
+                               // and remove all values which should not be stored
+                               objectUtils.removeProperties(options, propertiesToRemove);
+                       };
+
+                       /**
+                        * Show popup.
+                        * @method _show
+                        * @param {Object} options
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._show = function (options) {
+                               var self = this,
+                                       transitionOptions = objectUtils.merge({}, options),
+                                       overlay = self._ui.overlay,
+                                       pageContent = self._ui.pageContent;
+
+                               // set layout
+                               self._layout(self.element);
+
+                               // change state of popup
+                               self.state = states.DURING_OPENING;
+                               // set transition
+                               transitionOptions.ext = " in ";
+
+                               self.trigger(events.before_show);
+                               // show overlay
+                               if (overlay) {
+                                       overlay.classList.toggle(classes.overlayShown, true);
+                               }
+
+                               // disable page pointer events
+                               if (pageContent) {
+                                       pageContent.classList.toggle(Page.classes.uiContentUnderPopup, true);
+                               }
+
+                               // start opening animation
+                               self._transition(transitionOptions, self._onShow.bind(self));
+
+                               // animation has started
+                               self.trigger(events.transition_start);
+                       };
+
+                       /**
+                        * Show popup
+                        * @method _onShow
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._onShow = function () {
+                               var self = this;
+
+                               self._setActive(true);
+                               if (self.isKeyboardSupport) {
+                                       self.disableFocusableElements(this._ui.page);
+                                       self.enableDisabledFocusableElements(this.element);
+                                       BaseKeyboardSupport.focusElement(this.element);
+                               }
+                               self.trigger(events.show);
+                       };
+
+                       /**
+                        * Hide popup
+                        * @method _hide
+                        * @param {Object} options
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._hide = function (options) {
+                               var self = this,
+                                       isOpened = self._isOpened(),
+                                       callbacks = self._callbacks,
+                                       pageContent = self._ui.pageContent;
+
+                               // change state of popup
+                               self.state = states.DURING_CLOSING;
+
+                               self.trigger(events.before_hide);
+
+                               // enable page pointer events
+                               if (pageContent) {
+                                       pageContent.classList.toggle(Page.classes.uiContentUnderPopup, false);
+                               }
+
+                               if (isOpened) {
+                                       // popup is opened, so we start closing animation
+                                       options.ext = " out ";
+                                       self._transition(options, self._onHide.bind(self));
+                               } else {
+                                       // popup is active, but not opened yet (DURING_OPENING), so
+                                       // we stop opening animation
+                                       if (callbacks.transitionDeferred) {
+                                               callbacks.transitionDeferred.reject();
+                                       }
+                                       if (callbacks.animationEnd) {
+                                               callbacks.animationEnd();
+                                       }
+                                       // and set popup as inactive
+                                       self._onHide();
+                               }
+                       };
+
+                       /**
+                        * Hide popup
+                        * @method _onHide
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._onHide = function () {
+                               var self = this,
+                                       overlay = self._ui.overlay;
+
+                               self._setActive(false);
+
+                               if (self.isKeyboardSupport) {
+                                       self.enableDisabledFocusableElements(this._ui.page);
+                               }
+
+                               if (overlay) {
+                                       overlay.classList.toggle(classes.overlayShown, false);
+                               }
+                               self._restoreOpenOptions();
+                               self.trigger(events.hide);
+                       };
+
+                       /**
+                        * Handle events
+                        * @method handleEvent
+                        * @param {Event} event
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this,
+                                       router = ns.router.Router.getInstance();
+
+                               switch (event.type) {
+                                       case "pagebeforehide":
+                                               // we need close active popup if exists
+                                               router.close(null, {transition: "none", rel: "popup"});
+                                               break;
+                                       case "resize":
+                                               self._onResize(event);
+                                               break;
+                                       case "vclick":
+                                               if (event.target === self._ui.overlay) {
+                                                       self._onClickOverlay(event);
+                                               }
+                                               break;
+                                       case "scroll":
+                                               self._onScroll(event);
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * Refresh structure
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._refresh = function () {
+                               var self = this;
+
+                               self._setOverlay(self.element, self.options.overlay);
+                       };
+
+                       /**
+                        * Callback function fires after clicking on overlay.
+                        * @method _onClickOverlay
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._onClickOverlay = function (event) {
+                               var options = this.options;
+
+                               event.preventDefault();
+                               event.stopPropagation();
+
+                               if (options.dismissible) {
+                                       ns.router.Router.getInstance().close(null, {rel: "popup"});
+                               }
+                       };
+
+                       /**
+                        * Callback function fires on resizing
+                        * @method _onResize
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._onResize = function () {
+                               if (this._isOpened()) {
+                                       this._refresh();
+                               }
+                       };
+
+                       function clearAnimation(self, transitionClass, deferred) {
+                               var element = self.element,
+                                       elementClassList = element.classList,
+                                       overlay = self._ui.overlay,
+                                       animationEndCallback = self._callbacks.animationEnd;
+
+                               // remove callbacks on animation events
+                               element.removeEventListener("animationend", animationEndCallback, false);
+                               element.removeEventListener("webkitAnimationEnd", animationEndCallback, false);
+                               element.removeEventListener("mozAnimationEnd", animationEndCallback, false);
+                               element.removeEventListener("oAnimationEnd", animationEndCallback, false);
+                               element.removeEventListener("msAnimationEnd", animationEndCallback, false);
+
+                               // clear classes
+                               transitionClass.split(" ").forEach(function (currentClass) {
+                                       currentClass = currentClass.trim();
+                                       if (currentClass.length > 0) {
+                                               elementClassList.remove(currentClass);
+                                               if (overlay) {
+                                                       overlay.classList.remove(currentClass);
+                                               }
+                                       }
+                               });
+                               if (deferred.state() === "pending") {
+                                       // we resolve only pending (not rejected) deferred
+                                       deferred.resolve();
+                               }
+                       }
+
+                       function setTransitionDeferred(self, resolve) {
+                               var deferred = new UtilDeferred();
+
+                               deferred.then(function () {
+                                       if (deferred === self._callbacks.transitionDeferred) {
+                                               resolve();
+                                       }
+                               });
+
+                               self._callbacks.transitionDeferred = deferred;
+                               return deferred;
+                       }
+
+                       /**
+                        * Animate popup opening/closing
+                        * @method _transition
+                        * @protected
+                        * @param {Object} [options]
+                        * @param {string=} [options.transition]
+                        * @param {string=} [options.ext]
+                        * @param {?Function} [resolve]
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._transition = function (options, resolve) {
+                               var self = this,
+                                       transition = options.transition || self.options.transition || "none",
+                                       transitionClass = transition + options.ext,
+                                       element = self.element,
+                                       elementClassList = element.classList,
+                                       overlayClassList,
+                                       deferred,
+                                       animationEndCallback;
+
+                               if (self._ui.overlay) {
+                                       overlayClassList = self._ui.overlay.classList;
+                               }
+
+                               deferred = setTransitionDeferred(self, resolve);
+
+                               if (transition !== "none") {
+                                       // set animationEnd callback
+                                       animationEndCallback = clearAnimation.bind(null, self, transitionClass, deferred);
+                                       self._callbacks.animationEnd = animationEndCallback;
+
+                                       // add animation callbacks
+                                       element.addEventListener("animationend", animationEndCallback, false);
+                                       element.addEventListener("webkitAnimationEnd", animationEndCallback, false);
+                                       element.addEventListener("mozAnimationEnd", animationEndCallback, false);
+                                       element.addEventListener("oAnimationEnd", animationEndCallback, false);
+                                       element.addEventListener("msAnimationEnd", animationEndCallback, false);
+                                       // add transition classes
+                                       transitionClass.split(" ").forEach(function (currentClass) {
+                                               currentClass = currentClass.trim();
+                                               if (currentClass.length > 0) {
+                                                       elementClassList.add(currentClass);
+
+                                                       if (overlayClassList) {
+                                                               overlayClassList.add(currentClass);
+                                                       }
+
+                                               }
+                                       });
+                               } else {
+                                       if (!ns.getConfig("noAsync", false)) {
+                                               window.setTimeout(deferred.resolve, 0);
+                                       } else {
+                                               deferred.resolve();
+                                       }
+                               }
+                               return deferred;
+                       };
+
+                       /**
+                        * Destroy popup
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       element = self.element,
+                                       ui = self._ui,
+                                       wrapper = ui.wrapper,
+                                       child;
+
+                               if (wrapper) {
+                                       // restore all children from wrapper
+                                       child = wrapper.firstChild;
+                                       while (child) {
+                                               element.appendChild(child);
+                                               child = wrapper.firstChild;
+                                       }
+
+                                       if (wrapper.parentNode) {
+                                               wrapper.parentNode.removeChild(wrapper);
+                                       }
+                               }
+
+                               self._unbindEvents(element);
+                               self._setOverlay(element, false);
+
+                               ui.wrapper = null;
+                       };
+
+                       Popup.prototype = prototype;
+
+                       ns.widget.core.Popup = Popup;
+
+                       engine.defineWidget(
+                               "Popup",
+                               POPUP_SELECTOR,
+                               [
+                                       "open",
+                                       "close",
+                                       "reposition"
+                               ],
+                               Popup,
+                               "core"
+                       );
+                       }());
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+
+/**
+ * # Popup Widget
+ * Shows a pop-up window.
+ *
+ * The popup widget shows in the middle of the screen a list of items in a pop-up window.
+ * It automatically optimizes the pop-up window size within the screen. The following table
+ * describes the supported popup classes.
+ *
+ * ## Default selectors
+ * All elements with class *ui-popup* will be become popup widgets.
+ *
+ * The pop-up window can contain a header, content, and footer area like the page element.
+ *
+ * To open a pop-up window from a link, use the data-rel attribute in HTML markup as in the
+ * following code:
+ *
+ *      @example
+ *      <a href="#popup" class="ui-btn" data-rel="popup">Open popup when clicking this element.</a>
+ *
+ * The following table shows examples of various types of popups.
+ *
+ * The popup contains header, content and footer area
+ *
+ * ###HTML Examples
+ *
+ * #### Basic popup with header, content, footer
+ *
+ *        @example
+ *        <div class="ui-page">
+ *            <div class="ui-popup">
+ *                <div class="ui-popup-header">Power saving mode</div>
+ *                <div class="ui-popup-content">
+ *                    Turning on Power
+ *                    saving mode will
+ *                    limit the maximum
+ *                    per
+ *                </div>
+ *                <div class="ui-popup-footer">
+ *                    <button id="cancel" class="ui-btn">Cancel</button>
+ *                </div>
+ *            </div>
+ *        </div>
+ *
+ * #### Popup with 2 buttons in the footer
+ *
+ *      @example
+ *         <div id="2btnPopup" class="ui-popup">
+ *             <div class="ui-popup-header">Delete</div>
+ *             <div class="ui-popup-content">
+ *                 Delete the image?
+ *             </div>
+ *             <div class="ui-popup-footer ui-grid-col-2">
+ *                 <button id="2btnPopup-cancel" class="ui-btn">Cancel</button>
+ *                 <button id="2btnPopup-ok" class="ui-btn">OK</button>
+ *             </div>
+ *         </div>
+ *
+ * #### Popup with checkbox/radio
+ *
+ * If you want make popup with list checkbox(or radio) just include checkbox (radio) to popup and
+ * add class *ui-popup-checkbox-label* to popup element.
+ *
+ *        @example
+ *         <div id="listBoxPopup" class="ui-popup">
+ *             <div class="ui-popup-header">When?</div>
+ *             <div class="ui-popup-content" style="height:243px; overflow-y:scroll">
+ *                 <ul class="ui-listview">
+ *                     <li>
+ *                         <label for="check-1" class="ui-popup-checkbox-label">Yesterday</label>
+ *                         <input type="checkbox" name="checkSet" id="check-1" />
+ *                     </li>
+ *                     <li>
+ *                         <label for="check-2" class="ui-popup-checkbox-label">Today</label>
+ *                         <input type="checkbox" name="checkSet" id="check-2" />
+ *                     </li>
+ *                     <li>
+ *                         <label for="check-3" class="ui-popup-checkbox-label">Tomorrow</label>
+ *                         <input type="checkbox" name="checkSet" id="check-3" />
+ *                     </li>
+ *                 </ul>
+ *                 <ul class="ui-listview">
+ *                     <li>
+ *                         <label for="radio-1" class="ui-popup-radio-label">Mandatory</label>
+ *                         <input type="radio" name="radioSet" id="radio-1" />
+ *                     </li>
+ *                     <li>
+ *                         <label for="radio-2" class="ui-popup-radio-label">Optional</label>
+ *                         <input type="radio" name="radioSet" id="radio-2" />
+ *                     </li>
+ *                 </ul>
+ *             </div>
+ *             <div class="ui-popup-footer">
+ *                 <button id="listBoxPopup-close" class="ui-btn">Close</button>
+ *             </div>
+ *         </div>
+ *     </div>
+ *
+ * #### Popup with no header and footer
+ *
+ *      @example
+ *         <div id="listNoTitleNoBtnPopup" class="ui-popup">
+ *             <div class="ui-popup-content" style="height:294px; overflow-y:scroll">
+ *                 <ul class="ui-listview">
+ *                     <li><a href="">Ringtones 1</a></li>
+ *                     <li><a href="">Ringtones 2</a></li>
+ *                     <li><a href="">Ringtones 3</a></li>
+ *                 </ul>
+ *             </div>
+ *         </div>
+ *
+ * #### Toast popup
+ *
+ *      @example
+ *         <div id="PopupToast" class="ui-popup ui-popup-toast">
+ *             <div class="ui-popup-content">Saving contacts to sim on Samsung</div>
+ *         </div>
+ *
+ * ### Create Option popup
+ *
+ * Popup inherits value of option positionTo from property data-position-to set in link.
+ *
+ *        @example
+ *        <!--definition of link, which opens popup and sets its position-->
+ *        <a href="#popupOptionText" data-rel="popup"  data-position-to="origin">Text</a>
+ *        <!--definition of popup, which inherits property position from link-->
+ *        <div id="popupOptionText" class="ui-popup">
+ *            <div class="ui-popup-content">
+ *                <ul class="ui-listview">
+ *                <li><a href="#">Option 1</a></li>
+ *                <li><a href="#">Option 2</a></li>
+ *                <li><a href="#">Option 3</a></li>
+ *                <li><a href="#">Option 4</a></li>
+ *                </ul>
+ *            </div>
+ *        </div>
+ *
+ * ### Opening and closing popup
+ *
+ * To open popup from "a" link using html markup, use the following code:
+ *
+ *        @example
+ *      <div class="ui-page">
+ *          <header class="ui-header">
+ *              <h2 class="ui-title">Call menu</h2>
+ *          </header>
+ *          <div class="ui-content">
+ *              <a href="#popup" class="ui-btn" data-rel="popup" >Open Popup</a>
+ *          </div>
+ *
+ *          <div id="popup" class="ui-popup">
+ *               <div class="ui-popup-header">Power saving mode</div>
+ *                   <div class="ui-popup-content">
+ *                       Turning on Power
+ *                       saving mode will
+ *                       limit the maximum
+ *                       per
+ *                   </div>
+ *               <div class="ui-popup-footer">
+ *               <button id="cancel" class="ui-btn">Cancel</button>
+ *           </div>
+ *       </div>
+ *
+ *  To open the popup widget from JavaScript use method *tau.openPopup(to)*
+ *
+ *          @example
+ *          tau.openPopup("popup")
+ *
+ *  To close the popup widget from JavaScript use method *tau.openPopup(to)*
+ *
+ *          @example
+ *          tau.closePopup("popup")
+ *
+ * To find the currently active popup, use the ui-popup-active class.
+ *
+ * To bind the popup to a button, use the following code:
+ *
+ *      @example
+ *         <!--HTML code-->
+ *         <div id="1btnPopup" class="ui-popup">
+ *             <div class="ui-popup-header">Power saving mode</div>
+ *             <div class="ui-popup-content">
+ *             </div>
+ *             <div class="ui-popup-footer">
+ *                 <button id="1btnPopup-cancel" class="ui-btn">Cancel</button>
+ *             </div>
+ *         </div>
+ *         <script>
+ *             // Popup opens with button click
+ *             var button = document.getElementById("button");
+ *             button.addEventListener("click", function() {
+ *                 tau.openPopup("#1btnPopup");
+ *             });
+ *
+ *             // Popup closes with Cancel button click
+ *             document.getElementById("1btnPopup-cancel").addEventListener("click", function() {
+ *                 tau.closePopup();
+ *             });
+ *         </script>
+ *
+ * ## Manual constructor
+ * For manual creation of popup widget you can use constructor of widget from **tau** namespace:
+ *
+ *        @example
+ *        var popupElement = document.getElementById("popup"),
+ *            popup = tau.widget.popup(buttonElement);
+ *
+ * Constructor has one require parameter **element** which are base **HTMLElement** to create
+ * widget. We recommend get this element by method *document.getElementById*.
+ *
+ * ## Options for Popup Widget
+ *
+ * Options for widget can be defined as _data-..._ attributes or give as parameter in constructor.
+ *
+ * You can change option for widget using method **option**.
+ *
+ * ## Methods
+ *
+ * To call method on widget you can use tau API:
+ *
+ *        @example
+ *        var popupElement = document.getElementById("popup"),
+ *            popup = tau.widget.popup(buttonElement);
+ *
+ *        popup.methodName(methodArgument1, methodArgument2, ...);
+ *
+ * ## Transitions
+ *
+ * By default, the framework doesn't apply transition. To set a custom transition effect, add the
+ * data-transition attribute to the link.
+ *
+ *        @example
+ *        <a href="index.html" data-rel="popup" data-transition="slideup">I will slide up</a>
+ *
+ * Global configuration:
+ *
+ *        @example
+ *        gear.ui.defaults.popupTransition = "slideup";
+ *
+ * ### Transitions list
+ *
+ * - **none** Default value, no transition.
+ * - **slideup** Makes the content of the pop-up slide up.
+ *
+ * ## Handling Popup Events
+ *
+ * To use popup events, use the following code:
+ *
+ *      @example
+ *         <!--Popup html code-->
+ *         <div id="popup" class="ui-popup">
+ *             <div class="ui-popup-header"></div>
+ *             <div class="ui-popup-content"></div>
+ *         </div>
+ *         </div>
+ *         <script>
+ *             // Use popup events
+ *             var popup = document.getElementById("popup");
+ *             popup.addEventListener("popupbeforecreate", function() {
+ *                 // Implement code for popupbeforecreate event
+ *             });
+ *         </script>
+ *
+ * Full list of available events is in [events list section](#events-list).
+ *
+ * @author Hyunkook Cho <hk0713.cho@samsung.com>
+ * @class ns.widget.core.ContextPopup
+ * @extends ns.widget.core.Popup
+ * @component-selector [data-role="popup"], .ui-popup
+ */
+(function (window, document, ns) {
+       "use strict";
+       
+                       var Popup = ns.widget.core.Popup,
+
+                               PopupPrototype = Popup.prototype,
+
+                               engine = ns.engine,
+
+                               objectUtils = ns.util.object,
+
+                               domUtils = ns.util.DOM,
+
+                               /**
+                                * Object with default options
+                                * @property {Object} defaults
+                                * @property {string} [options.transition="none"] Sets the default transition for the popup.
+                                * @property {string} [options.positionTo="window"] Sets the element relative to which the
+                                * popup will be centered.
+                                * @property {boolean} [options.dismissible=true] Sets whether to close popup when a popup
+                                * is open to support the back button.
+                                * @property {boolean} [options.overlay=true] Sets whether to show overlay when a popup is
+                                * open.
+                                * @property {string} [overlayClass=""] Sets the custom class for the popup background,
+                                * which covers the entire window.
+                                * @property {boolean} [options.history=true] Sets whether to alter the url when a popup
+                                * is open to support the back button.
+                                * @property {string} [options.arrow="l,t,r,b"] Sets directions of popup's arrow by
+                                * priority ("l" for left, "t" for top,
+                                * "r" for right, and "b" for bottom). The first one has the highest priority, the last one
+                                * - the lowest. If you set arrow="t",
+                                * then arrow will be placed at the top of popup container and the whole popup will be
+                                * placed under clicked element.
+                                * @property {string} [options.positionTo="window"] Sets the element relative to which
+                                * the popup will be centered.
+                                * @property {number} [options.distance=0] Sets the extra distance in px from clicked
+                                * element.
+                                * @property {HTMLElement|string} [options.link=null] Set the element or its id, under
+                                * which popup should be placed.
+                                * It only works with option positionTo="origin".
+                                * @member ns.widget.core.ContextPopup
+                                * @static
+                                * @private
+                                */
+                               defaults = {
+                                       arrow: "l,b,r,t",
+                                       positionTo: "window",
+                                       positionOriginCenter: false,
+                                       distance: 0,
+                                       link: null
+                               },
+
+                               ContextPopup = function () {
+                                       var self = this,
+                                               ui;
+
+                                       Popup.call(self);
+
+                                       // set options
+                                       self.options = objectUtils.merge(self.options, defaults);
+
+                                       // set ui
+                                       ui = self._ui || {};
+                                       ui.arrow = null;
+                                       self._ui = ui;
+                               },
+
+                               /**
+                                * @property {Object} classes Dictionary for popup related css class names
+                                * @member ns.widget.core.Popup
+                                * @static
+                                */
+                               CLASSES_PREFIX = "ui-popup",
+                               classes = objectUtils.merge({}, Popup.classes, {
+                                       context: "ui-ctxpopup",
+                                       contextOverlay: "ui-ctxpopup-overlay",
+                                       arrow: "ui-arrow",
+                                       arrowDir: CLASSES_PREFIX + "-arrow-"
+                               }),
+
+                               /**
+                                * @property {Object} events Dictionary for popup related events
+                                * @member ns.widget.core.Popup
+                                * @static
+                                */
+                               /* eslint-disable camelcase */
+                               // we can't change this in this moment because this is part of API
+                               events = objectUtils.merge({}, Popup.events, {
+                                       before_position: "beforeposition"
+                               }),
+                               /* eslint-enable camelcase */
+
+                               positionTypes = {
+                                       WINDOW: "window",
+                                       ORIGIN: "origin",
+                                       ABSOLUTE: "absolute"
+                               },
+
+                               prototype = new Popup();
+
+                       ContextPopup.defaults = objectUtils.merge({}, Popup.defaults, defaults);
+                       ContextPopup.classes = classes;
+                       ContextPopup.events = events;
+                       ContextPopup.positionTypes = positionTypes;
+
+                       /**
+                        * Build structure of Popup widget
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.core.Popup
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       arrow;
+
+                               // build elements of popup
+                               PopupPrototype._build.call(self, element);
+
+                               // set class for element
+                               element.classList.add(classes.popup);
+
+                               // create arrow
+                               arrow = document.createElement("div");
+                               arrow.appendChild(document.createElement("span"));
+                               arrow.classList.add(classes.arrow);
+                               ui.arrow = arrow;
+
+                               // add arrow to popup element
+                               element.appendChild(arrow);
+
+                               return element;
+                       };
+
+                       /**
+                        * Init widget
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui;
+
+                               PopupPrototype._init.call(this, element);
+
+                               ui.arrow = ui.arrow || element.querySelector("." + classes.arrow);
+                       };
+
+                       /**
+                        * Layouting popup structure
+                        * @method layout
+                        * @member ns.widget.core.ContextPopup
+                        * @param {HTMLElement} element
+                        */
+                       prototype._layout = function (element) {
+                               var self = this;
+
+                               this._reposition();
+                               PopupPrototype._layout.call(self, element);
+                       };
+
+                       /**
+                        * Set position and size of popup.
+                        * @method _reposition
+                        * @param {Object} options
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._reposition = function (options) {
+                               var self = this,
+                                       element = self.element,
+                                       ui = self._ui,
+                                       elementClassList = element.classList;
+
+                               options = objectUtils.merge({}, self.options, options);
+
+                               self.trigger(events.before_position, null, false);
+
+                               elementClassList.add(classes.build);
+
+                               // set height of content
+                               self._setContentHeight();
+
+                               // set class for contextpopup
+                               if ((options.positionTo === "origin") && ui.overlay) {
+                                       ui.overlay.classList.add(classes.contextOverlay);
+                               }
+
+                               // set position of popup
+                               self._placementCoords(options);
+
+                               elementClassList.remove(classes.build);
+
+                       };
+
+                       /**
+                        * Find the best position of context popup.
+                        * @method findBestPosition
+                        * @param {ns.widget.core.ContextPopup} self
+                        * @param {HTMLElement} clickedElement
+                        * @private
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       function findBestPosition(self, clickedElement) {
+                               var options = self.options,
+                                       arrowsPriority = options.arrow.split(","),
+                                       element = self.element,
+                                       windowWidth = window.innerWidth,
+                                       windowHeight = window.innerHeight,
+                                       popupWidth = domUtils.getElementWidth(element, "outer"),
+                                       popupHeight = domUtils.getElementHeight(element, "outer"),
+                                       // offset coordinates of clicked element
+                                       clickElementRect = clickedElement.getBoundingClientRect(),
+                                       clickElementOffsetX = clickElementRect.left,
+                                       clickElementOffsetY = clickElementRect.top,
+                                       // width of visible part of clicked element
+                                       clickElementOffsetWidth = Math.min(clickElementRect.width,
+                                               windowWidth - clickElementOffsetX),
+                                       // height of visible part of clicked element
+                                       clickElementOffsetHeight = Math.min(clickElementRect.height,
+                                               windowHeight - clickElementOffsetY),
+                                       // params for all types of popup
+                                       // "l" - popup with arrow on the left side, "r" - right, "b" - bottom, "t" - top
+                                       // dir - this letter is added as a suffix of class to popup's element
+                                       // fixedPositionField - specifies which coordinate is changed for this type of popup
+                                       // fixedPositionFactor - factor, which specifies if size should be added or subtracted
+                                       // size - available size, which is needed for this type of popup (width or height)
+                                       // max - maximum size of available place
+                                       params = {
+                                               "l": {
+                                                       dir: "l", fixedPositionField: "x", fixedPositionFactor: 1,
+                                                       size: popupWidth, max: clickElementOffsetX
+                                               },
+                                               "r": {
+                                                       dir: "r", fixedPositionField: "x", fixedPositionFactor: -1,
+                                                       size: popupWidth, max: windowWidth - clickElementOffsetX - clickElementOffsetWidth
+                                               },
+                                               "b": {
+                                                       dir: "b", fixedPositionField: "y", fixedPositionFactor: -1,
+                                                       size: popupHeight, max: clickElementOffsetY
+                                               },
+                                               "t": {
+                                                       dir: "t", fixedPositionField: "y", fixedPositionFactor: 1,
+                                                       size: popupHeight, max: windowHeight - clickElementOffsetY - clickElementOffsetHeight
+                                               }
+                                       },
+                                       bestDirection,
+                                       direction,
+                                       bestOffsetInfo;
+
+                               // set value of bestDirection on the first possible type or top
+                               bestDirection = params[arrowsPriority[0]] || params.t;
+
+                               arrowsPriority.forEach(function (key) {
+                                       var param = params[key],
+                                               paramMax = param.max;
+
+                                       if (!direction) {
+                                               if (param.size < paramMax) {
+                                                       direction = param;
+                                               } else if (paramMax > bestDirection.max) {
+                                                       bestDirection = param;
+                                               }
+                                       }
+                               });
+
+                               if (!direction) {
+                                       direction = bestDirection;
+                                       if (direction.fixedPositionField === "x") {
+                                               popupWidth = direction.max;
+                                       } else {
+                                               popupHeight = direction.max;
+                                       }
+                               }
+
+                               // info about the best position without taking into account type of popup
+                               bestOffsetInfo = {
+                                       x: clickElementOffsetX + clickElementOffsetWidth / 2 - popupWidth / 2,
+                                       y: clickElementOffsetY + clickElementOffsetHeight / 2 - popupHeight / 2,
+                                       w: popupWidth,
+                                       h: popupHeight,
+                                       dir: direction.dir
+                               };
+
+                               // check type of popup and correct value for "fixedPositionField" coordinate
+                               bestOffsetInfo[direction.fixedPositionField] +=
+                                       (direction.fixedPositionField === "x" ?
+                                               (popupWidth + clickElementOffsetWidth) * direction.fixedPositionFactor :
+                                               (popupHeight + clickElementOffsetHeight) * direction.fixedPositionFactor) / 2 +
+                                       options.distance * direction.fixedPositionFactor;
+
+                               // fix min/max position
+                               bestOffsetInfo.x = bestOffsetInfo.x < 0 ? 0 : bestOffsetInfo.x + bestOffsetInfo.w > windowWidth ? windowWidth - bestOffsetInfo.w : bestOffsetInfo.x;
+                               bestOffsetInfo.y = bestOffsetInfo.y < 0 ? 0 : bestOffsetInfo.y + bestOffsetInfo.h > windowHeight ? windowHeight - bestOffsetInfo.h : bestOffsetInfo.y;
+
+                               return bestOffsetInfo;
+                       }
+
+                       /**
+                        * Find the best position of arrow.
+                        * @method adjustedPositionAndPlacementArrow
+                        * @param {ns.widget.core.ContextPopup} self
+                        * @param {Object} bestRectangle
+                        * @param {number} x
+                        * @param {number} y
+                        * @private
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       function adjustedPositionAndPlacementArrow(self, bestRectangle, x, y) {
+                               var ui = self._ui,
+                                       wrapper = ui.wrapper,
+                                       arrow = ui.arrow,
+                                       popupElement = self.element,
+                                       arrowStyle = arrow.style,
+                                       windowWidth = window.innerWidth,
+                                       windowHeight = window.innerHeight,
+                                       wrapperRect = wrapper.getBoundingClientRect(),
+                                       arrowHalfWidth = arrow.offsetWidth / 2,
+                                       popupProperties = {
+                                               "padding-top": 0,
+                                               "padding-bottom": 0,
+                                               "padding-left": 0,
+                                               "padding-right": 0,
+                                               "border-top-width": 0,
+                                               "border-left-width": 0,
+                                               "box-sizing": null
+                                       },
+                                       wrapperProperties = {
+                                               "margin-top": 0,
+                                               "margin-bottom": 0,
+                                               "margin-left": 0,
+                                               "margin-right": 0,
+                                               "padding-top": 0,
+                                               "padding-bottom": 0,
+                                               "padding-left": 0,
+                                               "padding-right": 0
+                                       },
+                                       margins,
+                                       params = {
+                                               "t": {pos: x, min: "left", max: "right", posField: "x", valField: "w", styleField: "left"},
+                                               "b": {pos: x, min: "left", max: "right", posField: "x", valField: "w", styleField: "left"},
+                                               "l": {pos: y, min: "top", max: "bottom", posField: "y", valField: "h", styleField: "top"},
+                                               "r": {pos: y, min: "top", max: "bottom", posField: "y", valField: "h", styleField: "top"}
+                                       },
+                                       param = params[bestRectangle.dir],
+                                       surplus,
+                                       addPadding;
+
+                               domUtils.extractCSSProperties(popupElement, popupProperties);
+                               domUtils.extractCSSProperties(wrapper, wrapperProperties);
+                               addPadding = popupProperties["box-sizing"] === "border-box";
+                               margins = {
+                                       "t": popupProperties["padding-top"] + wrapperProperties["margin-top"] + wrapperProperties["padding-top"],
+                                       "b": popupProperties["padding-bottom"] + wrapperProperties["margin-bottom"] + wrapperProperties["padding-bottom"],
+                                       "l": popupProperties["padding-left"] + wrapperProperties["margin-left"] + wrapperProperties["padding-left"],
+                                       "r": popupProperties["padding-right"] + wrapperProperties["margin-right"] + wrapperProperties["padding-right"]
+                               };
+
+                               // value of coordinates of proper edge of wrapper
+                               wrapperRect = {
+                                       // x-coordinate of left edge
+                                       left: margins.l + bestRectangle.x,
+                                       // x-coordinate of right edge
+                                       right: margins.l + wrapperRect.width + bestRectangle.x,
+                                       // y-coordinate of top edge
+                                       top: margins.t + bestRectangle.y,
+                                       // y-coordinate of bottom edge
+                                       bottom: wrapperRect.height + margins.t + bestRectangle.y
+                               };
+
+                               if (wrapperRect[param.min] > param.pos - arrowHalfWidth) {
+                                       surplus = bestRectangle[param.posField];
+                                       if (surplus > 0) {
+                                               bestRectangle[param.posField] = Math.max(param.pos - arrowHalfWidth, 0);
+                                               param.pos = bestRectangle[param.posField] + arrowHalfWidth;
+                                       } else {
+                                               param.pos = wrapperRect[param.min] + arrowHalfWidth;
+                                       }
+                               } else if (wrapperRect[param.max] < param.pos + arrowHalfWidth) {
+                                       surplus = (param.valField === "w" ? windowWidth : windowHeight) -
+                                               (bestRectangle[param.posField] + bestRectangle[param.valField]);
+                                       if (surplus > 0) {
+                                               bestRectangle[param.posField] += Math.min(surplus, (param.pos + arrowHalfWidth) - wrapperRect[param.max]);
+                                               param.pos = bestRectangle[param.posField] + bestRectangle[param.valField] - arrowHalfWidth;
+                                       } else {
+                                               param.pos = wrapperRect[param.max] - arrowHalfWidth;
+                                       }
+                               }
+
+                               arrowStyle[param.styleField] = (param.pos - arrowHalfWidth - bestRectangle[param.posField] - (addPadding ? popupProperties["border-" + param.styleField + "-width"] : 0)) + "px";
+
+                               return bestRectangle;
+                       }
+
+                       /**
+                        * Set top, left and margin for popup's container.
+                        * @method _placementCoordsWindow
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._placementCoordsWindow = function (element) {
+                               var elementStyle = element.style,
+                                       elementWidth = element.offsetWidth;
+
+                               elementStyle.bottom = "0px";
+                               elementStyle.left = "50%";
+                               elementStyle.marginLeft = -(elementWidth / 2) + "px";
+                       };
+
+                       /**
+                        * Set top, left and margin for popup's container.
+                        * @method _placementCoordsAbsolute
+                        * @param {HTMLElement} element
+                        * @param {number} x
+                        * @param {number} y
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._placementCoordsAbsolute = function (element, x, y) {
+                               var elementStyle = element.style,
+                                       elementWidth = element.offsetWidth,
+                                       elementHeight = element.offsetHeight;
+
+                               elementStyle.top = y + "px";
+                               elementStyle.left = x + "px";
+                               elementStyle.marginTop = -(elementHeight / 2) + "px";
+                               elementStyle.marginLeft = -(elementWidth / 2) + "px";
+                       };
+
+                       /**
+                        * Find clicked element.
+                        * @method _findClickedElement
+                        * @param {number} x
+                        * @param {number} y
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._findClickedElement = function (x, y) {
+                               return document.elementFromPoint(x, y);
+                       };
+
+                       /**
+                        * Emulate position of event for clicked element.
+                        * @method emulatePositionOfClick
+                        * @param {string} bestDirection direction of arrow
+                        * @param {HTMLElement} clickedElement
+                        * @private
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       function emulatePositionOfClick(bestDirection, clickedElement) {
+                               var clickedElementRect = clickedElement.getBoundingClientRect(),
+                                       position = {};
+
+                               switch (bestDirection) {
+                                       case "l":
+                                               // the arrow will be on the left edge of container, so x-coordinate
+                                               // should have value equals to the position of right edge of clicked element
+                                               position.x = clickedElementRect.right;
+                                               // y-coordinate should have value equals to the position of top edge of clicked
+                                               // element plus half of its height
+                                               position.y = clickedElementRect.top + clickedElementRect.height / 2;
+                                               break;
+                                       case "r":
+                                               // the arrow will be on the right edge of container
+                                               position.x = clickedElementRect.left;
+                                               position.y = clickedElementRect.top + clickedElementRect.height / 2;
+                                               break;
+                                       case "t":
+                                               // the arrow will be on the top edge of container
+                                               position.x = clickedElementRect.left + clickedElementRect.width / 2;
+                                               position.y = clickedElementRect.bottom;
+                                               break;
+                                       case "b":
+                                               // the arrow will be on the bottom edge of container
+                                               position.x = clickedElementRect.left + clickedElementRect.width / 2;
+                                               position.y = clickedElementRect.top;
+                                               break;
+                               }
+                               return position;
+                       }
+
+                       prototype._placementCoordsOrigin = function (clickedElement, options) {
+                               var self = this,
+                                       element = self.element,
+                                       elementStyle = element.style,
+                                       elementClassList = element.classList,
+                                       x = options.x,
+                                       y = options.y,
+                                       bestRectangle,
+                                       emulatedPosition,
+                                       arrowType,
+                                       elementHeight;
+
+                               elementClassList.add(classes.context);
+
+                               elementHeight = element.offsetHeight;
+                               bestRectangle = findBestPosition(self, clickedElement);
+
+                               arrowType = bestRectangle.dir;
+                               elementClassList.add(classes.arrowDir + arrowType);
+                               self._ui.arrow.setAttribute("type", arrowType);
+
+                               if ((typeof x !== "number" && typeof y !== "number") || self.options.positionOriginCenter) {
+                                       // if we found element, which was clicked, but the coordinates of event
+                                       // was not available, we have to count these coordinates to the center of proper edge of element.
+                                       emulatedPosition = emulatePositionOfClick(arrowType, clickedElement);
+                                       x = emulatedPosition.x;
+                                       y = emulatedPosition.y;
+                               }
+                               bestRectangle = adjustedPositionAndPlacementArrow(self, bestRectangle, x, y);
+
+                               if (elementHeight > bestRectangle.h) {
+                                       self._setContentHeight(bestRectangle.h);
+                               }
+
+                               elementStyle.left = bestRectangle.x + "px";
+                               elementStyle.top = bestRectangle.y + "px";
+                       };
+
+                       prototype._placementCoordsElement = function (clickedElement) {
+                               var self = this,
+                                       element = self.element,
+                                       elementStyle = element.style,
+                                       bestRectangle,
+                                       elementHeight;
+
+                               element.classList.add(classes.context);
+
+                               elementHeight = element.offsetHeight;
+                               bestRectangle = findBestPosition(self, clickedElement);
+
+                               if (elementHeight > bestRectangle.h) {
+                                       self._setContentHeight(bestRectangle.h);
+                               }
+
+                               elementStyle.left = bestRectangle.x + "px";
+                               elementStyle.top = bestRectangle.y + "px";
+                       };
+
+                       /**
+                        * Find and set the best position for popup.
+                        * @method _placementCoords
+                        * @param {Object} options
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._placementCoords = function (options) {
+                               var self = this,
+                                       positionTo = options.positionTo,
+                                       x = options.x,
+                                       y = options.y,
+                                       element = self.element,
+                                       clickedElement,
+                                       link;
+
+                               switch (positionTo) {
+                                       case positionTypes.ORIGIN:
+                                               // if we know x-coord and y-coord, we open the popup with arrow
+                                               link = options.link;
+                                               if (link) {
+                                                       if (typeof link === "string") {
+                                                               clickedElement = document.getElementById(link);
+                                                       } else if (typeof link === "object") {
+                                                               clickedElement = link;
+                                                       }
+                                               } else if (typeof x === "number" && typeof y === "number") {
+                                                       clickedElement = self._findClickedElement(x, y);
+                                               }
+                                               if (clickedElement) {
+                                                       self._placementCoordsOrigin(clickedElement, options);
+                                                       return;
+                                               }
+                                               break;
+                                       case positionTypes.WINDOW:
+                                               self._placementCoordsWindow(element);
+                                               return;
+                                       case positionTypes.ABSOLUTE:
+                                               if (typeof x === "number" && typeof y === "number") {
+                                                       self._placementCoordsAbsolute(element, x, y);
+                                                       return;
+                                               }
+                                               break;
+                                       default:
+                                               // there is possible, that element or its id was given
+                                               if (typeof positionTo === "string") {
+                                                       try {
+                                                               clickedElement = document.querySelector(options.positionTo);
+                                                       } catch (e) {
+                                                       }
+                                               } else if (typeof positionTo === "object") {
+                                                       clickedElement = positionTo;
+                                               }
+                                               if (clickedElement) {
+                                                       self._placementCoordsElement(clickedElement, options);
+                                                       return;
+                                               }
+                                               break;
+                               }
+
+                               // if there was problem with setting position of popup, we set its position to window
+                               self._placementCoordsWindow(element);
+                       };
+
+                       /**
+                        * Set height for popup's container.
+                        * @method _setContentHeight
+                        * @param {number} maxHeight
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._setContentHeight = function (maxHeight) {
+                               var self = this,
+                                       element = self.element,
+                                       content = self._ui.content,
+                                       contentStyle,
+                                       contentHeight,
+                                       elementOffsetHeight;
+
+                               if (content) {
+                                       contentStyle = content.style;
+
+                                       if (contentStyle.height || contentStyle.minHeight) {
+                                               contentStyle.height = "";
+                                               contentStyle.minHeight = "";
+                                       }
+
+                                       maxHeight = maxHeight || window.innerHeight;
+
+                                       contentHeight = content.offsetHeight;
+                                       elementOffsetHeight = element.offsetHeight;
+
+                                       if (elementOffsetHeight > maxHeight) {
+                                               contentHeight -= (elementOffsetHeight - maxHeight);
+                                               contentStyle.height = contentHeight + "px";
+                                               contentStyle.minHeight = contentHeight + "px";
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Hide popup.
+                        * @method _onHide
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._onHide = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       element = self.element,
+                                       elementClassList = element.classList,
+                                       arrow = ui.arrow;
+
+                               elementClassList.remove(classes.context);
+                               ["l", "r", "b", "t"].forEach(function (key) {
+                                       elementClassList.remove(classes.arrowDir + key);
+                               });
+
+                               // we remove styles for element, which are changed
+                               // styles for container, header and footer are left unchanged
+                               if (element) {
+                                       element.removeAttribute("style");
+                               }
+                               if (arrow) {
+                                       arrow.removeAttribute("style");
+                               }
+
+                               PopupPrototype._onHide.call(self);
+                       };
+
+                       /**
+                        * Destroy popup.
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       arrow = ui.arrow;
+
+                               PopupPrototype._destroy.call(self);
+
+                               if (arrow && arrow.parentNode) {
+                                       arrow.parentNode.removeChild(arrow);
+                               }
+
+                               ui.arrow = null;
+                       };
+
+                       /**
+                        * Set new position for popup.
+                        * @method reposition
+                        * @param {Object} options
+                        * @param {number} options.x
+                        * @param {number} options.y
+                        * @param {string} options.positionTo
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype.reposition = function (options) {
+                               if (this._isActive()) {
+                                       this._reposition(options);
+                               }
+                       };
+
+                       /**
+                        * Refresh structure
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.core.ContextPopup
+                        */
+                       prototype._refresh = function () {
+                               if (this._isActive()) {
+                                       PopupPrototype._refresh.call(this);
+                                       this.reposition(this.options);
+                               }
+                       };
+
+                       ContextPopup.prototype = prototype;
+                       ns.widget.core.ContextPopup = ContextPopup;
+
+                       engine.defineWidget(
+                               "Popup",
+                               "[data-role='popup'], .ui-popup",
+                               [
+                                       "open",
+                                       "close",
+                                       "reposition"
+                               ],
+                               ContextPopup,
+                               "core",
+                               true
+                       );
+
+                       // @remove
+                       // THIS IS ONLY FOR COMPATIBILITY
+                       ns.widget.popup = ns.widget.Popup;
+
+                       }(window, window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * # Listview Widget
+ * Shows a list view.
+ *
+ * The list widget is used to display, for example, navigation data, results, and data entries. The following table describes the supported list classes.
+ *
+ * ## Default selectors
+ *
+ * Default selector for listview widget is class *ui-listview*.
+ *
+ * To add a list widget to the application, use the following code:
+ *
+ * ### List with basic items
+ *
+ * You can add a basic list widget as follows:
+ *
+ *      @example template
+ *         <ul class="ui-listview">
+ *             <li><span>List Item</span></li>
+ *         </ul>
+ *
+ * ### List with link items
+ *
+ * You can add a list widget with a link and press effect that allows the user to click each list item as follows:
+ *
+ *      @example tau-listview-with-link
+ *         <ul class="ui-listview">
+ *             <li>
+ *                 <a href="#">List Item</a>
+ *             </li>
+ *         </ul>
+ *
+ * ## JavaScript API
+ *
+ * Listview widget hasn't JavaScript API.
+ *
+ * @class ns.widget.core.Listview
+ * @component-selector .ui-listview
+ * @components-constraint 'listitem'
+ * @component-type container-component
+ * @extends ns.widget.BaseWidget
+ */
+/**
+ * Listview with gradient background
+ * @style ui-colored-list
+ * @member ns.widget.core.Listview
+ * @mobile
+ */
+/**
+ * Enable snap list style
+ * @style ui-snap-listview
+ * @member ns.widget.core.Listview
+ * @wearable
+ */
+/**
+ *
+ * @style ui-snap-listview
+ * @member ns.widget.core.Listview
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               Listview = function () {
+                               },
+                               classes = {
+                                       LISTVIEW: "ui-listview",
+                                       DETAILS: "ui-details"
+                               },
+                               prototype = new BaseWidget();
+
+                       Listview.classes = classes;
+
+                       /**
+                        * build Listview
+                        * @method _build
+                        * @private
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.core.Listview
+                        */
+                       prototype._build = function (element) {
+                               element.classList.add(classes.LISTVIEW);
+                               return element;
+                       };
+
+                       Listview.prototype = prototype;
+                       ns.widget.core.Listview = Listview;
+
+                       engine.defineWidget(
+                               "Listview",
+                               "[data-role='listview'], .ui-listview",
+                               [],
+                               Listview,
+                               "core"
+                       );
+                       }(window.document, ns));
+
+/**
+ * # List Item
+ *
+ * You can add a basic list item as follows:
+ *
+ *      @example template
+ *         <li><span>List Item</span></li>
+ *
+ *
+ * @class ns.widget.core.ListItem
+ * @component-selector .ui-listview li
+ * @components-constraint 'text', 'image', 'checkbox', 'button', 'radio', 'toggleswitch', 'processing'
+ * @component-type container-component
+ * @extends ns.widget.BaseWidget
+ */
+/**
+ *
+ * @style ui-li-anchor
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Subtext for item
+ * @style li-text-sub
+ * @selector  > *
+ * @member ns.widget.core.ListItem
+ * @mobile
+ */
+/**
+ * Subtext for item
+ * @style ui-li-sub-text
+ * @selector  > *
+ * @member ns.widget.core.ListItem
+ * @wearable
+ */
+/**
+ * Item with button on the right
+ * @style li-has-right-btn
+ * @mobile
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Item with circular button on the right
+ * @style li-has-right-circle-btn
+ * @selector
+ * @member ns.widget.core.ListItem
+ * @mobile
+ */
+/**
+ * Item with thumbnail on the left
+ * @style li-has-thumb
+ * @selector
+ * @member ns.widget.core.ListItem
+ * @mobile
+ */
+/**
+ * Thumbnail inside item
+ * @style li-thumb
+ * @selector .li-has-thumb > *
+ * @member ns.widget.core.ListItem
+ * @mobile
+ */
+/**
+ * Item with checkbox
+ * @style li-has-checkbox
+ * @member ns.widget.core.ListItem
+ * @mobile
+ */
+/**
+ * Item with radio button
+ * @style li-has-radio
+ * @selector
+ * @member ns.widget.core.ListItem
+ * @mobile
+ */
+/**
+ * Item with progressbar
+ * @style li-has-progress
+ * @mobile
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Item with multiline
+ * @style li-has-multiline
+ * @mobile
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Second subtext for multiline item positioned under the first one
+ * @style ui-text-sub2
+ * @selector .li-has-multiline > *
+ * @mobile
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Subtext for multiline item positioned on the right
+ * @style ui-text-sub3
+ * @selector .li-has-multiline > *
+ * @member ns.widget.core.ListItem
+ * @mobile
+ */
+/**
+ * Item with 2 lines
+ * @style li-has-2line
+ * @wearable
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Item with 3 lines
+ * @style li-has-3-lines
+ * @mobile
+ * @member ns.widget.core.ListItem
+ */
+/**
+ *
+ * @style li-icon-sub
+ * @selector  .li-text-sub > *
+ * @member ns.widget.core.ListItem
+ * @mobile
+ */
+/**
+ *
+ * @style li-icon-sub
+ * @selector .li-text-sub3 > *
+ * @member ns.widget.core.ListItem
+ * @mobile
+ */
+/**
+ *
+ * @style ui-li-static
+ * @mobile
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Expandable item
+ * @style ui-expandable
+ * @mobile
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Divider item
+ * @style ui-group-index
+ * @mobile
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * List divider
+ * @style ui-listview-divider
+ * @wearable
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Marquee item
+ * @style ui-marquee
+ * @wearable
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Marquee item with blurry effect
+ * @style ui-marquee-gradient
+ * @wearable
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Item with action icon
+ * @style ui-li-has-action-icon
+ * @wearable
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Text for action item
+ * @style ui-action-text
+ * @selector .ui-li-has-action-icon > *
+ * @wearable
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Setting icon for action item
+ * @style ui-action-setting
+ * @selector .ui-li-has-action-icon > *
+ * @wearable
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Delete icon for action item
+ * @style ui-action-delete
+ * @selector .ui-li-has-action-icon > *
+ * @wearable
+ * @member ns.widget.core.ListItem
+ */
+/**
+ * Adding icon for action item
+ * @style ui-action-add
+ * @selector .ui-li-has-action-icon > *
+ * @wearable
+ * @member ns.widget.core.ListItem
+ */
+;
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* global define, ns */
+/**
+ * #Button
+ * Shows a control that can be used to generate an action event.
+ *
+ * The button component shows on the screen a control that you can use to generate an action event
+ * when it is pressed and released. The component is coded with standard HTML anchor and input
+ * elements.
+ *
+ * The following table describes the supported button classes.
+ *
+ * ## Default selectors
+ * The button widget shows a control on the screen that you can use to generate an action event
+ * when it is pressed and released.
+ * This widget is coded with standard HTML anchor and input elements.
+ *
+ * Default selector for buttons is class *ui-btn*
+ *
+ * ### HTML Examples
+ *
+ * #### Standard button
+ * To add a button widget to the application, use the following code:
+ *
+ *      @example
+ *      <button type="button" class="ui-btn">Button</button>
+ *      <a href="#" class="ui-btn">Button</a>
+ *      <input type="button" class="ui-btn" value="Button" />
+ *
+ * #### Inline button
+ *
+ *      @example
+ *      <input type="button" class="ui-btn ui-inline" value="Button" />
+ *
+ * #### Multiline text button
+ *
+ *      @example
+ *      <a href="#" class="ui-btn ui-multiline ui-inline">A Button<br />Icon</a>
+ *
+ * ## Options
+ *
+ * ### Icons
+ * Buttons can contains icons
+ *
+ * Creates an icon button in the header area is permitted but in content or footer area creating
+ * icon are not supported.
+ *
+ * To use menu icon in header add class *ui-more* to the button element:
+ *
+ *      @example
+ *      <button class="ui-btn ui-more ui-icon-overflow">More Options</button>
+ *
+ * Samsung Wearable Web UI Framework supports 3 icon css styles:
+ *
+ *  - ui-icon-detail
+ *  - ui-icon-overflow
+ *  - ui-icon-selectall
+ *
+ * ### Disabled
+ *
+ * If you want to make disabled button, add attribute *disabled* in button tag:
+ *
+ *      @example
+ *      <button class="ui-btn" disabled="disabled">Button disabled</button>
+ *
+ * ### Inline
+ *
+ * If you want to make inline button, add class *ui-inline* to button element:
+ *
+ *      @example
+ *      <button class="ui-btn ui-inline">Inline button</button>
+ *
+ * ### Multiline
+ *
+ * If you want to make multiline text button, add *ui-multiline* class
+ *
+ *      @example
+ *      <button class="ui-btn ui-multiline">Multiline button</button>
+ *
+ * ### Color theme
+ *
+ * To optimize color support for the Samsung Wearable, the following styles below are supported:
+ *
+ * <table>
+ *  <tr>
+ *      <th>Class</th>
+ *      <th>Default</th>
+ *      <th>Press</th>
+ *      <th>Disable</th>
+ *  </tr>
+ *  <tr>
+ *      <td>ui-color-red</td>
+ *      <td>#ce2302</td>
+ *      <td>#dd654e</td>
+ *      <td>#3d0a0a</td>
+ *  </tr>
+ *  <tr>
+ *      <td>ui-color-orange</td>
+ *      <td>#ed8600</td>
+ *      <td>#f0aa56</td>
+ *      <td>#462805</td>
+ *  </tr>
+ *  <tr>
+ *      <td>ui-color-green</td>
+ *      <td>#64a323</td>
+ *      <td>#92be5e</td>
+ *      <td>#1e3108</td>
+ *  </tr>
+ * </table>
+ *
+ * ### Button Group
+ *
+ * You can group buttons in columns or rows. The following table lists the supported button column
+ * and row classes.
+ *
+ * <table>
+ *  <tr>
+ *      <th>Class</th>
+ *      <th>Description</th>
+ *  </tr>
+ *  <tr>
+ *      <td>ui-grid-col-1</td>
+ *      <td>Defines the button column width as 100% of the screen.</td>
+ *  </tr>
+ *  <tr>
+ *      <td>ui-grid-col-2</td>
+ *      <td>Defines the button column width as 50% of the screen.</td>
+ *  </tr>
+ *  <tr>
+ *      <td>ui-grid-col-3</td>
+ *      <td>Defines the button column width as 33% of the screen.</td>
+ *  </tr>
+ *  <tr>
+ *      <td>ui-grid-row</td>
+ *      <td>Arranges the buttons in a row.</td>
+ *  </tr>
+ * </table>
+ *
+ * To implement the button groups, use the following code:
+ *
+ * #### For columns:
+ *
+ *      @example
+ *      <div class="ui-grid-col-3" style="height:76px">
+ *          <button type="button" class="ui-btn">Button Circle</button>
+ *          <a href="#" class="ui-btn ui-color-red" >A Button Circle</a>
+ *          <input type="button" class="ui-btn ui-color-orange" value="Value" />
+ *      </div>
+ *
+ * #### For rows:
+ *
+ *      @example
+ *      <div class="ui-grid-row">
+ *          <button type="button" class="ui-btn">Button Circle</button>
+ *          <a href="#" class="ui-btn ui-color-red" >A Button Circle</a>
+ *          <input type="button" class="ui-btn ui-color-orange" value="Value" />
+ *      </div>
+ *
+ * @since 2.0
+ * @class ns.widget.core.Button
+ * @component-selector button, [data-role="button"], .ui-btn, input[type="button"]
+ * @component-type standalone-component
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               Page = ns.widget.core.Page,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               engine = ns.engine,
+                               /**
+                                * Create instance of widget
+                                * @constructor
+                                * @member ns.widget.core.Button
+                                */
+                               utilDOM = ns.util.DOM,
+                               classes = {
+                                       /**
+                                        * Standard button
+                                        * @style ui-btn
+                                        * @member ns.widget.core.Button
+                                        */
+                                       BTN: "ui-btn",
+                                       /**
+                                        * Disabled button
+                                        * @style ui-state-disabled
+                                        * @member ns.widget.core.Button
+                                        */
+                                       DISABLED: "ui-state-disabled",
+                                       /**
+                                        * Make inline button
+                                        * @style ui-inline
+                                        * @member ns.widget.core.Button
+                                        */
+                                       INLINE: "ui-inline",
+                                       /**
+                                        * Creates an icon button
+                                        * @style ui-btn-icon
+                                        * @member ns.widget.core.Button
+                                        */
+                                       BTN_ICON: "ui-btn-icon",
+                                       ICON_PREFIX: "ui-icon-",
+                                       /**
+                                        * Creates a circle icon button
+                                        * @style ui-btn-circle
+                                        * @member ns.widget.core.Button
+                                        */
+                                       BTN_CIRCLE: "ui-btn-circle",
+                                       /**
+                                        * Creates a button without background
+                                        * @style ui-btn-nobg
+                                        * @member ns.widget.core.Button
+                                        */
+                                       BTN_NOBG: "ui-btn-nobg",
+                                       BTN_ICON_ONLY: "ui-btn-icon-only",
+                                       BTN_TEXT: "ui-btn-text",
+                                       BTN_FAB: "ui-btn-fab",
+                                       BTN_FLAT: "ui-btn-flat",
+                                       BTN_CONTAINED: "ui-btn-contained",
+                                       /**
+                                        * Creates a button widget with light text
+                                        * @style ui-btn-text-light
+                                        * @member ns.widget.core.Button
+                                        */
+                                       BTN_TEXT_LIGHT: "ui-btn-text-light",
+                                       /**
+                                        * Creates a button widget with dark text
+                                        * @style ui-btn-text-dark
+                                        * @member ns.widget.core.Button
+                                        */
+                                       BTN_TEXT_DARK: "ui-btn-text-dark",
+                                       FOCUS: "ui-btn-focus",
+                                       /**
+                                        * Change background color of button to red
+                                        * @style ui-color-red
+                                        * @preview <span style="background-color: red;">&nbsp;</span>
+                                        * @member ns.widget.core.Button
+                                        */
+                                       /**
+                                        * Button for header
+                                        * @style ui-more
+                                        * @member ns.widget.core.Button
+                                        */
+                                       /**
+                                        * Button more for header
+                                        * @style ui-icon-overflow
+                                        * @member ns.widget.core.Button
+                                        */
+                                       /**
+                                        * Button details for header
+                                        * @style ui-icon-detail
+                                        * @member ns.widget.core.Button
+                                        */
+                                       /**
+                                        * Button select all for header
+                                        * @style ui-icon-selectall
+                                        * @member ns.widget.core.Button
+                                        */
+                                       /**
+                                        * Icon only style
+                                        * @style ui-btn-icon-only
+                                        * @member ns.widget.core.Button
+                                        */
+                                       BTN_ICON_POSITION_PREFIX: "ui-btn-icon-",
+                                       /**
+                                        * Creates a button widget with position in middle
+                                        * @style ui-btn-text-middle
+                                        * @member ns.widget.core.Button
+                                        */
+                                       BTN_ICON_MIDDLE: "ui-btn-icon-middle",
+                                       BUTTON_CONTENT: "ui-btn-content",
+                                       HIDDEN: "ui-hidden"
+                               },
+                               MIN_SIZE = 32,
+                               MAX_SIZE = 230,
+                               buttonStyle = {
+                                       CIRCLE: "circle",
+                                       TEXTLIGHT: "light",
+                                       TEXTDARK: "dark",
+                                       NOBG: "nobg",
+                                       ICON_MIDDLE: "icon-middle",
+                                       FLOATING: "fab",
+                                       FLAT: "flat",
+                                       CONTAINED: "contained"
+                               },
+                               defaultOptions = {
+                                       // common options
+                                       inline: true,
+                                       icon: null,
+                                       disabled: false,
+                                       // mobile options
+                                       style: buttonStyle.CONTAINED,
+                                       iconpos: "left",
+                                       size: null,
+                                       middle: false,
+                                       value: null,
+                                       enabledIcon: false
+                               },
+                               Button = function () {
+                                       var self = this;
+
+                                       BaseKeyboardSupport.call(self);
+                                       self.options = {};
+                                       self._ui = {
+                                               fab: null
+                                       };
+                                       self._callbacks = {
+                                               onFABClick: null
+                                       }
+                                       self._classesPrefix = classes.BTN + "-";
+                               },
+
+                               prototype = new BaseWidget();
+
+                       Button.classes = classes;
+                       Button.prototype = prototype;
+
+                       /**
+                        * Configure button
+                        * @method _configure
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._configure = function () {
+                               /**
+                                * Object with default options
+                                * @property {Object} options
+                                * @property {boolean} [options.inline=false] If is set true then button has inline style
+                                * @property {?string} [options.icon=null] Set icon class name for button
+                                * @property {boolean} [options.disabled=false] Disable button if is set to true
+                                * @property {"left"|"right"|"button"|"top"} [options.iconpos="left"] Set icon position
+                                * @member ns.widget.core.Button
+                                * @static
+                                */
+                               /**
+                                * "circle" Make circle button
+                                * "nobg" Make button without background
+                                * @property {string} [options.style="flat"] Set style of button
+                                * @member ns.widget.core.Button
+                                * @static
+                                */
+                               this.options = ns.util.object.copy(defaultOptions);
+                       };
+
+                       /**
+                        * Reads class based on name conversion option value
+                        *
+                        * @method _readWidgetSpecyficOptionFromElementClassname
+                        * @param {HTMLElement} element Main element of widget
+                        * @param {string} name Name of option which should be used
+                        * @return {boolean} If option value was successfully read
+                        * @member ns.widget.BaseWidget
+                        * @protected
+                        */
+                       prototype._readWidgetSpecyficOptionFromElementClassname = function (element, name) {
+                               var options = this.options,
+                                       classList = element.classList;
+
+                               switch (name) {
+                                       case "enabledIcon" :
+                                               if (classList.contains(classes.BTN_ICON)) {
+                                                       options.enabledIcon = true;
+                                                       return true;
+                                               }
+                                               break;
+                               }
+                               return false;
+                       };
+
+                       /**
+                        * Set style option
+                        * @method _setStyle
+                        * @param {HTMLElement} element
+                        * @param {string} style
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._setStyle = function (element, style) {
+                               var self = this,
+                                       options = self.options,
+                                       buttonClassList = element.classList,
+                                       change = false,
+                                       ui = self._ui;
+
+                               style = style || options.style;
+
+                               if (style !== buttonStyle.FLOATING && // new button style
+                                       ui.fab !== null) { // and current button doesn't have fab element
+                                       self._revertFromFAB(element); // then revert FAB html structure
+                               }
+
+                               buttonClassList.remove(classes.BTN_CIRCLE);
+                               buttonClassList.remove(classes.BTN_NOBG);
+                               buttonClassList.remove(classes.BTN_TEXT_LIGHT);
+                               buttonClassList.remove(classes.BTN_TEXT_DARK);
+                               buttonClassList.remove(classes.BTN_FLAT);
+                               buttonClassList.remove(classes.BTN_CONTAINED);
+
+                               switch (style) {
+                                       case buttonStyle.CIRCLE:
+                                               buttonClassList.add(classes.BTN_CIRCLE);
+                                               change = true;
+                                               break;
+                                       case buttonStyle.NOBG:
+                                               buttonClassList.add(classes.BTN_NOBG);
+                                               change = true;
+                                               break;
+                                       case buttonStyle.TEXTLIGHT:
+                                               buttonClassList.add(classes.BTN_TEXT_LIGHT);
+                                               change = true;
+                                               break;
+                                       case buttonStyle.TEXTDARK:
+                                               buttonClassList.add(classes.BTN_TEXT_DARK);
+                                               change = true;
+                                               break;
+                                       case buttonStyle.FLOATING:
+                                               this._changeToFAB(element);
+                                               change = true;
+                                               break;
+                                       case buttonStyle.FLAT:
+                                               buttonClassList.add(classes.BTN_FLAT);
+                                               change = true;
+                                               break;
+                                       case buttonStyle.CONTAINED:
+                                               buttonClassList.add(classes.BTN_CONTAINED);
+                                               change = true;
+                                               break;
+                                       default:
+                               }
+
+                               if (change) {
+                                       options.style = style;
+
+                                       self._saveOption("style", style);
+                               }
+                       };
+
+                       /**
+                        * Set inline option
+                        * @method _setInline
+                        * @param {HTMLElement} element
+                        * @param {boolean} inline
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._setInline = function (element, inline) {
+                               var options = this.options;
+
+                               if (inline === undefined) {
+                                       inline = element.getAttribute("data-inline");
+                                       if (inline === null) {
+                                               inline = this._readCommonOptionFromElementClassname(element, "inline");
+                                       }
+                                       inline = (inline === "false") ? false : !!inline;
+                               }
+
+                               element.classList.toggle(classes.INLINE, inline);
+                               options.inline = inline;
+
+                               this._saveOption("inline", inline);
+                       };
+
+                       /**
+                        * Set icon option
+                        * @method _setIcon
+                        * @param {HTMLElement} element
+                        * @param {string} icon
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._setIcon = function (element, icon) {
+                               var self = this,
+                                       classList = element.classList,
+                                       options = self.options,
+                                       styles = {},
+                                       urlIcon,
+                                       iconCSSRule = self._iconCSSRule;
+
+                               element.className = element.className
+                                       .replace(RegExp("(\\" + classes.ICON_PREFIX + "([a-z-]*))", "g"), "");
+
+                               icon = icon || options.icon;
+                               options.icon = icon;
+
+                               if (icon) { // icon setting enables icon style
+                                       options.enabledIcon = true;
+                               }
+
+                               self._saveOption("icon", icon);
+
+                               if (options.enabledIcon) {
+                                       classList.add(classes.BTN_ICON);
+                                       if (icon) {
+                                               if (icon.indexOf(".") === -1) {
+                                                       classList.add(classes.ICON_PREFIX + icon);
+                                                       self._setTitleForIcon(element);
+                                                       if (iconCSSRule) {
+                                                               utilDOM.removeCSSRule(iconCSSRule);
+                                                       }
+                                               } else {
+                                                       // if icon is file path
+                                                       urlIcon = "url(\"" + icon + "\")";
+                                                       styles["-webkit-mask-image"] = urlIcon;
+                                                       styles["mask-image"] = urlIcon;
+                                                       self._iconCSSRule = utilDOM.setStylesForPseudoClass("#" + element.id, "after", styles);
+                                               }
+                                       } // else - icon can be defined from app css styles
+
+                                       // remove button text class if text content is empty
+                                       if (!element.textContent.trim()) {
+                                               classList.remove(classes.BTN_TEXT);
+                                       }
+                               } else {
+                                       classList.remove(classes.BTN_ICON);
+                                       if (iconCSSRule) {
+                                               utilDOM.removeCSSRule(iconCSSRule);
+                                       }
+                               }
+                       };
+
+                       prototype._removeIconposClass = function (element) {
+                               var self = this;
+
+                               element = element || self.element;
+                               element.classList.remove(classes.BTN_ICON_POSITION_PREFIX + "left");
+                               element.classList.remove(classes.BTN_ICON_POSITION_PREFIX + "top");
+                               element.classList.remove(classes.BTN_ICON_ONLY);
+                       };
+
+                       prototype._addIconposClass = function (element) {
+                               var self = this,
+                                       innerTextLength;
+
+                               element = element || self.element;
+
+                               innerTextLength = element.textContent.trim().length ||
+                                       (element.value ? element.value.length : 0);
+
+                               if (innerTextLength > 0) {
+                                       element.classList.add(classes.BTN_ICON_POSITION_PREFIX + self.options.iconpos);
+                               } else {
+                                       element.classList.add(classes.BTN_ICON_ONLY);
+                               }
+                       };
+
+                       /**
+                        * Set iconpos option
+                        * @method _setIconpos
+                        * @param {HTMLElement} element
+                        * @param {string} iconpos
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._setIconpos = function (element, iconpos) {
+                               var self = this,
+                                       options = self.options,
+                                       style = options.style;
+
+                               self._removeIconposClass(element);
+
+                               iconpos = iconpos || options.iconpos;
+
+                               if (options.icon && style !== buttonStyle.CIRCLE && style !== buttonStyle.NOBG && style !== buttonStyle.FLOATING) {
+                                       options.iconpos = iconpos;
+
+                                       self._addIconposClass(element);
+                                       self._saveOption("iconpos", iconpos);
+                               }
+                       };
+
+                       /**
+                        * Set title for button without showing text
+                        * @method _setTitleForIcon
+                        * @param {HTMLElement|HTMLInputElement|HTMLButtonElement} element
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._setTitleForIcon = function (element) {
+                               var options = this.options,
+                                       buttonText = element.textContent;
+
+                               // Add title to element if button not has text.
+                               if (options.iconpos === "notext" && !element.getAttribute("title")) {
+                                       element.setAttribute("title", buttonText);
+                                       ns.warn("iconpos='notext' is deprecated.");
+                               }
+                       };
+
+                       prototype._focus = function () {
+                               var elementClassList;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       elementClassList = this.element.classList;
+
+                                       elementClassList.add(classes.FOCUS);
+                                       this.element.focus();
+                               }
+                       };
+
+                       prototype._blur = function () {
+                               var elementClassList;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       elementClassList = this.element.classList;
+
+                                       elementClassList.remove(classes.FOCUS);
+                                       this.element.blur();
+                               }
+                       };
+
+                       /**
+                        * Sets button to disabled if element.disabled or element.disabled property is true,
+                        * or class is set to ui-state-disabled
+                        * @method _setDisabled
+                        * @param {HTMLElement} element
+                        * @param {boolean} state
+                        * @protected
+                        */
+                       prototype._setDisabled = function (element, state) {
+                               var self = this,
+                                       options = self.options,
+                                       buttonClassList = element.classList;
+
+                               if (state === true || options.disabled === true || element.disabled ||
+                                       buttonClassList.contains(classes.DISABLED)) {
+                                       options.disabled = true;
+                                       self._disable(element);
+                               } else {
+                                       options.disabled = false;
+                               }
+
+                               self._saveOption("disabled", options.disabled);
+                       };
+
+                       function wrapButtonContent(element) {
+                               var content = null;
+
+                               if (element.children.length > 1 ||
+                                       (element.children.length === 1 && // don't wrap himself
+                                               !element.firstElementChild.classList.contains(classes.BUTTON_CONTENT))) {
+                                       content = document.createElement("div");
+                                       content.classList.add(classes.BUTTON_CONTENT);
+
+                                       // move button content to the content element
+                                       [].slice.call(element.children).forEach(function (child) {
+                                               content.appendChild(child);
+                                       });
+
+                                       element.appendChild(content);
+                               }
+
+                               return content;
+                       }
+
+                       /**
+                        * Build Button
+                        * @method _build
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       buttonClassList = element.classList;
+
+                               if (!buttonClassList.contains(classes.BTN)) {
+                                       buttonClassList.add(classes.BTN);
+                               }
+
+                               self._content = wrapButtonContent(element);
+
+                               self._setStyle(element);
+                               self._setInline(element);
+                               self._setIconpos(element);
+                               self._setIcon(element);
+                               self._setSize(element);
+                               self._setDisabled(element);
+                               self._setTextButton(element);
+
+                               if (!element.hasAttribute("tabindex")) {
+                                       element.setAttribute("tabindex", 0);
+                               }
+
+                               return element;
+                       };
+
+                       /**
+                        * Refresh structure
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._refresh = function () {
+                               var self = this,
+                                       element = this.element;
+
+                               self.options = self._getCreateOptions(element);
+                               self._build(element);
+
+                               return null;
+                       };
+
+                       /**
+                        * Get value of button
+                        * @method _getValue
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._getValue = function () {
+                               return this.element.textContent;
+                       };
+
+                       /**
+                        * Set size of button
+                        * @method _setSize
+                        * @param {HTMLElement} element
+                        * @param {string|number} value
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._setSize = function (element, value) {
+                               var style = element.style,
+                                       options = this.options,
+                                       size = value || options.size;
+
+                               if (size) {
+                                       size = parseInt(size, 10);
+
+                                       if (size < MIN_SIZE) {
+                                               size = MIN_SIZE;
+                                       }
+                                       if (size > MAX_SIZE) {
+                                               size = MAX_SIZE;
+                                       }
+                                       style.height = size + "px";
+                                       style.width = size + "px";
+
+                                       // @to do: why size has the same value for width and height
+                                       options.size = size;
+                               }
+
+                       };
+
+                       /**
+                        * Set text of the button
+                        * @method _setTextButton
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._setTextButton = function (element) {
+                               if (element.textContent.trim()) {
+                                       element.classList.add(classes.BTN_TEXT);
+                               } else {
+                                       element.classList.remove(classes.BTN_TEXT);
+                               }
+                       };
+
+                       /**
+                        * Set value of button
+                        * @method _setValue
+                        * @param {string} value
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._setValue = function (value) {
+                               this.element.textContent = value;
+                       };
+
+                       /**
+                        * Enable button
+                        * @method _enable
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._enable = function (element) {
+                               var self = this,
+                                       options = self.options;
+
+                               if (element) {
+                                       if (element.tagName.toLowerCase() === "button") {
+                                               element.disabled = false;
+                                       }
+                                       if (!this.isCustomElement) {
+                                               element.removeAttribute("disabled");
+                                       }
+                                       element.classList.remove(classes.DISABLED);
+                                       options.disabled = false;
+
+                                       self._saveOption("disabled", false);
+                               }
+                       };
+
+                       prototype._bindEvents = function (element) {
+                               var self = this;
+
+                               self._focusCallback = self._focus.bind(self);
+                               self._blurCallback = self._blur.bind(self);
+
+                               element.addEventListener("focus", self._focusCallback);
+                               element.addEventListener("blur", self._blurCallback);
+                       };
+
+                       prototype._unbindEvents = function (element) {
+                               var self = this;
+
+                               element.removeEventListener("focus", self._focusCallback);
+                               element.removeEventListener("blur", self._blurCallback);
+                       };
+
+                       /**
+                        * Disable button
+                        * @method _disable
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._disable = function (element) {
+                               var options = this.options;
+
+                               if (element) {
+                                       if (element.tagName.toLowerCase() === "button") {
+                                               element.disabled = true;
+                                       }
+                                       if (!this.isCustomElement) {
+                                               element.setAttribute("disabled", "disabled");
+                                       }
+                                       element.classList.add(classes.DISABLED);
+                                       options.disabled = true;
+
+                                       this._saveOption("disabled", true);
+                               }
+                       };
+
+                       /**
+                        * Store widget option value in element as data attribute
+                        * @method _saveOption
+                        * @param {string} name
+                        * @param {*} value
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._saveOption = function (name, value) {
+                               var self = this,
+                                       element = self.element,
+                                       defaultValue = defaultOptions[name];
+
+                               if (element) {
+                                       if (defaultValue !== value) {
+                                               element.dataset[name] = value;
+                                       } else {
+                                               delete element.dataset[name];
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Returns default option value for given name
+                        * @method _getDefaultOption
+                        * @param {string} optionName
+                        * @return {*} default widget option value
+                        * @protected
+                        * @member ns.widget.core.Button
+                        */
+                       prototype._getDefaultOption = function (optionName) {
+                               return defaultOptions[optionName];
+                       }
+
+                       function onFABClick(self, e) {
+                               ns.event.trigger(self.element, "vclick", e);
+                       }
+
+                       prototype._bindEventsFAB = function () {
+                               var self = this,
+                                       fab = self._ui.fab;
+
+                               self._callbacks.onFABClick = onFABClick.bind(null, self);
+                               fab.addEventListener("vclick", self._callbacks.onFABClick);
+                       }
+
+                       prototype._unbindEventsFAB = function () {
+                               var self = this,
+                                       fab = self._ui.fab;
+
+                               fab.removeEventListener("vclick", self._callbacks.onFABClick);
+                               self._callbacks.onFABClick = null;
+                       }
+
+                       prototype._changeToFAB = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       fab = document.createElement("button"),
+                                       pageContainer = ns.util.selectors.getClosestBySelector(element, Page.selector);
+
+                               ui.fab = fab;
+                               fab.classList.add(classes.BTN);
+                               fab.classList.add(classes.BTN_FAB);
+                               if (self.options.icon) {
+                                       fab.classList.add(classes.BTN_ICON);
+                                       fab.classList.add(classes.ICON_PREFIX + self.options.icon);
+                               }
+
+                               // hide element
+                               element.classList.add(classes.HIDDEN);
+
+                               if (pageContainer) {
+                                       pageContainer.appendChild(fab);
+                               }
+                               // bind events to FAB
+                               self._bindEventsFAB();
+                       }
+
+                       prototype._revertFromFAB = function (element) {
+                               var self = this,
+                                       fab = self._ui.fab;
+
+                               // unbind FAB events
+                               self._unbindEventsFAB();
+
+                               // remove element from DOM
+                               if (fab) {
+                                       fab.parentElement.removeChild(fab);
+                                       self._ui.fab = null;
+                               }
+                               // show element
+                               element.classList.remove(classes.HIDDEN);
+                       }
+
+                       ns.widget.core.Button = Button;
+
+                       Button.defaultOptions = defaultOptions;
+
+                       engine.defineWidget(
+                               "Button",
+                               "button, [data-role='button'], .ui-btn, input[type='button']",
+                               [],
+                               Button,
+                               "core"
+                       );
+
+                       engine.defineWidget(
+                               "inputButton",
+                               "",
+                               [],
+                               Button,
+                               "core",
+                               false,
+                               false,
+                               HTMLInputElement
+                       );
+
+                       engine.defineWidget(
+                               "formButton",
+                               "",
+                               [],
+                               Button,
+                               "core",
+                               false,
+                               false,
+                               HTMLButtonElement
+                       );
+
+                       BaseKeyboardSupport.registerActiveSelector("[data-role='button'], button, [type='button'], [type='submit'], [type='reset'], .ui-button, .ui-btn");
+
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Mobile UI Components
+ *
+ * The Web UI Framework (called as **TAU**; Tizen Advanced UI framework) provides rich Tizen components that are optimized for the Tizen Web browser.
+ *
+ * ##UI components list
+ *
+ * The following table displays the components provided by the Tizen mobile Web UI Framework.
+ *
+ * @class ns.widget.mobile
+ * @seeMore https://developer.tizen.org/dev-guide/2.2.1/org.tizen.web.uiwidget.apireference/html/web_ui_framework.htm "Web UI Framework Reference"
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function (window, ns) {
+       "use strict";
+                               ns.widget.mobile = ns.widget.mobile || {};
+                       }(window, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Popup
+ * Widget handles creating and managing popup windows.
+ *
+ * ##Default selectors
+ * In default all elements with _data-role=popup_ or CSS class _.ui-popup_ are changed to Tizen WebUI popups.
+ *
+ * ##HTML Examples
+ *
+ * ###Create simple popup from div
+ *
+ *             @example
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *             <!-- link related with popup-->
+ *             <a href="#popup">Click to open popup</a>
+ *
+ * ###Create simple popup positioned to window
+ *
+ * Popup inherits value of option _positionTo_ from property _data-position-to_ set in link.
+ *
+ *             @example
+ *             <!--definition of link, which opens popup and sets its position-->
+ *             <a href="#center_info" data-position-to="window">Click to open popup</a>
+ *             <!--definition of popup, which inherits property position from link-->
+ *             <div id="center_info" data-role="popup" class="center_info">
+ *                     <div class="ui-popup-text">
+ *                             <p>Pop-up dialog box, a child window that blocks user interaction to the parent windows</p>
+ *                     </div>
+ *             </div>
+ *
+ * ###Create popup with title and button
+ *
+ *             @example
+ *             <a href="#center_title_1btn">Click to open popup</a>
+ *             <!--definition of popup with a title and button-->
+ *             <div id="center_title_1btn" data-role="popup" class="center_title_1btn">
+ *                     <div class="ui-popup-title">
+ *                             <h1>Popup title</h1>
+ *                     </div>
+ *                     <div class="ui-popup-text">
+ *                             Pop-up dialog box, a child window that blocks user interaction to the parent windows
+ *                     </div>
+ *                     <div class="ui-popup-button-bg">
+ *                             <a data-role="button" data-rel="back" data-inline="true">Button</a>
+ *                     </div>
+ *             </div>
+ *
+ * ###Create popup with menu
+ *
+ * A menu can be created by placing listview inside a popup.
+ *
+ *             @example
+ *             <a href="#center_liststyle_1btn">Click to open popup</a>
+ *             <div id="center_liststyle_1btn" data-role="popup" class="center_liststyle_1btn">
+ *                     <div class="ui-popup-title">
+ *                             <h1>Popup title</h1>
+ *                     </div>
+ *                     <div class="ui-popup-scroller-bg" data-scroll="y">
+ *                             <ul data-role="listview" data-icon="1line-textonly">
+ *                                     <li><a href="#">List item 1</a></li>
+ *                                     <li><a href="#">List item 2</a></li>
+ *                             </ul>
+ *                     </div>
+ *                     <div class="ui-popup-button-bg">
+ *                             <a data-role="button" data-rel="back" data-inline="true">Cancel</a>
+ *                     </div>
+ *             </div>
+ *
+ * ###Create popup with nested menu
+ *
+ * A nested menu can be created by placing collapsible-set widget with listview elements.
+ *
+ *             @example
+ *             <a href="#popupNested">Click to open popup</a>
+ *             <div id="popupNested" data-role="popup">
+ *                     <div data-role="collapsible-set" data-collapsed-icon="arrow-r" data-expanded-icon="arrow-d">
+ *                             <div data-role="collapsible">
+ *                                     <h2>First menu</h2>
+ *                                     <ul data-role="listview">
+ *                                             <li><a href="#" >Item 1</a></li>
+ *                                             <li><a href="#" >Item 2</a></li>
+ *                                     </ul>
+ *                             </div>
+ *                             <div data-role="collapsible">
+ *                                     <h2>Second menu</h2>
+ *                                     <ul data-role="listview">
+ *                                             <li><a href="#" >Item 1</a></li>
+ *                                             <li><a href="#" >Item 2</a></li>
+ *                                     </ul>
+ *                             </div>
+ *                     </div>
+ *             </div>
+ *
+ * ###Create popup with form
+ *
+ * A form can be created by placing inputs elements inside popup.
+ *
+ *             @example
+ *             <a href="#textbox_popup">Click to open popup</a>
+ *             <div id="textbox_popup" data-role="popup" class="center_title_2btn">
+ *                     <div class="ui-popup-title">
+ *                             <h1>PopupTest<h1>
+ *                     </div>
+ *                     <div class="ui-popup-text">
+ *                             <input type="text" size="20" />
+ *                             <input type="text" size="20" />
+ *                     </div>
+ *                     <div class="ui-popup-button-bg">
+ *                             <a data-role="button" id="btn_textbox_popup_cancel" data-inline="true">Cancel</a>
+ *                             <a data-role="button" data-rel="back" data-inline="true">OK</a>
+ *                     </div>
+ *             </div>
+ *
+ * ##Manual constructor
+ * For manual creation of popup widget you can use constructor of widget:
+ *
+ *             @example
+ *             <div id="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     var popupElement = document.getElementById("popup"),
+ *                             popup = tau.widget.Popup(popupElement);
+ *                     popup.open();
+ *             </script>
+ *
+ * If jQuery library is loaded, its method can be used:
+ *
+ *             @example
+ *             <div id="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     var popup = $("#popup").popup();
+ *                     popup.popup("open");
+ *             </script>
+ *
+ * ##Context popup with arrow
+ *
+ * If property _id_ is set in link and option _positionTo="origin"_ in popup, the context popup will be opened after clicking.
+ *
+ *             @example
+ *             <!-- definition of link, which opens popup with id popup in context style with arrow -->
+ *             <a href="#popup" id="linkId" data-position-to="origin" data-role="button" data-inline="true">Click to open context popup</a>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic context popup, no options set.</p>
+ *             </div>
+ *
+ * Be award that option _positionTo_ has value "origin" in popup by default. However, the property _positionTo_ is inherited from related link and this inherited value has higher priority during opening process and overwrites the previous value. So, if we do not change it in popup and do not set value of _data-position-to_ other than "origin" in link, popup connected with link will be always opened in context style.
+ *
+ * To be sure that popup will be opened in context style with arrow, we can set properties _data-position-to="origin"_ as well as _id_ in the related with popup link as in the example above.
+ *
+ * Moreover, the same result can be achieve by setting only _id_ and not setting _positionTo_ in link because popup has value "origin" for option _positionTo_ by default.
+ *
+ *             @example
+ *             <!-- in link id is set -->
+ *             <a href="#popup" id="linkId" data-role="button" data-inline="true">Click to open context popup</a>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *
+ * After building, the value of option _positionTo_ can be changed by using method _option_.
+ *
+ *             @example
+ *             <a href="#popup" id="linkId" data-role="button" data-inline="true">Click to open context popup</a>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     // changing value of option positionTo by method option
+ *                     var popupWidget = tau.widget.Popup(document.getElementById("popup"));
+ *                     popupWidget.option("positionTo", "origin");
+ *             </script>
+ *
+ * If jQuery is loaded:
+ *
+ *             @example
+ *             <a href="#popup" id="linkId" data-role="button" data-inline="true">Click to open context popup</a>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     // changing value of option positionTo by method option
+ *                     $("#popup").popup("option", "positionTo", "origin");
+ *             </script>
+ *
+ *
+ * Context popup can be created also manually for elements different than link by pushing options such as _positionTo_ and _link to method _open_.
+ *
+ *             @example
+ *             <!-- element with no properties - popup will be opened next to it in context style manually -->
+ *             <div id="linkId">Click to open context popup</div>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     // set opening popup on click event
+ *                     document.getElementById("linkId").addEventListener("click", function () {
+ *                             // open context popup
+ *                             var popupWidget = tau.widget.Popup(document.getElementById("popup"));
+ *                             // opening with options
+ *                             popupWidget.open({link: "linkId", positionTo: "origin"});
+ *                     });
+ *             </script>
+ *
+ * If jQuery is loaded:
+ *
+ *             @example
+ *             <!-- element with no properties - popup will be opened next to it in context style manually -->
+ *             <div id="linkId">Click to open context popup</div>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     // set opening popup on click event
+ *                     $("#linkId").on("click", function () {
+ *                             // opening with options
+ *                             $("#popup").popup("open", {link: "linkId", positionTo: "origin"});
+ *                     });
+ *             </script>
+ *
+ * These options can be also set globally and then method _open_ can be called without options. However, this solution can be used only for TAU API.
+ *
+ *             @example
+ *             <!-- element with no properties - popup will be opened next to it in context style manually -->
+ *             <div id="linkId">Link for popup</div>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     // set options
+ *                     var popupWidget = tau.widget.Popup(document.getElementById("popup"));
+ *                     popupWidget.option({positionTo: "origin", link: "linkId"}); // here we set positionTo and id of link, which sets placement of popup
+ *
+ *                     // set opening popup on click event
+ *                     document.getElementById("linkId").addEventListener("click", function () {
+ *                             //if options are set, we can call method open without options
+ *                             popupWidget.open();
+ *                     });
+ *             </script>
+ *
+ * For jQuery API, id of link has to be always added as a option:
+ *
+ *             @example
+ *             <!-- element with no properties - popup will be opened next to it in context style manually -->
+ *             <div id="linkId">Link for popup</div>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     // set option positionTo
+ *                     $("#popup").popup("option", "positionTo", "origin");
+ *
+ *                     // set opening popup on click event
+ *                     $("#linkId").on("click", function () {
+ *                             // for jQuery API, link has to be added as a option
+ *                             $("#popup").popup("open", {link: "linkId"});
+ *                     });
+ *             </script>
+ *
+ *
+ * ##Special classes
+ *
+ * There are some special CSS classes, which changes the style of popup:
+ *
+ *  - _center_info_ - basic pop-up message<br>
+ *  - _center_title_ - pop-up message with a title<br>
+ *  - _center_basic_1btn_ - pop-up message with 1 button<br>
+ *  - _center_basic_2btn_ - pop-up message with 2 horizontal buttons<br>
+ *  - _center_title_1btn_ - pop-up message with a title and 1 button<br>
+ *  - _center_title_2btn_ - pop-up message with a title and 2 horizontal buttons<br>
+ *  - _center_title_3btn_ - pop-up message with a title and 3 horizontal buttons<br>
+ *  - _center_button_vertical_ - pop-up message with vertical buttons<br>
+ *  - _center_checkbox_ - pop-up message with a check box<br>
+ *  - _center_liststyle_1btn_ - pop-up message with a list and 1 button<br>
+ *  - _center_liststyle_2btn_ - pop-up message with a list and 2 horizontal buttons<br>
+ *  - _center_liststyle_3btn_ - pop-up message with a list and 3 horizontal buttons<br>
+ *
+ * ##Methods
+ *
+ * To call method on widget you can use one of existing API:
+ *
+ * First API is from tau namespace:
+ *
+ *             @example
+ *             var popupElement = document.getElementById("popup"),
+ *                     popup = tau.widget.Popup(popupElement);
+ *
+ *             popup.methodName(methodArgument1, methodArgument2, ...);
+ *
+ * Second API is jQuery Mobile API and for call _methodName_ you can use:
+ *
+ *             @example
+ *             $(".selector").popup("methodName", methodArgument1, methodArgument2, ...);
+ *
+ * ##Opening popup
+ * There are two ways to open popup.
+ *
+ * ###Opening by clicking on link
+ *
+ * If link has _id_ of popup set as value of property _href_, then this popup will be opened after clicking on it.
+ *
+ *             @example
+ *             <!--definition of link, which opens popup with id popup-->
+ *             <a href="#popup">Click to open popup</a>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ * Be award that context popup with arrow will be opened if link has _id_ property set and _data-position-to="origin"_  as in this example:
+ *
+ *             @example
+ *             <!--definition of link, which opens context popup with id popup-->
+ *             <a href="#popup" id="linkId" data-position-to="origin" data-role="button" data-inline="true">Click to open context popup</a>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ * To open window popup, property _data-position-to="window"_ must be set in link or popup.
+ *
+ *             @example
+ *             <!--definition of link, which opens window popup with id popup-->
+ *             <a href="#popup" id="linkId" data-position-to="window">Click to open popup</a>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ * ###Opening manually
+ *
+ * To open popup with _id_ "popup", tau namespace can be used:
+ *
+ *             @example
+ *             <div id="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     var popupElement = document.getElementById("popup"),
+ *                             popup = tau.widget.Popup(popupElement);
+ *                     popup.open();
+ *             </script>
+ *
+ * If jQuery library is loaded, this method can be used:
+ *
+ *             @example
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     var popup = $("#popup").popup();
+ *                     popup.popup("open");
+ *             </script>
+ *
+ *
+ * ## Closing popup
+ *
+ * ###Closing by clicking on button inside
+ *
+ * If link inside popup has property _data-rel="back"_, then popup will be closed after clicking on it as in this example:
+ *
+ *             @example
+ *             <a href="#center_title_1btn" data-position-to="window">Click to open popup</a>
+ *             <!--definition of popup with a title and button-->
+ *             <div id="center_title_1btn" data-role="popup" class="center_title_1btn">
+ *                     <div class="ui-popup-title">
+ *                             <h1>Popup title</h1>
+ *                     </div>
+ *                     <div class="ui-popup-text">
+ *                             Pop-up dialog box, a child window that blocks user interaction to the parent windows
+ *                     </div>
+ *                     <div class="ui-popup-button-bg">
+ *                             <a data-role="button" data-rel="back" data-inline="true">Button</a>
+ *                     </div>
+ *             </div>
+ *
+ *
+ * The selector, which causes closing on click, can be changed by setting option _closeLinkSelector_ in popup.
+ *
+ * ###Closing manually
+ *
+ * To close popup with _id_ "popup", tau namespace can be used:
+ *
+ *             @example
+ *             <a href="#popup" data-position-to="window">Click to open popup</a>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     var popupElement = document.getElementById("popup"),
+ *                             popup = tau.widget.Popup(popupElement);
+ *                     // close popup after opening
+ *                     popupElement.addEventListener("popupafteropen", function () {
+ *                             popup.close();
+ *                     });
+ *             </script>
+ *
+ * If jQuery library is loaded, this method can be used:
+ *
+ *             @example
+ *             <a href="#popup" data-position-to="window">Click to open popup</a>
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     $("#popup").on("popupafteropen", function () {
+ *                             $("#popup").popup("close");
+ *                     });
+ *             </script>
+ *
+ * ## Handling Popup Events
+ *
+ * To use popup events, use the following code:
+ *
+ *             @example
+ *             <!-- Popup html code -->
+ *             <div id="popup" data-role="popup">
+ *                     <p>This is a completely basic popup, no options set.</p>
+ *             </div>
+ *
+ *             <script>
+ *                     // Use popup events
+ *                     var popup = document.getElementById("popup");
+ *                     popup.addEventListener("popupafteropen", function() {
+ *                             // Implement code for popupafteropen event
+ *                     });
+ *             </script>
+ *
+ * Full list of available events is in [events list section](#events-list).
+
+ * @since 2.0
+ * @class ns.widget.mobile.Popup
+ * @component-selector .ui-popup, [data-role]="popup"
+ * @extends ns.widget.core.Popup
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Michał Szepielak <m.szepielak@samsung.com>
+ */
+
+/**
+ * Triggered when process of opening popup is completed.
+ * The "popupafteropen" event is triggered when the popup has completely appeared on the screen and all associated animations have completed.
+ * @event popupafteropen
+ * @member ns.widget.mobile.Popup
+ */
+/**
+ * Triggered when process of opening popup is completed.
+ * The "popupshow" event is triggered when the popup has completely appeared on
+ * the screen and all associated animations have completed. This event is
+ * triggered in the same time as event "popupafteropen".
+ * @event popupshow
+ * @member ns.widget.mobile.Popup
+ */
+/**
+ * Triggered before a popup computes the coordinates where it will appear.
+ * The "beforeposition" event is triggered before the popup starts the opening animations and calculates the coordinates where it will appear on the screen. Handling this event gives an opportunity to modify the content of the popup before it appears on the screen.
+ * @event beforeposition
+ * @member ns.widget.mobile.Popup
+ */
+
+/**
+ * Triggered when the process of closing popup is completed.
+ * The "popupafterclose" event is triggered when the popup has completely disappeared from the screen and all associated animations have completed.
+ * @event popupafterclose
+ * @member ns.widget.mobile.Popup
+ */
+/**
+ * Triggered when the process of closing popup is completed.
+ * The "popuphide" event is triggered when the popup has completely disappeared
+ * from the screen and all associated animations have completed. This event is
+ * triggered at the same time as event "popupafterclose".
+ * @event popuphide
+ * @member ns.widget.mobile.Popup
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var CorePopup = ns.widget.core.ContextPopup,
+                               CorePopupPrototype = CorePopup.prototype,
+
+                               Listview = ns.widget.core.Listview,
+
+                               engine = ns.engine,
+
+                               doms = ns.util.DOM,
+
+                               POPUP_SELECTOR = "[data-role='popup'], .ui-popup",
+
+                               objectUtils = ns.util.object,
+
+                               utilSelector = ns.util.selectors,
+
+                               Popup = function () {
+                                       var self = this;
+
+                                       CorePopup.call(this);
+                                       // set options
+                                       self.options = objectUtils.merge(self.options, Popup.defaults);
+                                       self._positionCallback = null;
+                               };
+
+                       Popup.classes = CorePopup.classes;
+
+                       /**
+                       * @property {Object} options Object with default options
+                       * @property {string} [options.transition="none"] Sets the default transition for the popup.
+                       * @property {string} [options.positionTo="origin"] Sets the element relative to which the popup will be centered.
+                       * @property {Array} [options.directionPriority=["bottom", "top", "right", "left"]] Sets directions of popup's placement by priority.
+                       * First one has the highest priority, last the lowest. It is *deprecated* option.
+                       * @property {string} [options.closeLinkSelector="a[data-rel="back"]"] Sets selector for buttons in popup
+                       * @property {boolean} [options.history=false] Sets whether to alter the url when a popup is open to support the back button.
+                       * @member ns.widget.mobile.Popup
+                       */
+                       Popup.defaults = objectUtils.merge({}, CorePopup.defaults, {
+                               closeLinkSelector: "a[data-rel='back']",
+                               transition: "pop",
+                               directionPriority: ["bottom", "top", "right", "left"], /* deprecated */
+                               arrow: "b,t,r,l",
+                               positionTo: "origin"
+                       });
+
+                       Popup.events = objectUtils.merge({}, CorePopup.events, {
+                               AFTER_OPEN: "popupafteropen",
+                               AFTER_CLOSE: "popupafterclose"
+                       });
+
+                       Popup.selector = POPUP_SELECTOR;
+
+                       Popup.prototype = new CorePopup();
+
+                       /**
+                       * Build structure of popup widget
+                       * @method _build
+                       * @param {HTMLElement} element
+                       * @return {HTMLElement}
+                       * @protected
+                       * @member ns.widget.mobile.Popup
+                       */
+                       Popup.prototype._build = function (element) {
+                               var page = utilSelector.getClosestByClass(element, "ui-page") || document.body,
+                                       elementClassList = element.classList,
+                                       self = this,
+                                       i,
+                                       popupContentClassList,
+                                       DOMTokenListPrototype = DOMTokenList.prototype,
+                                       classListToSwap;
+
+                               if (element.parentNode !== page) {
+                                       page.appendChild(element);
+                               }
+                               element = CorePopupPrototype._build.call(self, element);
+                               popupContentClassList = self._ui.content.classList;
+
+                               //This is for backwards compatibility when
+                               //.ui-popup-activity class was in div with class
+                               //.ui-popup-content, now .ui-popup-activity class
+                               // should be placed in most outer Popup div that has class .ui-popup
+                               if (popupContentClassList.contains("ui-popup-activity")) {
+
+                                       classListToSwap = [];
+
+                                       for (i = 0; i < popupContentClassList.length; i++) {
+                                               if (popupContentClassList[i].indexOf("ui-popup-activity") !== -1) {
+                                                       classListToSwap.push(popupContentClassList[i]);
+                                               }
+                                       }
+
+                                       DOMTokenListPrototype.remove.apply(popupContentClassList, classListToSwap);
+                                       for (i = 0; i < classListToSwap.length; i++) {
+                                               elementClassList.add(classListToSwap[i]);
+                                       }
+                               }
+                               return element;
+                       };
+
+                       Popup.prototype._setDirectionPriority = function (element, value) {
+                               if (value) {
+                                       this.options.arrow = value.map(function (arrow) {
+                                               return arrow.charAt(0).toLowerCase();
+                                       }).join(",");
+                               }
+                       };
+
+                       /**
+                        * Refresh structure
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.mobile.Popup
+                        */
+                       Popup.prototype._refresh = function () {
+                               var self = this;
+
+                               if (this._isActive()) {
+                                       if (typeof self._positionCallback === "function") {
+                                               self._positionCallback();
+                                       }
+                                       CorePopupPrototype._refresh.call(this);
+                               }
+                       };
+
+                       /**
+                        * set height of content
+                        * @method _setContentHeight
+                        * @protected
+                        * @member ns.widget.mobile.Popup
+                        * */
+                       Popup.prototype._setContentHeight = function () {
+                               var computedMaxHeight = window.innerHeight - doms.getCSSProperty(this.element, "margin-top", 0, "float");
+
+                               CorePopupPrototype._setContentHeight.call(this, computedMaxHeight);
+                       };
+
+                       /**
+                        * Find clicked element.
+                        * @method _findClickedElement
+                        * @param {number} x
+                        * @param {number} y
+                        * @protected
+                        * @member ns.widget.mobile.Popup
+                        */
+                       Popup.prototype._findClickedElement = function (x, y) {
+                               var element = CorePopupPrototype._findClickedElement.call(this, x, y),
+                                       button = utilSelector.getClosestBySelector(element, engine.getWidgetDefinition("Button").selector);
+
+                               return button || element;
+                       };
+
+                       /**
+                        * Show popup
+                        * @method _show
+                        * @protected
+                        * @member ns.widget.mobile.Popup
+                        */
+                       Popup.prototype._show = function () {
+                               var self = this,
+                                       listviewElement,
+                                       listview;
+
+                               // Disabled colored list for contextual popups
+                               if (self.options.positionTo !== "window") {
+                                       listviewElement = self.element.querySelector("." + Listview.classes.LISTVIEW);
+                                       if (listviewElement) {
+                                               listview = engine.getBinding(listviewElement);
+                                               if (listview) {
+                                                       listview.option("coloredBackground", false);
+                                               }
+                                       }
+                               }
+
+                               CorePopupPrototype._show.call(self);
+                       };
+
+                       /**
+                        * Show popup
+                        * @method _onShow
+                        * @protected
+                        * @member ns.widget.mobile.Popup
+                        */
+                       Popup.prototype._onShow = function () {
+                               CorePopupPrototype._onShow.call(this);
+                               this.trigger(Popup.events.AFTER_OPEN);
+                       };
+
+                       /**
+                        * Hide popup
+                        * @method _onHide
+                        * @protected
+                        * @member ns.widget.mobile.Popup
+                        */
+                       Popup.prototype._onHide = function () {
+                               CorePopupPrototype._onHide.call(this);
+                               this.trigger(Popup.events.AFTER_CLOSE);
+                       };
+
+                       /**
+                        * Set callback, which is called on "resize" event. This callback should return desired position of popup after resizing.
+                        *
+                        * This function should be used instead of "setPositionCB".
+                        *
+                        *      @example
+                        *      <div id="popup" data-role="popup">
+                        *          <p>This is a completely basic popup, no options set.</p>
+                        *      </div>
+                        *
+                        *      <script>
+                        *          var popupWidget = tau.widget.Popup(document.getElementById("popup"));
+                        *
+                        *          popupWidget.setPositionCallback(function() {
+                        *                return {x: 10, y: 20};
+                        *         });
+                        *      </script>
+                        *
+                        * If jQuery is loaded:
+                        *
+                        *      @example
+                        *      <div id="popup" data-role="popup">
+                        *          <p>This is a completely basic popup, no options set.</p>
+                        *      </div>
+                        *
+                        *      <script>
+                        *          $("#popup").popup("setPositionCallback", function() {
+                        *                return {x: 10, y: 20};
+                        *          });
+                        *      </script>
+                        *
+                        * @method setPositionCallback
+                        * @param {Function} callback Function called on resizing. It should return desired position of popup as object with "x" and "y" properties.
+                        * @member ns.widget.mobile.Popup
+                        * @since 2.3
+                        */
+                       Popup.prototype.setPositionCallback = function (callback) {
+                               this._positionCallback = callback;
+                       };
+
+                       ns.widget.mobile.Popup = Popup;
+                       engine.defineWidget(
+                               "Popup",
+                               POPUP_SELECTOR,
+                               [
+                                       "open",
+                                       "close",
+                                       "reposition",
+                                       "setPositionCallback",
+                                       "setPositionCB"
+                               ],
+                               Popup,
+                               "mobile",
+                               true
+                       );
+                       }(window, window.document, ns));
+
+/*global window, define, ns*/
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * # ScrollView Widget
+ * Widgets allows for creating scrollable panes, lists, etc.
+ *
+ * ## Default selectors
+ * All elements with _data-role=content attribute or _.ui-scrollview
+ * css class will be changed to ScrollView widgets, unless they specify
+ * _data-scroll=none attribute.
+ *
+ * ### HTML Examples
+ *
+ * #### Data attribute
+ *
+ *             @example
+ *             <div data-role="page">
+ *                     <div data-role="content"><!-- this will become scrollview //-->
+ *                             content data
+ *                     </div>
+ *             </div>
+ *
+ * #### CSS Class
+ *
+ *             @example
+ *             <div data-role="page">
+ *                     <div class="ui-content"><!-- this will become scrollview //-->
+ *                             content data
+ *                     </div>
+ *             </div>
+ *
+ * ## Manual constructor
+ *
+ * To create the widget manually you can use 2 different APIs, the TAU
+ * API or jQuery API.
+ *
+ * ### Create scrollview by TAU API
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     </div>
+ *             </div>
+ *             <script>
+ *                     var page = tau.widget.Page(document.getElementById("myPage")),
+ *                             scrollview = tau.widget.Scrollview(page.ui.content);
+ *             </script>
+ *
+ * ### Create scrollview using jQuery API
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     </div>
+ *             </div>
+ *             <script>
+ *                     $("#myPage > div[data-role='content']").scrollview();
+ *             </script>
+ *
+ * ## Options for Scrollview widget
+ *
+ * Options can be set using data-* attributes or by passing them to
+ * the constructor.
+ *
+ * There is also a method **option** for changing them after widget
+ * creation.
+ *
+ * jQuery mobile format is also supported.
+ *
+ * ## Scroll
+ *
+ * This options specifies of a content element should become Scrollview
+ * widget.
+ *
+ * You can change this by all available methods for changing options.
+ *
+ * ### By data-scroll attribute
+ *
+ *             @example
+ *             <div data-role="page">
+ *                     <div data-role="content" data-scroll="none">
+ *                             content
+ *                     </div>
+ *             </div>
+ *
+ * ### By config passed to constructor
+ *
+ *             @example
+ *             <div class="myPageClass" data-role="page">
+ *                     <div data-role="content">
+ *                             content
+ *                     </div>
+ *             </div>
+ *             <script>
+ *                     var contentElement = document.querySelector(".myPageClass > div[data-role=content]");
+ *                     tau.widget.Scrollview(contentElement, {
+ *                             "scroll": false
+ *                     });
+ *             </script>
+ *
+ * ### By using jQuery API
+ *
+ *             @example
+ *             <div class="myPageClass" data-role="page">
+ *                     <div data-role="content">
+ *                             content
+ *                     </div>
+ *             </div>
+ *             <script>
+ *                     $(".myPageClass > div[data-role='content']").scrollview({
+ *                             "scroll": false
+ *                     });
+ *             </script>
+ *
+ * ## ScrollJumps
+ *
+ * Scroll jumps are small buttons which allow the user to quickly
+ * scroll to top or left
+ *
+ * You can change this by all available methods for changing options.
+ *
+ * ### By data-scroll-jump
+ *
+ *             @example
+ *             <div data-role="page">
+ *                     <div data-role="content" data-scroll-jump="true">
+ *                             content
+ *                     </div>
+ *             </div>
+ *
+ * ### By config passed to constructor
+ *
+ *             @example
+ *             <div class="myPageClass" data-role="page">
+ *                     <div data-role="content">
+ *                             content
+ *                     </div>
+ *             </div>
+ *             <script>
+ *                     var contentElement = document.querySelector(".myPageClass > div[data-role=content]");
+ *                     tau.widget.Scrollview(contentElement, {
+ *                             "scrollJump": true
+ *                     });
+ *             </script>
+ *
+ * ### By using jQuery API
+ *
+ *             @example
+ *             <div class="myPageClass" data-role="page">
+ *                     <div data-role="content">
+ *                             content
+ *                     </div>
+ *             </div>
+ *             <script>
+ *                     $(".myPageClass > div[data-role='content']").scrollview({
+ *                             "scrollJump": true
+ *                     });
+ *             </script>
+ *
+ * ## Methods
+ *
+ * Page methods can be called trough 2 APIs: TAU API and jQuery API
+ * (jQuery mobile-like API)
+ *
+ * @class ns.widget.mobile.Scrollview
+ * @extends ns.widget.core.Scrollview
+ *
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Grzegorz Osimowicz <g.osimowicz@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Hyunkook Cho <hk0713.cho@samsung.com>
+ * @author Junhyeon Lee <juneh.lee@samsung.com>
+ */
+/**
+ * Triggered when scrolling operation starts
+ * @event scrollstart
+ * @member ns.widget.mobile.Scrollview
+ */
+/**
+ * Triggered when scroll is being updated
+ * @event scrollupdate
+ * @member ns.widget.mobile.Scrollview
+ */
+/**
+ * Triggered when scrolling stops
+ * @event scrollstop
+ * @member ns.widget.mobile.Scrollview
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var Scrollview = ns.widget.core.Scrollview;
+
+                       ns.widget.mobile.Scrollview = Scrollview;
+                       ns.engine.defineWidget(
+                               "Scrollview",
+                               ".ui-content:not([data-scroll='none']):not([data-handler='true']):not(.ui-scrollview-clip)" +
+                                               ":not(.ui-scrolllistview):not(.ui-scrollhandler)" +
+                                               ", [data-scroll]:not([data-scroll='none']):not([data-handler='true']):not(.ui-scrollhandler)" +
+                                               ", .ui-scrollview:not([data-scroll='none']):not([data-handler='true']):not(.ui-scrollhandler)",
+                               [
+                                       "scrollTo",
+                                       "ensureElementIsVisible",
+                                       "centerToElement",
+                                       "getScrollPosition",
+                                       "skipDragging",
+                                       "translateTo"
+                               ],
+                               Scrollview,
+                               "tizen",
+                               true
+                       );
+                       }(window, window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * #BaseWidgetMobile
+ * Extension of class BaseWidget for mobile profile.
+ * This class has compatibility properties and methods with jQuery Mobile Widget.
+ * @class ns.widget.mobile.BaseWidgetMobile
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+       
+                       var BaseWidgetMobile = function () {
+                                       this.options = {};
+                               },
+                               BaseWidget = ns.widget.BaseWidget,
+                               basePrototype = BaseWidget.prototype,
+                               parentConfigure = basePrototype.configure,
+                               parentDisable = basePrototype.disable,
+                               parentEnable = basePrototype.enable,
+                               prototype = new BaseWidget(),
+                               slice = [].slice;
+
+                       BaseWidgetMobile.classes = BaseWidget.classes;
+
+                       /**
+                        * Configures widget object from definition.
+                        * @method configure
+                        * @param {Object} definition
+                        * @param {string} definition.name Name of widget
+                        * @param {string} definition.selector Selector of widget
+                        * @param {string} definition.binding Path to file with widget (without extension)
+                        * @param {HTMLElement} element
+                        * @param {Object} options Configure options
+                        * @member ns.widget.mobile.BaseWidgetMobile
+                        * @return {HTMLElement}
+                        * @instance
+                        */
+                       prototype.configure = function (definition, element, options) {
+                               var self = this,
+                                       definitionName,
+                                       widgetName;
+
+                               element = parentConfigure.call(self, definition, element, options);
+                               if (definition) {
+                                       definitionName = definition.name;
+                                       widgetName = definitionName && definitionName.toLowerCase();
+                                       /**
+                                        * @property {string} widgetName Widget base class
+                                        * @member ns.widget.mobile.BaseWidgetMobile
+                                        * @instance
+                                        */
+                                       self.widgetName = widgetName;
+                                       /**
+                                       * @property {string} widgetBaseClass Widget base class
+                                       * @member ns.widget.mobile.BaseWidgetMobile
+                                       * @instance
+                                       */
+                                       self.widgetBaseClass = self.namespace + "-" + widgetName;
+                                       /**
+                                       * @property {number} uuid Number id of widget instance
+                                       * @member ns.widget.mobile.BaseWidgetMobile
+                                       * @instance
+                                       */
+                                       self.uuid = ns.getNumberUniqueId();
+
+                                       /**
+                                        * @property {string} eventNamespace Namespace of widget events (suffix for events)
+                                        * @member ns.widget.mobile.BaseWidgetMobile
+                                        * @instance
+                                        */
+                                       self.eventNamespace = "." + widgetName + (self.uuid || "");
+
+                                       /**
+                                        * @property {string} [defaultElement='<div>'] Default element for the widget
+                                        * @member ns.widget.mobile.BaseWidgetMobile
+                                        * @instance
+                                        */
+                                       self.defaultElement = "<div>";
+                               }
+
+                               return element;
+                       };
+
+                       /**
+                       * Disables widget.
+                       * @method disable
+                       * @member ns.widget.mobile.BaseWidgetMobile
+                       * @instance
+                       */
+                       prototype.disable = function () {
+                               var self = this,
+                                       element = self.element,
+                                       elementClasses = element.classList,
+                                       args = slice.call(arguments);
+
+                               parentDisable.apply(self, args);
+                               elementClasses.add(self.widgetFullName + "-disabled");
+                       };
+
+                       /**
+                       * Enables widget.
+                       * @method enable
+                       * @member ns.widget.mobile.BaseWidgetMobile
+                       * @instance
+                       */
+                       prototype.enable = function () {
+                               var self = this,
+                                       element = self.element,
+                                       elementClasses = element.classList,
+                                       args = slice.call(arguments);
+
+                               parentEnable.apply(self, args);
+                               elementClasses.remove(self.widgetFullName + "-disabled");
+                       };
+
+                       /**
+                       * Throws exception.
+                       * @method raise
+                       * @param {?string} msg Message of throw
+                       * @member ns.widget.mobile.BaseWidgetMobile
+                       * @instance
+                       */
+                       prototype.raise = function (msg) {
+                               throw "Widget [" + this.widgetName + "]: " + msg;
+                       };
+
+                       /**
+                       * Returns element of widget.
+                       * @method widget
+                       * @member ns.widget.mobile.BaseWidgetMobile
+                       * @return {HTMLElement}
+                       * @instance
+                       */
+                       prototype.widget = function () {
+                               return this.element;
+                       };
+
+                       BaseWidgetMobile.prototype = prototype;
+
+                       // definition
+                       ns.widget.mobile.BaseWidgetMobile = BaseWidgetMobile;
+
+                       }(window.document, ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * #Expandable
+ * Expandable component allows you to expand or collapse content when tapped.
+ *
+ * ## Default selectors
+ * All elements with _data-role="expandable"_ or class _.ui-expandable_ are
+ * changed to expandable component.
+ *
+ * ###HTML Examples
+ *
+ * ####Create expandable div using data-role
+ *
+ *             @example
+ *             <div id="expandable" data-role="expandable">
+ *                     <h1>Expandable head</h1>
+ *                     <div>Content</div>
+ *             </div>
+ *
+ * ####Create Expandable list using data-role
+ *
+ *             @example
+ *             <ul data-role="listview">
+ *                     <li data-role="expandable">
+ *                             <h2>Expandable head</h2>
+ *                             <-- sub list -->
+ *                             <ul data-role="listview">
+ *                                     <li>sub list item1</li>
+ *                                     <li>sub list item2</li>
+ *                             </ul>
+ *                     </li>
+ *             </ul>
+ *
+ * ####Create part of list as expandable
+ *
+ *             @example
+ *             <ul data-role="listview">
+ *                     <li>list item1</li>
+ *                     <li>list item2</li>
+ *                     <li>list item3</li>
+ *                     <li>list item4</li>
+ *                     <li class="ui-expandable-from"></li>
+ *                     <li>list item5</li>
+ *                     <li>list item6</li>
+ *                     <li>list item7</li>
+ *                     <li>list item8</li>
+ *             </ul>
+ *
+ * ####Create using class selector
+ *
+ *             @example
+ *             <div id="expandable" class="ui-expandable">
+ *                     <h1>Expandable head</h1>
+ *                     <div>Content</div>
+ *             </div>
+ *
+ * ## Manual constructor
+ * For manual creation of Expandable component you can use constructor of component
+ * from **tau** namespace:
+ *
+ *             @example
+ *             <script>
+ *                     var expandableElement = document.getElementById("expandable"),
+ *                             expandable = tau.widget.Expandable(expandableElement,
+ *                                     {collapsed: false});
+ *             </script>
+ *
+ * Constructor has one require parameter **element** which are base
+ * **HTMLElement** to create widget. We recommend get this element by method
+ * *document.getElementById*. Second parameter is **options** and it is
+ * a object with options for widget.
+ *
+ * ##Options for Collapsible Widget
+ *
+ * You can change option for widget using method **option**.
+ *
+ * ##Methods
+ *
+ * To call method on widget you can use one of existing API:
+ *
+ *             @example
+ *             var expandableElement = document.getElementById("expandable"),
+ *                     expandable = tau.widget.Expandable(expandableElement);
+ *
+ *             expandable.methodName(methodArgument1, methodArgument2, ...);
+ *
+ * @since 2.4
+ * @class ns.widget.mobile.Expandable
+ * @component-selector .ui-expandable [data-role]="expandable .ui-expandable-from"
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Marcin Jakuszko <m.jakuszko@samsung.com>
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ * @author Heeju Joo <heeju.joo@samsung.com>
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               /**
+                                * @property {Object} BaseWidget alias variable
+                                * @private
+                                * @static
+                                */
+                       var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               /**
+                                * @property {Object} engine alias variable
+                                * @private
+                                * @static
+                                */
+                               engine = ns.engine,
+                               /**
+                                * @property {Object} selectorsUtil alias variable
+                                * @private
+                                * @static
+                                */
+                               selectorsUtil = ns.util.selectors,
+                               /**
+                                * @property {Object} eventUtil alias variable
+                                * @private
+                                * @static
+                                */
+                               eventUtil = ns.event,
+                               /**
+                                * @property {Object} domUtils alias variable
+                                * @private
+                                * @static
+                                */
+                               domUtils = ns.util.DOM,
+
+                               /**
+                                * Dictionary object containing commonly used widget classes
+                                * @property {Object} classes
+                                * @readonly
+                                * @static
+                                * @member ns.widget.mobile.Expandable
+                                */
+                               classes = {
+                                       /**
+                                        * Standard expandable widget
+                                        * @style ui-expandable
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       uiExpandable: "ui-expandable",
+                                       /**
+                                        * Set content to expandable widget
+                                        * @style ui-expandable-content
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       uiExpandableContent: "ui-expandable-content",
+                                       /**
+                                        * Set collapsed content to expandable widget
+                                        * @style ui-expandable-content-collapsed
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       uiExpandableContentCollapsed: "ui-expandable-content-collapsed",
+                                       /**
+                                        * Set expandable widget as collapsed
+                                        * @style ui-expandable-collapsed
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       uiExpandableCollapsed: "ui-expandable-collapsed",
+                                       /**
+                                        * Set expandable widget as expanded
+                                        * @style ui-expandable-collapsed
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       uiExpandableExpanded: "ui-expandable-expanded",
+                                       /**
+                                        * Set heading to expandable widget
+                                        * @style ui-expandable-heading
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       uiExpandableHeading: "ui-expandable-heading",
+                                       /**
+                                        * Set collapsed heading to expandable widget
+                                        * @style ui-expandable-heading-collapsed
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       uiExpandableHeadingCollapsed: "ui-expandable-heading-collapsed",
+                                       /**
+                                        * Set toggle to expandable widget heading
+                                        * @style ui-expandable-heading-toggle
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       uiExpandableHeadingToggle: "ui-expandable-heading-toggle",
+                                       /**
+                                        * Set active to expandable widget heading
+                                        * @style ui-expandable-heading-active
+                                        * @member ns.widget.mobile.Expandable,
+                                        */
+                                       uiExpandableHeadingActive: "ui-expandable-heading-active",
+                                       /**
+                                        * Set active to expandable widget heading
+                                        * @style ui-expandable-heading-active
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       expandButton: "ui-expand-button",
+                                       /**
+                                        * All sibling elements after this element will be toggled
+                                        * @style ui-expandable-from
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       expandFrom: "ui-expandable-from",
+                                       /**
+                                        * All sibling elements before this element will be toggled.
+                                        * On this class will be build widget too
+                                        * @style ui-expandable-to
+                                        * @member ns.widget.mobile.Expandable
+                                        */
+                                       expandTo: "ui-expandable-to"
+                               },
+
+                               /**
+                                * @property {Object} selectors selectors used in this widget
+                                * @private
+                                * @static
+                                */
+                               selectors = {
+                                       HEADING: "h1,h2,h3,h4,h5,h6,legend,li",
+                                       BUTTON: "." + classes.expandButton
+                               },
+
+                               Expandable = function () {
+                                       var self = this;
+
+                                       /**
+                                        * Expandable widget options.
+                                        * @property {boolean} [options.collapsed=true] Determines if content should be collapsed on load
+                                        * @property {string} [options.heading="h1,h2,h3,h4,h5,h6,legend,li"] Within the Expandable container, the first immediate child element
+                                        * that matches this selector will be used as the header for the Expandable.
+                                        * @property {string} [options.expander="heading"] Determines which part of widget expands content: "heading", "button"
+                                        */
+                                       self.options = {
+                                               collapsed: true,
+                                               heading: selectors.HEADING,
+                                               expander: "heading"
+                                       };
+
+                                       self._eventHandlers = {};
+                                       self._ui = {
+                                               heading: null,
+                                               expandableHeadingContent: null,
+                                               expandButton: null,
+                                               expandFrom: null,
+                                               expandTo: null
+                                       };
+
+                               },
+                               prototype = new BaseWidget();
+
+                       Expandable.prototype = prototype;
+                       Expandable.classes = classes;
+                       Expandable.selectors = selectors;
+
+                       /**
+                        * Handler function for expanding/collapsing widget
+                        * @method toggleExpandableHandler
+                        * @param {ns.widget.mobile.Expandable} self
+                        * @param {HTMLElement} element
+                        * @param {Event} event
+                        * @private
+                        */
+                       function toggleExpandableHandler(self, element, event) {
+                               var     ui = self._ui,
+                                       elementClassList = element.classList,
+                                       heading = ui.heading,
+                                       headingClassList,
+                                       content = ui.expandableContent,
+                                       contentClassList,
+                                       isCollapse = event.type === "collapse";
+
+                               if (event.defaultPrevented) {
+                                       return;
+                               }
+
+                               event.preventDefault();
+
+                               if (ui.expandFrom) {
+                                       if (isCollapse) {
+                                               ui.expandFrom.classList.remove(classes.uiExpandableExpanded);
+                                       } else {
+                                               ui.expandFrom.classList.add(classes.uiExpandableExpanded);
+                                       }
+                               } else {
+                                       headingClassList = heading.classList;
+                                       contentClassList = content.classList;
+                                       //Toggle functions switched to if/else statement due to toggle bug on Tizen
+                                       if (isCollapse) {
+                                               elementClassList.add(classes.uiExpandableCollapsed);
+                                               headingClassList.add(classes.uiExpandableHeadingCollapsed);
+                                               contentClassList.add(classes.uiExpandableContentCollapsed);
+                                       } else {
+                                               elementClassList.remove(classes.uiExpandableCollapsed);
+                                               headingClassList.remove(classes.uiExpandableHeadingCollapsed);
+                                               contentClassList.remove(classes.uiExpandableContentCollapsed);
+                                       }
+                                       content.setAttribute("aria-hidden", isCollapse);
+                               }
+                               eventUtil.trigger(element, isCollapse ? "collapsed" : "expanded");
+                       }
+
+                       function setHeadingActiveClassHandler(self, setClass) {
+                               var heading = self._ui.heading,
+                                       headingClassList;
+
+                               if (heading) {
+                                       headingClassList = self._ui.heading.classList;
+                                       if (setClass) {
+                                               headingClassList.add(classes.uiExpandableHeadingActive);
+                                       } else {
+                                               headingClassList.remove(classes.uiExpandableHeadingActive);
+                                       }
+                               }
+                       }
+
+                       function toggleEventTypeHandler(self, event) {
+                               var element = self.element,
+                                       ui = self._ui,
+                                       heading = ui.heading,
+                                       expandFrom = ui.expandFrom,
+                                       eventType;
+
+                               if (heading) {
+                                       eventType = heading.classList.contains(classes.uiExpandableHeadingCollapsed) ? "expand" : "collapse";
+                               } else if (expandFrom) {
+                                       eventType = expandFrom.classList.contains(classes.uiExpandableExpanded) ? "collapse" : "expand";
+                               }
+
+                               eventUtil.trigger(element, eventType);
+
+                               event.preventDefault();
+                               eventUtil.stopPropagation(event);
+                       }
+
+                       /**
+                        * Method tries to find expandable heading or create new if not exists
+                        * @method _getExpandableHeading
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.Expandable
+                        */
+                       prototype._getExpandableHeading = function (element) {
+                               var options = this.options,
+                                       // First child matching selector is Expandable header
+                                       expandableHeading = selectorsUtil.getChildrenBySelector(element, options.heading)[0],
+                                       alternativeHeading;
+
+                               if (!expandableHeading) {
+                                                                               expandableHeading = document.createElement("h1");
+                                       element.appendChild(expandableHeading);
+                               }
+
+                               if (expandableHeading.tagName.toLowerCase() === "legend") {
+                                       alternativeHeading = document.createElement("div");
+                                       alternativeHeading.setAttribute("role", "heading");
+                                       alternativeHeading.innerHTML = expandableHeading.innerHTML;
+                                       element.replaceChild(alternativeHeading, expandableHeading);
+                                       expandableHeading = alternativeHeading;
+                               }
+
+                               return expandableHeading;
+                       };
+
+                       /**
+                        * Method tries to find expandable content or create new if not exists
+                        * @method _getExpandableContent
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @param {HTMLElement} expandableHeading
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.Expandable
+                        */
+                       prototype._getExpandableContent = function (element, expandableHeading) {
+                               var expandableContent = element.querySelector("." + classes.uiExpandableContent);
+
+                               if (!expandableContent) {
+                                       // Wrap all widget content
+                                       domUtils.wrapInHTML(element.childNodes, "<div class='" + classes.uiExpandableContent + "'></div>");
+
+                                       // Move header out
+                                       element.insertBefore(expandableHeading, element.firstChild);
+                                       domUtils.wrapInHTML(expandableHeading.childNodes, "<a class='" + classes.uiExpandableHeadingToggle + "' tabindex='0'></a>");
+                                       expandableContent = expandableHeading.nextElementSibling;
+                               }
+                               return expandableContent;
+                       };
+
+                       /**
+                        * Build list item for expand button on the end of listview
+                        * @method _createExpandButton
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.Expandable
+                        */
+                       prototype._createExpandTo = function (element) {
+                               var expandTo = element.parentElement.querySelector("." + classes.expandTo);
+
+                               if (!expandTo) {
+                                       expandTo = document.createElement("li");
+                                       expandTo.classList.add(classes.expandTo);
+                                       expandTo.setAttribute("data-expander", "button");
+                                       // append to listview
+                                       element.parentElement.appendChild(expandTo);
+                               }
+
+                               return expandTo;
+                       }
+
+                       /**
+                        * Build expand button on listview item
+                        * @method _createExpandButton
+                        * @protected
+                        * @param {HTMLElement} expandTo
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.Expandable
+                        */
+                       prototype._createExpandButton = function (expandTo) {
+                               var button = expandTo.querySelector(selectors.BUTTON);
+
+                               if (!button) {
+                                       button = document.createElement("a");
+                                       button.classList.add("ui-btn");
+                                       expandTo.appendChild(button);
+                                       button.setAttribute("href", "#");
+                               }
+                               button.setAttribute("data-icon", "down");
+                               button.setAttribute("data-style", "flat");
+                               button.classList.add(classes.expandButton);
+
+                               return button;
+                       }
+
+                       /**
+                        * Build widget structure
+                        * @method _build
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.Expandable
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       elementClassList = element.classList,
+                                       expandableHeading,
+                                       expandableContent;
+
+                               if (element.classList.contains(classes.expandFrom)) {
+                                       ui.expandFrom = element;
+                                       ui.expandTo = self._createExpandTo(element);
+                                       ui.expandButton = element.querySelector(selectors.BUTTON) ||
+                                               ui.expandTo.querySelector(selectors.BUTTON);
+                                       if (!ui.expandButton) {
+                                               ui.expandButton = self._createExpandButton(ui.expandTo);
+                                       }
+                               } else {
+                                       if ((element.parentNode && element.parentNode.tagName.toLowerCase() === "ul") && (element.tagName.toLowerCase() === "div")) {
+                                               ns.warn("Don't make the Expandable list using <div>. It violates standard of HTML rule. Instead of, please use <li>.");
+                                       }
+                                       elementClassList.add(classes.uiExpandable);
+
+                                       expandableHeading = self._getExpandableHeading(element);
+                                       expandableHeading.classList.add(classes.uiExpandableHeading);
+
+                                       expandableContent = self._getExpandableContent(element, expandableHeading);
+
+                                       ui.heading = expandableHeading;
+                                       ui.expandableContent = expandableContent;
+                               }
+                               return element;
+                       };
+
+                       /**
+                        * Init widget structure
+                        * @method _init
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.Expandable
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui;
+
+                               ui.heading = ui.heading || selectorsUtil.getChildrenByClass(element, classes.uiExpandableHeading)[0];
+                               ui.expandableContent = ui.expandableContent || element.querySelector("." + classes.uiExpandableContent);
+
+                               if (ui.expandTo) {
+                                       ui.expandButton = ui.expandButton || ui.expandTo.querySelector(selectors.BUTTON);
+                                       ns.widget.Button(ui.expandButton);
+                                       if (self.options.collapsed) {
+                                               element.classList.remove(classes.uiExpandableExpanded);
+                                       }
+                               } else {
+                                       ui.expandButton = ui.expandButton || element.querySelector(selectors.BUTTON);
+                                       if (self.options.collapsed) {
+                                               element.classList.add(classes.uiExpandableCollapsed);
+                                               if (ui.heading) {
+                                                       ui.heading.classList.add(classes.uiExpandableHeadingCollapsed);
+                                               }
+                                               if (ui.expandableContent) {
+                                                       ui.expandableContent.classList.add(classes.uiExpandableContentCollapsed);
+                                               }
+                                       }
+                               }
+
+                               return element;
+                       };
+
+                       /**
+                        * Bind widget events
+                        * @method _bindEvents
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @member ns.widget.mobile.Expandable
+                        */
+                       prototype._bindEvents = function (element) {
+                               var self = this,
+                                       eventHandlers = self._eventHandlers,
+                                       ui = self._ui,
+                                       heading = ui.heading;
+
+                               // Declare handlers with and assign them to local variables
+                               eventHandlers.toggleExpandable = toggleExpandableHandler.bind(null, self, element);
+                               eventHandlers.removeActiveClass = setHeadingActiveClassHandler.bind(null, self, false);
+                               eventHandlers.addActiveClass = setHeadingActiveClassHandler.bind(null, self, true);
+                               eventHandlers.toggleEventType = toggleEventTypeHandler.bind(null, self);
+
+                               eventUtil.on(element, "expand collapse", eventHandlers.toggleExpandable, false);
+
+                               if (heading) {
+                                       eventUtil.on(heading, "vmousedown", eventHandlers.addActiveClass, false);
+                                       eventUtil.on(heading, "vmousemove vmousecancel vmouseup", eventHandlers.removeActiveClass, false);
+                                       eventUtil.on(heading, "vclick", eventHandlers.toggleEventType, false);
+                               } else if (ui.expandTo) {
+                                       eventUtil.on(ui.expandButton, "vclick", eventHandlers.toggleEventType, false);
+                               }
+                       };
+
+                       /**
+                        * This method refreshes Expandable.
+                        *
+                        *              @example
+                        *              <div id="Expandable" data-role="expandable">
+                        *                      <h6>Expandable head</h6>
+                        *                      <div>Content</div>
+                        *              </div>
+                        *
+                        *              <script>
+                        *                      var ExpandableWidget = tau.widget.Expandable(document.getElementById("Expandable"));
+                        *                      ExpandableWidget.refresh();
+                        *              </script>
+                        *
+                        * @method refresh
+                        * @chainable
+                        * @member ns.widget.mobile.Expandable
+                        */
+
+                       /**
+                       * Refresh structure
+                       * @method _refresh
+                       * @protected
+                       * @member ns.widget.mobile.Expandable
+                       */
+                       prototype._refresh = function () {
+                               return;
+                       };
+
+                       /**
+                        * Removes the Expandable functionality completely.
+                        *
+                        *              @example
+                        *              <div id="Expandable" data-role="expandable">
+                        *                      <h6>Expandable head</h6>
+                        *                      <div>Content</div>
+                        *              </div>
+                        *
+                        *              <script>
+                        *                      var ExpandableWidget = tau.widget.Expandable(document.getElementById("Expandable"));
+                        *                      ExpandableWidget.destroy();
+                        *              </script>
+                        *
+                        * @method destroy
+                        * @member ns.widget.mobile.Expandable
+                        */
+
+                       /**
+                        * Destroy widget
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.mobile.Expandable
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       element = self.element,
+                                       ui = self._ui,
+                                       heading = ui.heading,
+                                       eventHandlers = self._eventHandlers,
+                                       parentNode = element.parentNode;
+
+                               eventUtil.off(element, "expand collapse", eventHandlers.toggleExpandable, false);
+
+                               if (heading) {
+                                       eventUtil.off(heading, "vmousedown", eventHandlers.addActiveClass, false);
+                                       eventUtil.off(heading, "vmousemove vmousecancel vmouseup", eventHandlers.removeActiveClass, false);
+                                       eventUtil.off(heading, "vclick", eventHandlers.toggleEventType, false);
+                               } else if (ui.expandTo) {
+                                       eventUtil.off(ui.expandButton, "vclick", eventHandlers.toggleEventType, false);
+                               }
+
+                               self._ui = null;
+                               self._eventHandlers = null;
+
+                               eventUtil.trigger(document, "destroyed", {
+                                       widget: "Expandable",
+                                       parent: parentNode
+                               });
+                       };
+
+                       // definition
+                       ns.widget.mobile.Expandable = Expandable;
+                       engine.defineWidget(
+                               "Expandable",
+                               "[data-role='expandable'], .ui-expandable, .ui-expandable-from",
+                               [],
+                               Expandable,
+                               "mobile"
+                       );
+                       }(window.document, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global define, ns */
+/**
+ * # List View
+ * List view component is used to display, for example, navigation data,
+ * results, and data entries, in a list format.
+ *
+ * ## Default selectors
+ * All elements which have a data-role [data-role="listview"] or class .ui-listview
+ * will become Listview widgets. It is recommended to use UL, LI tags for list creation
+ *
+ * ###HTML examples
+ *
+ * ####Create a page widget using the data-role attribute
+ *
+ *      @example
+ *      <ul data-role="listview">
+ *          <li>
+ *              ...some item
+ *          </li>
+ *      </ul>
+ *
+ * #### Create a listview widget using css classes
+ *
+ *      @example
+ *      <ul class="ui-listview">
+ *          <li>
+ *            ...some item
+ *          </li>
+ *      </ul>
+ *
+ * ### Manual constructor
+ *
+ * These examples show how to create a Listview widget by hand using
+ * JavaScript code
+ *
+ * #### Created using TAU api
+ *
+ *      @example
+ *      <ul class="ui-listview ui-colored-list" id="list">
+ *          <li class="ui-li-flex">
+ *               <span class="ui-li-area ui-li-area-a">
+ *                   <span class="ui-li-text">
+ *                        <span>1 text...</span>
+ *                   </span>
+ *               </span>
+ *           </li>
+ *      </ul>
+ *
+ *      <script type="text/javascript">
+ *          var listview = tau.widget.Listview(document.getElementById("list"));
+ *      </script>
+ *
+ * #### Create reorder list with TAU api
+ *
+ *      @example
+ *      <a class="ui-btn" id="dragButton">DRAG</a>
+ *      <ul class="ui-listview ui-colored-list" id="reorder">
+ *          <li class="ui-li-flex">
+ *              <span>1 text...</span>
+ *          </li>
+ *          <li class="ui-li-flex">
+ *              <span>2 text...</span>
+ *          </li>
+ *      </ul>
+ *
+ *      <script type="text/javascript">
+ *        var listview = tau.widget.Listview(document.getElementById("reorder"));
+ *        var dragButton = document.getElementById("dragButton");
+ *
+ *        tau.event.on(dragButton, "click", function(){
+ *            listview.toggleDragMode();
+ *        });
+ *      </script>
+ *
+ * ## Options for Listview widget
+ *
+ * Options can be set by using data-* attributes or by passing them
+ * to the constructor.
+ *
+ * There is also a method **option** for changing them after widget
+ * creation.
+ *
+ * @class ns.widget.mobile.Listview
+ * @component-selector .ui-listview, [data-role]="listview"
+ * @extends ns.widget.core.Listview
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @since 2.0
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var Page = ns.widget.core.Page,
+                               Popup = ns.widget.mobile.Popup,
+                               Scrollview = ns.widget.mobile.Scrollview,
+                               CoreListview = ns.widget.core.Listview,
+                               CoreListviewProto = CoreListview.prototype,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               utils = ns.util,
+                               objectUtils = utils.object,
+                               selectorUtils = utils.selectors,
+                               eventUtils = ns.event,
+                               now = Date.now,
+                               colorDefinitionRegex = new RegExp("[^0-9\-\.:,]+", "gi"),
+                               min = Math.min,
+                               max = Math.max,
+                               round = Math.round,
+                               ceil = Math.ceil,
+                               slice = [].slice,
+                               utilsEvents = ns.event,
+                               isNumber = utils.isNumber,
+                               colorTmp = [0, 0, 0, 0],
+                               MAX_IDLE_TIME = 3 * 1000, //3s
+                               direction = {
+                                       PREV: -1,
+                                       HOLD: 0,
+                                       NEXT: 1
+                               },
+                               Listview = function () {
+                                       var self = this,
+                                               /**
+                                                * @property {Object} options
+                                                * @property {boolean} options.coloredBackground=false enables/disables colored background
+                                                */
+                                               options = {
+                                                       coloredBackground: false,
+                                                       colorRestOfTheScreenBellow: true,
+                                                       colorRestOfTheScreenAbove: true,
+                                                       firstColorStep: 0,
+                                                       lastColorStep: 0,
+                                                       multipleSelection: false
+                                               };
+
+                                       CoreListview.call(self);
+                                       BaseKeyboardSupport.call(self);
+
+                                       // merge options from prototype
+                                       self.options = (!self.options) ?
+                                               options :
+                                               objectUtils.fastMerge(self.options, options);
+
+                                       // async function (requestAnimationFrame)
+                                       self._async = utils.requestAnimationFrame;
+                                       // rendering context
+                                       self._context = null;
+                                       // canvas elements style
+                                       self._canvasStyle = null;
+                                       // detected parent scrollable element
+                                       self._scrollableContainer = null;
+                                       // detected parent page element
+                                       self._pageContainer = null;
+                                       // detected parent popup element
+                                       self._popupContainer = null;
+                                       // drawCallback
+                                       self._drawCallback = null;
+                                       // scrollCallback
+                                       self._scrollCallback = null;
+                                       // _backgroundRenderCallback
+                                       self._backgroundRenderCallback = null;
+                                       // flag for async timers
+                                       self._running = false;
+                                       // flag for drawing
+                                       self._redraw = false;
+                                       // starting default color for gradient background
+                                       self._colorBase = [250, 250, 250, 1];
+                                       // color modifier for each background gradient step
+                                       self._colorStep = [0, 0, 0, -0.04];
+                                       // _lastChange
+                                       self._lastChange = 0;
+                                       // arrays of neighbor colored listview related to parent
+                                       self._siblingListsBellow = [];
+                                       self._siblingListsAbove = [];
+
+                                       initializeGlobalsForDrag(self);
+                               },
+                               WIDGET_SELECTOR = "[data-role='listview'], .ui-listview",
+                               /**
+                                * @property {Object} classes
+                                * @property {string} classes.BACKGROUND_LAYER
+                                * @property {string} classes.GRADIENT_BACKGROUND_DISABLED
+                                * @member ns.widget.mobile.Listview
+                                * @static
+                                * @readonly
+                                */
+                               classes = {
+                                       /**
+                                        * Set background for listview widget
+                                        * @style ui-listview-background
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "BACKGROUND_LAYER": "ui-listview-background",
+                                       /**
+                                        * Set background as disable for listview widget
+                                        * @style ui-listview-background-disabled
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "GRADIENT_BACKGROUND_DISABLED": "ui-listview-background-disabled",
+                                       /**
+                                        * Set index for group in listview widget
+                                        * @style ui-group-index
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "GROUP_INDEX": "ui-group-index",
+                                       /**
+                                        * Set listview to show in popup widget
+                                        * @style ui-popup-listview
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "POPUP_LISTVIEW": "ui-popup-listview",
+                                       /**
+                                        * Set drag as active for listview widget
+                                        * @style ui-drag-active
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "DRAG_ACTIVE": "ui-drag-active",
+                                       /**
+                                        * Set expandable widget. Expandable component allows you to expand or collapse content when tapped.
+                                        * @style ui-expandable
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "EXPANDABLE": "ui-expandable",
+                                       /**
+                                        * Set element as listview item
+                                        * @style ui-listview-item
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "ITEM": "ui-listview-item",
+                                       /**
+                                        * Set element as active listview item
+                                        * @style ui-listview-item-active
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "ITEM_ACTIVE": "ui-listview-item-active",
+                                       /**
+                                        * Set list item selected
+                                        * @style ui-li-selected
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "ITEM_SELECTED": "ui-li-selected",
+                                       /**
+                                        * Set helper for listview widget
+                                        * @style ui-listview-helper
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "HELPER": "ui-listview-helper",
+                                       /**
+                                        * Create holder element to help reordering
+                                        * @style ui-listview-holder
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "HOLDER": "ui-listview-holder",
+                                       "SNAPSHOT": "ui-snapshot",
+                                       /**
+                                        * Create handler for listview widget
+                                        * @style ui-listview-handler
+                                        * @member ns.widget.mobile.Listview
+                                        */
+                                       "HANDLER": "ui-listview-handler",
+                                       "DRAG_MODE": "ui-drag-mode",
+                                       "ACTIVATE_HANDLERS": "ui-activate-handlers",
+                                       "CANCEL_ANIMATION": "ui-cancel-animation",
+                                       "DEACTIVATE_HANDLERS": "ui-deactivate-handlers",
+                                       "FOCUS": "ui-listview-focus",
+                                       "ITEMFOCUS": "ui-listview-item-focus"
+                               },
+
+                               /**
+                                * @property {Object} events
+                                * @property {string} events.BACKGROUND_RENDER
+                                * @member ns.widget.mobile.Listview
+                                * @static
+                                * @readonly
+                                */
+                               events = {
+                                       "BACKGROUND_RENDER": "event-listview-background-render",
+                                       "REORDER": "listviewreorder"
+                               },
+                               engine = ns.engine,
+                               prototype = new CoreListview();
+
+                       /**
+                        * Set globals for drag functionality, constructor helper
+                        * @method initializeGlobalsForDrag
+                        * @param {Object} self
+                        * @member ns.widget.mobile.Listview
+                        * @private
+                        */
+                       function initializeGlobalsForDrag(self) {
+                               self._topOffset = window.innerHeight;
+                               self._previousVisibleElement = null;
+                               self._canvasWidth = 0;
+                               self._canvasHeight = 0;
+
+                               self._dragMode = false;
+                               self.originalListPosition = 0;
+                               self.indexDraggingElement = 0;
+
+                               self._ui = {
+                                       helper: {},
+                                       holder: {}
+                               };
+
+                               self._snapshotItems = [];
+                               self._liElements = [];
+                               self.topValue = 0;
+                               self.isScrolling = null;
+                               self._reorderElements = [];
+                       }
+
+                       /**
+                        * Modifies input color array (rgba) by a specified
+                        * modifier color array (rgba)
+                        * @method modifyColor
+                        * @param {Array} color input array of color values (rgba)
+                        * @param {Array} modifier array of color values (rgba)
+                        * @member ns.widget.mobile.Listview
+                        * @return {number} Return opacity of color
+                        * @private
+                        */
+                       function modifyColor(color, modifier) {
+                               color[0] += modifier[0];
+                               color[1] += modifier[1];
+                               color[2] += modifier[2];
+                               color[3] += modifier[3];
+
+                               color[0] = min(max(0, color[0]), 255);
+                               color[1] = min(max(0, color[1]), 255);
+                               color[2] = min(max(0, color[2]), 255);
+                               color[3] = min(max(0, color[3]), 1);
+
+                               return color[3];
+                       }
+
+                       /**
+                        * Copies values from one color array (rgba) to other
+                        * @method copyColor
+                        * @param {Array} inc color array (rgba)
+                        * @param {Array} out color array (rgba)
+                        * @member ns.widget.mobile.Listview
+                        * @private
+                        */
+                       function copyColor(inc, out) {
+                               out[0] = inc[0];
+                               out[1] = inc[1];
+                               out[2] = inc[2];
+                               out[3] = inc[3];
+                       }
+
+                       /**
+                        * Returns number from specified value (mixed) or
+                        * 0 if no param is not a number
+                        * @method toNumber
+                        * @param {mixed} val
+                        * @return {number}
+                        * @member ns.widget.mobile.Listview
+                        * @private
+                        */
+                       function toNumber(val) {
+                               var res = parseFloat(val);
+
+                               // fast NaN check
+                               if (res === res) {
+                                       return res;
+                               }
+
+                               return 0;
+                       }
+
+                       Listview.classes = objectUtils.fastMerge(classes, CoreListview.classes);
+                       Listview.events = events;
+
+                       function changeLiSelection(checkbox) {
+                               var liElement = selectorUtils.getClosestByTag(checkbox, "li");
+
+                               if (liElement) {
+                                       if (checkbox.checked) {
+                                               liElement.classList.add(classes.ITEM_SELECTED);
+                                       } else {
+                                               liElement.classList.remove(classes.ITEM_SELECTED);
+                                       }
+                               }
+                       }
+
+                       function onChangeSelection(event) {
+                               var target = event.target;
+
+                               if (target.tagName === "INPUT" && target.type === "checkbox") {
+                                       changeLiSelection(target);
+                               }
+                       }
+
+                       /**
+                        * Enables / disables multiple selection on listview
+                        * @method _setMultipleSelection
+                        * @param {HTMLElement} element Main element of widget
+                        * @param {boolean} enabled option value
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._setMultipleSelection = function (element, enabled) {
+                               if (enabled) {
+                                       element.addEventListener("change", onChangeSelection, true);
+                               } else {
+                                       element.removeEventListener("change", onChangeSelection, true);
+                               }
+                               this.options.multipleSelection = enabled;
+                       };
+
+                       prototype._setFirstColorStep = function (element, value) {
+                               value = parseInt(value, 10);
+                               this.options.firstColorStep = value;
+
+                               return true;
+                       }
+
+                       /**
+                        * Enables / disables colored background
+                        * @method _setColoredBackground
+                        * @param {HTMLElement} element Main element of widget
+                        * @param {boolean} value option value
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._setColoredBackground = function (element, value) {
+                               element.classList.toggle(classes.GRADIENT_BACKGROUND_DISABLED, !value);
+                               this.options.coloredBackground = value;
+                       };
+
+                       prototype._addCanvas = function (element) {
+                               var canvas = document.createElement("canvas"),
+                                       context = canvas.getContext("2d");
+
+                               canvas.classList.add(classes.BACKGROUND_LAYER);
+                               element.insertBefore(canvas, element.firstElementChild);
+                               this._context = context;
+
+                               return canvas;
+                       }
+
+                       /**
+                        * Builds widget
+                        * @method _build
+                        * @param {HTMLElement} element Main element of widget
+                        * @member ns.widget.mobile.Listview
+                        * @return {HTMLElement}
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       newElement = CoreListviewProto._build.call(self, element),
+                                       isChildListview = element &&
+                                               selectorUtils.getClosestByClass(element.parentElement, "ui-listview");
+
+                               self._isChildListview = isChildListview;
+
+                               if (!isChildListview) {
+                                       self._addCanvas(newElement);
+                               }
+
+                               return newElement;
+                       };
+
+                       prototype._getCanvas = function () {
+                               var self = this,
+                                       canvas;
+
+                               // If reference to canvas has been changed.
+                               // Developer can remove canvas from list, eg. by element.innerHTML = "<li>item</li>"
+                               if (self._context) {
+                                       canvas = self._context.canvas;
+                               }
+                               if (!canvas || !canvas.parentElement) {
+                                       canvas = self.element.querySelector("." + classes.BACKGROUND_LAYER);
+                                       if (!canvas) {
+                                               canvas = self._addCanvas(self.element);
+                                       }
+                                       self._context = canvas.getContext("2d");
+                               }
+
+                               return canvas;
+                       }
+
+                       /**
+                        * Init colors used to draw colored bars
+                        * @method _prepareColors
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        * */
+                       prototype._prepareColors = function () {
+                               var self = this,
+                                       canvas = self._getCanvas(),
+                                       computedAfter,
+                                       colorCSSDefinition,
+                                       baseColor,
+                                       modifierColor,
+                                       colors;
+
+                               if (canvas) {
+                                       computedAfter = window.getComputedStyle(canvas, ":before");
+                                       colorCSSDefinition = computedAfter.getPropertyValue("content");
+
+                                       if (colorCSSDefinition.length > 0) {
+                                               colorCSSDefinition = colorCSSDefinition.replace(colorDefinitionRegex, "");
+                                               colors = colorCSSDefinition.split("::");
+                                               if (colors.length === 2) {
+                                                       baseColor = colors[0].split(",").filter(isNumber).map(toNumber);
+                                                       modifierColor = colors[1].split(",").filter(isNumber).map(toNumber);
+                                                       if (baseColor.length > 0) {
+                                                               copyColor(baseColor, self._colorBase);
+                                                       }
+                                                       if (modifierColor.length > 0) {
+                                                               copyColor(modifierColor, self._colorStep);
+                                                       }
+                                               }
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Refresh background canvas
+                        * @method _refreshBackgroundCanvas
+                        * @param {HTMLElement} container
+                        * @param {HTMLElement} element
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._refreshBackgroundCanvas = function (container, element) {
+                               var self = this,
+                                       canvas = self._getCanvas(),
+                                       canvasStyle,
+                                       rect,
+                                       // canvasHeight of canvas element
+                                       canvasHeight,
+                                       // canvasWidth of canvas element
+                                       canvasWidth;
+
+                               if (canvas) {
+                                       canvasStyle = canvas.style;
+                                       rect = element.getBoundingClientRect();
+                                       canvasHeight = 0;
+                                       canvasWidth = rect.width;
+
+                                       // calculate canvasHeight of canvas
+                                       if (container) {
+                                               canvasHeight = container.getBoundingClientRect().height;
+                                       }
+
+                                       canvasHeight = Math.max(rect.height, canvasHeight) + self._topOffset;
+
+                                       // limit canvas for better performance
+                                       canvasHeight = Math.min(canvasHeight, 4 * window.innerHeight);
+                                       self._canvasHeight = canvasHeight;
+                                       self._canvasWidth = canvasWidth;
+
+                                       // init canvas
+                                       canvas.setAttribute("width", canvasWidth);
+                                       canvas.setAttribute("height", canvasHeight);
+                                       canvasStyle.width = canvasWidth + "px";
+                                       canvasStyle.height = canvasHeight + "px";
+                               }
+                       };
+
+                       /**
+                        * Find and store all possible containers which may contains the listview
+                        * @method _findContainers
+                        * @param {HTMLElement} element widget element
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._findContainers = function (element) {
+                               var self = this;
+
+                               self._pageContainer = selectorUtils.getClosestByClass(element, Page.classes.uiPage);
+                               self._popupContainer = selectorUtils.getClosestByClass(element, Popup.classes.popup);
+                               self._scrollableContainer = selectorUtils.getClosestByClass(element, Scrollview.classes.clip) ||
+                                       selectorUtils.getClosestByTag(element, "section");
+                       };
+
+                       /**
+                        * Method checks if listview contains in popup then add specific class
+                        * @method _checkClosestPopup
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._checkClosestPopup = function () {
+                               var self = this,
+                                       popupContainer = self._popupContainer,
+                                       popupContent;
+
+                               if (popupContainer) {
+                                       popupContainer.classList.add(classes.POPUP_LISTVIEW);
+                                       popupContent = popupContainer.querySelector("." + Popup.classes.content);
+                                       if (popupContent) {
+                                               self._scrollableContainer = popupContent;
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Refreshes colored list in widget background,
+                        * @method _refreshColoredBackground
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._refreshColoredBackground = function () {
+                               var self = this,
+                                       element = self.element,
+                                       canvas;
+
+                               // if listview contains in popup then add specific class
+                               self._checkClosestPopup();
+
+                               self._redraw = true;
+                               self._lastChange = Date.now();
+                               self._previousVisibleElement = null;
+
+                               self._prepareColors();
+                               self._refreshBackgroundCanvas(self._scrollableContainer, element);
+
+                               canvas = self._getCanvas();
+                               if (canvas) {
+                                       if (element.firstElementChild &&
+                                               element.firstElementChild.tagName.toLowerCase() !== "canvas") {
+                                               element.insertBefore(canvas, element.firstElementChild);
+                                       } else if (!(element.firstElementChild instanceof HTMLElement)) {
+                                               element.appendChild(canvas);
+                                       }
+                                       if (typeof self._frameCallback === "function") {
+                                               self._frameCallback();
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Refreshes widget, critical to call after changes (ex. in background color)
+                        * @method _refresh
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._refresh = function () {
+                               var self = this,
+                                       element = self.element,
+                                       popupContainer = selectorUtils.getClosestByClass(element, Popup.classes.popup);
+
+                               self._findContainers(element);
+
+                               if (self.options.coloredBackground) {
+                                       self._refreshColoredBackground();
+                               } else if (popupContainer) {
+                                       // if listview contains in popup then remove specific class
+                                       popupContainer.classList.remove(classes.POPUP_LISTVIEW);
+                                       self._popupContainer = popupContainer;
+                               }
+                       };
+
+                       /**
+                        * Initializes widget and async timers
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       context = self._context,
+                                       canvas,
+                                       foundSelf = false,
+                                       siblingLists,
+                                       childrenLists;
+
+                               self.options.firstColorStep = parseInt(self.options.firstColorStep, 10);
+
+                               if (!self._isChildListview) {
+                                       if (!context) {
+                                               canvas = element.querySelector("." + classes.BACKGROUND_LAYER);
+                                               if (canvas) {
+                                                       context = canvas.getContext("2d");
+                                               }
+                                       } else {
+                                               canvas = context.canvas;
+                                       }
+
+                                       if (context) {
+                                               self._canvasStyle = canvas.style;
+                                               self._frameCallback = self._handleFrame.bind(self);
+
+                                               self.refresh();
+                                       }
+                               }
+
+                               // check other sibling colored lists
+                               siblingLists = [].slice.call(self.element.parentElement.querySelectorAll(WIDGET_SELECTOR));
+                               childrenLists = [].slice.call(self.element.querySelectorAll(WIDGET_SELECTOR));
+                               // remove itself listview from list and above listview elements
+                               self._siblingListsBellow = siblingLists.filter(function (listviewElement) {
+                                       // filter children
+                                       if (childrenLists.indexOf(listviewElement) > -1) {
+                                               return false;
+                                       }
+                                       if (foundSelf) {
+                                               return true;
+                                       }
+                                       foundSelf = listviewElement === self.element;
+
+                                       return false;
+                               });
+                               foundSelf = false;
+                               self._siblingListsAbove = siblingLists.filter(function (listviewElement) {
+                                       // filter children
+                                       if (childrenLists.indexOf(listviewElement) > -1) {
+                                               return false;
+                                       }
+                                       if (foundSelf || listviewElement === self.element) {
+                                               foundSelf = true;
+                                               return false;
+                                       }
+                                       return true;
+                               });
+
+                               if (self._siblingListsBellow.length > 0) {
+                                       // disable coloring the test of space below current listview
+                                       self.options.colorRestOfTheScreenBellow = false;
+                               }
+                               if (self._siblingListsAbove.length > 0) {
+                                       self.options.colorRestOfTheScreenAbove = false;
+                               }
+
+                               self._setMultipleSelection(self.element, self.options.multipleSelection);
+                       };
+
+                       /**
+                        * Handles scroll event data
+                        * @method _handleScroll
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._handleScroll = function () {
+                               var self = this;
+
+                               self._lastChange = now();
+
+                               if (!self._running) {
+                                       self._running = true;
+                                       self._async(self._frameCallback);
+                               }
+                       };
+
+                       /**
+                        * Handles touch start event
+                        * Used to disable scroll event listener on reorder
+                        * @method _handleTouchStart
+                        * @member ns.widget.mobile.Listview
+                        * @param {Event} event Event
+                        * @protected
+                        */
+                       prototype._handleTouchStart = function (event) {
+                               var self = this,
+                                       scrollableContainer = self._scrollableContainer;
+
+                               if (self._dragMode && event.srcElement.classList.contains(classes.HANDLER)) {
+                                       eventUtils.off(scrollableContainer, "scroll", self._reorderCallback);
+                               }
+                       };
+
+                       /**
+                        * Handles touch end event
+                        * Used to re-enable scroll event listener when reorder ends
+                        * @method _handleTouchEnd
+                        * @member ns.widget.mobile.Listview
+                        * @param {Event} event Event
+                        * @protected
+                        */
+                       prototype._handleTouchEnd = function (event) {
+                               var self = this,
+                                       scrollableContainer = self._scrollableContainer;
+
+                               if (self._dragMode && event.srcElement.classList.contains(classes.HANDLER)) {
+                                       eventUtils.on(scrollableContainer, "scroll", self._reorderCallback);
+                               }
+                       };
+
+                       /**
+                        * Handles scroll and scroll end
+                        * This method re-enables canvas on listview and removes backgrounds
+                        * added on reorder
+                        * It also adds timeout that is triggered on scroll end
+                        * @method _handleReorderScroll
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._handleReorderScroll = function () {
+                               eventUtils.trigger(this.element, events.REORDER);
+                       };
+
+                       /**
+                        * Refresh event wrapper
+                        * @method _backgroundRender
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._backgroundRender = function () {
+                               this.refresh();
+                       };
+
+                       /**
+                        * Handler for "select-all" event. This event is triggering by AppBar widget
+                        * when checkbox "All" is changing state
+                        * @method _selectAll
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._selectAll = function (event) {
+                               var checkboxes = [].slice.call(this.element.querySelectorAll("input[type='checkbox']"));
+
+                               checkboxes.forEach(function (checkbox) {
+                                       var checked = event.detail.checked;
+
+                                       checkbox.checked = checked;
+                                       if (checked) {
+                                               checkbox.setAttribute("checked", "checked");
+                                       } else {
+                                               checkbox.removeAttribute("checked");
+                                       }
+                                       changeLiSelection(checkbox);
+                               });
+                       };
+
+                       /**
+                        * Calculate element height as difference between top of current element and top of next element
+                        * @param {HTMLElement} nextVisibleLiElement
+                        * @param {Object} rectangle
+                        * @return {number}
+                        */
+                       function calculateElementHeight(nextVisibleLiElement, rectangle) {
+                               // we need round to eliminate empty spaces between bars
+                               if (nextVisibleLiElement) {
+                                       return round(nextVisibleLiElement.getBoundingClientRect().top - rectangle.top);
+                               }
+                               return round(rectangle.height);
+                       }
+
+                       /**
+                        * Handles frame computations and drawing (if necessary)
+                        * @method _handleFrame
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._handleFrame = function () {
+                               var self = this,
+                                       element = self.element,
+                                       // get all li liElements
+                                       liElements = slice.call(element.querySelectorAll("li")),
+                                       nextVisibleLiElement,
+                                       // scrollable container, connected with scrollview
+                                       scrollableContainer = self._scrollableContainer,
+                                       scrollTop = scrollableContainer ? scrollableContainer.scrollTop : 0,
+                                       scrollableContainerRect = null,
+                                       scrollableContainerTop = 0,
+                                       // top of element to calculate offset top
+                                       top = element.getBoundingClientRect().top,
+                                       previousVisibleElement = self._previousVisibleElement,
+                                       topOffset = self._topOffset,
+                                       rectangle,
+                                       currentVisibleLiElement = getNextVisible(liElements),
+                                       liOffsetTop,
+                                       height;
+
+                               if (scrollableContainer) {
+                                       scrollableContainerRect = scrollableContainer.getBoundingClientRect();
+                                       scrollableContainerTop = scrollableContainerRect.top;
+                               }
+
+                               // Reset first color step if listview is above top edge of scroll container
+                               if (scrollableContainerRect && top < scrollableContainerTop) {
+                                       if (self.options.firstColorStep !== 0) {
+                                               self.options.firstColorStep = 0;
+                                               self._redraw = true;
+                                       }
+                               }
+
+                               while (currentVisibleLiElement) {
+                                       // store size of current element
+                                       rectangle = getElementRectangle(currentVisibleLiElement);
+                                       liOffsetTop = rectangle.top - top ;
+                                       // get next element to calculate difference
+                                       nextVisibleLiElement = getNextVisible(liElements);
+                                       height = calculateElementHeight(nextVisibleLiElement, rectangle);
+                                       if (liOffsetTop + height - (scrollableContainerTop - top - scrollTop) >= scrollTop) {
+                                               if (currentVisibleLiElement !== previousVisibleElement && self._context) {
+                                                       self._previousVisibleElement = currentVisibleLiElement;
+                                                       self._context.canvas.style.transform = "translateY(" + (liOffsetTop - topOffset) + "px)";
+                                                       self._redraw = true;
+                                               }
+                                               currentVisibleLiElement = null;
+                                       } else {
+                                               // go to next element
+                                               currentVisibleLiElement = nextVisibleLiElement;
+                                       }
+                               }
+
+                               if (self._redraw && self._context) {
+                                       self._handleDraw();
+                               }
+                               if (self._running && self._context) {
+                                       self._async(self._frameCallback);
+                               }
+                               if (now() - self._lastChange >= MAX_IDLE_TIME) {
+                                       self._running = false;
+                               }
+                       };
+
+                       /**
+                        * Get next visible element from list
+                        * @param {HTMLElement} liElements
+                        * @return {HTMLElement}
+                        */
+                       function getNextVisible(liElements) {
+                               var next = liElements.shift();
+
+                               while (next) {
+                                       if (next.offsetHeight) {
+                                               return next;
+                                       }
+                                       next = liElements.shift();
+                               }
+
+                               return null;
+                       }
+
+                       /**
+                        * Calculate rectangle and create new object which is not read-only
+                        * @param {HTMLElement} element
+                        * @return {{top: (number|*), height: (number|*), left, width}}
+                        */
+                       function getElementRectangle(element) {
+                               var rectangle = element.getBoundingClientRect();
+
+                               return {
+                                       top: rectangle.top,
+                                       height: rectangle.height,
+                                       left: rectangle.left,
+                                       width: rectangle.width
+                               };
+                       }
+
+                       /**
+                        * Draw bar on canvas
+                        * @param {CanvasRenderingContext2D} context
+                        * @param {Object} rectangle
+                        */
+                       function drawRectangle(context, rectangle) {
+                               // set color
+                               context.fillStyle = "rgba(" + colorTmp[0] + "," + colorTmp[1] + "," + colorTmp[2] + "," + colorTmp[3] + ")";
+                               // first element is bigger by offset, to show color on scroll in up direction
+                               context.fillRect(rectangle.left, rectangle.top, rectangle.width, rectangle.height);
+                       }
+
+                       /**
+                        * Init color variable and clear canvas
+                        * @method _prepareCanvas
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._prepareCanvas = function () {
+                               var self = this,
+                                       i;
+
+                               // prepare first color
+                               copyColor(self._colorBase, colorTmp);
+
+                               // modify first color refer to option "firstColorStep"
+                               for (i = 0; i < self.options.firstColorStep; i++) {
+                                       modifyColor(colorTmp, self._colorStep);
+                               }
+                               self.options.lastColorStep = self.options.firstColorStep;
+
+                               // clear canvas
+                               self._context.clearRect(0, 0, self._canvasWidth, self._canvasHeight);
+                       };
+
+                       function adjustRectangle(rectangle, topOffset, listLeft, previousTop) {
+                               rectangle.height += topOffset;
+                               rectangle.left -= listLeft;
+                               rectangle.top = previousTop;
+                               return rectangle;
+                       }
+
+                       /**
+                        * Draw backgrounds on LI elements
+                        * @method _drawLiElements
+                        * @member ns.widget.mobile.Listview
+                        * @return {Object}
+                        * @protected
+                        */
+                       prototype._drawLiElements = function () {
+                               var self = this,
+                                       element = self.element,
+                                       elements = slice.call(element.querySelectorAll("li")),
+                                       firstElement = elements[0],
+                                       firstElementRect,
+                                       visibleLiElement = getNextVisible(elements),
+                                       nextVisibleLiElement,
+                                       context = self._context,
+                                       step = self._colorStep,
+                                       rectangleList = element.getBoundingClientRect(),
+                                       listLeft = rectangleList.left,
+                                       // get scroll top
+                                       scrollableContainer = self._scrollableContainer,
+                                       scrollableContainerTop = (scrollableContainer) ?
+                                               scrollableContainer.getBoundingClientRect().top : 0,
+                                       // store dimensions of li
+                                       rectangle = null,
+                                       // top on each last element
+                                       previousBottom = 0,
+                                       // top offset of widget
+                                       topOffset = self._topOffset,
+                                       changeColor,
+                                       backgroundRectangles = [],
+                                       firstItem = null,
+                                       firstRectangle = null,
+                                       onceClearUpperPartOfCanvas = false;
+
+                               if (firstElement) {
+                                       firstElementRect = firstElement.getBoundingClientRect();
+                                       if (firstElementRect.top + firstElementRect.height >= scrollableContainerTop) {
+                                               onceClearUpperPartOfCanvas = true;
+                                       }
+                               }
+
+                               while (visibleLiElement) {
+                                       // if li element is group index, the color of next element wont change
+                                       changeColor = (!visibleLiElement.classList.contains(classes.GROUP_INDEX) &&
+                                               !visibleLiElement.classList.contains(classes.EXPANDABLE));
+                                       //calculate size of li element
+                                       rectangle = getElementRectangle(visibleLiElement);
+                                       nextVisibleLiElement = getNextVisible(elements);
+                                       rectangle.height = calculateElementHeight(nextVisibleLiElement, rectangle);
+                                       //check if next element is group index, if yes then change its color
+                                       if (!changeColor && nextVisibleLiElement &&
+                                               (nextVisibleLiElement.classList.contains(classes.GROUP_INDEX) ||
+                                               nextVisibleLiElement.classList.contains(classes.EXPANDABLE))) {
+                                               changeColor = true;
+                                       }
+                                       // check that element is visible (can be partially visible)
+                                       if (ceil(rectangle.top + rectangle.height) >= scrollableContainerTop) {
+                                               // adjust height for first element
+                                               rectangle = adjustRectangle(rectangle, topOffset, listLeft, previousBottom);
+                                               topOffset = 0;
+                                               backgroundRectangles.push({
+                                                       rectangle: rectangle,
+                                                       changeColor: changeColor
+                                               })
+                                               previousBottom += rectangle.height;
+                                       }
+                                       // get visibleLiElement element
+                                       visibleLiElement = nextVisibleLiElement;
+                               }
+
+                               //Remove color buffer above first element if list is not coloring rest of the screen
+                               firstItem = backgroundRectangles[0];
+                               if (firstItem) {
+                                       firstRectangle = firstItem.rectangle;
+                                       if (!self.options.colorRestOfTheScreenAbove || onceClearUpperPartOfCanvas) {
+                                               // clear area above list and shrink the rectangle to cover only ont
+                                               self._context.clearRect(firstRectangle.left, firstRectangle.top, firstRectangle.width, firstRectangle.height);
+                                               firstRectangle.top += self._topOffset;
+                                               firstRectangle.height -= self._topOffset;
+                                       }
+                               }
+
+
+                               backgroundRectangles.forEach(function (bgRect) {
+                                       drawRectangle(context, bgRect.rectangle)
+                                       if (bgRect.changeColor) {
+                                               modifyColor(colorTmp, step);
+                                               self.options.lastColorStep++;
+                                       }
+                               });
+
+                               return rectangle;
+                       };
+
+                       /**
+                        * Draw rest of empty space
+                        * @method _drawEndOfList
+                        * @param {Object} rectangle
+                        * @param {CanvasRenderingContext2D} context
+                        * @protected
+                        */
+                       prototype._drawEndOfList = function (rectangle, context) {
+                               var canvasRect;
+
+                               // fill rest of canvas by color of next item
+                               if (rectangle !== null) {
+                                       canvasRect = context.canvas.getBoundingClientRect();
+                                       if (rectangle.height + rectangle.top < canvasRect.height) {
+                                               rectangle.top += rectangle.height;
+                                               rectangle.height = canvasRect.height - rectangle.top;
+                                               drawRectangle(context, rectangle);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Handles drawing of step-gradient background
+                        * @method _handleDraw
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._handleDraw = function () {
+                               var self = this,
+                                       // store dimensions of li
+                                       rectangle,
+                                       nextListview;
+
+                               self._prepareCanvas();
+                               rectangle = self._drawLiElements();
+                               if (self.options.colorRestOfTheScreenBellow) {
+                                       self._drawEndOfList(rectangle, self._context);
+                               }
+                               // change first color of next listviews
+                               self._siblingListsBellow.forEach(function (listviewElement) {
+                                       nextListview = ns.engine.getBinding(listviewElement);
+                                       if (nextListview) {
+                                               nextListview.option("firstColorStep", self.options.lastColorStep);
+                                       }
+                               });
+
+                               self._redraw = false;
+                       };
+
+                       prototype._focusItem = function (event) {
+                               var target = event.detail.element,
+                                       liElement = selectorUtils.getClosestByTag(target, "li");
+
+                               if (ns.getConfig("keyboardSupport") && (target.tagName === "A")) {
+                                       liElement.classList.add(classes.ITEMFOCUS);
+                               }
+                       };
+
+                       prototype._blurItem = function (event) {
+                               var target = event.detail.element,
+                                       liElement = selectorUtils.getClosestByTag(target, "li");
+
+                               if (ns.getConfig("keyboardSupport") && (target.tagName === "A")) {
+                                       liElement.classList.remove(classes.ITEMFOCUS);
+                               }
+                       };
+
+                       prototype._focus = function (element) {
+                               if (ns.getConfig("keyboardSupport")) {
+                                       element.classList.add(classes.FOCUS);
+                               }
+                       }
+
+                       prototype._blur = function (element) {
+                               if (ns.getConfig("keyboardSupport")) {
+                                       element.classList.remove(classes.FOCUS);
+                               }
+                       }
+
+                       /**
+                        * Bounds to events
+                        * @method _bindEvents
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       scrollableContainer = self._scrollableContainer,
+                                       pageContainer = self._pageContainer,
+                                       popupContainer = self._popupContainer;
+
+                               self._bindEventMouse();
+
+                               if (!self._isChildListview) {
+                                       if (scrollableContainer) {
+                                               self._scrollableContainer = scrollableContainer;
+                                               self._scrollCallback = self._handleScroll.bind(self);
+                                               self._reorderCallback = self._handleReorderScroll.bind(self);
+                                               self._touchStartCallback = self._handleTouchStart.bind(self);
+                                               self._touchEndCallback = self._handleTouchEnd.bind(self);
+                                               eventUtils.on(scrollableContainer, "touchstart", self._scrollCallback);
+                                               eventUtils.on(scrollableContainer, "touchmove", self._scrollCallback);
+                                               eventUtils.on(scrollableContainer, "touchstart", self._touchStartCallback);
+                                               eventUtils.on(scrollableContainer, "touchend", self._touchEndCallback);
+                                               eventUtils.on(scrollableContainer, "scroll", self._scrollCallback);
+                                       }
+
+                                       self._backgroundRenderCallback = self._backgroundRender.bind(self);
+                                       self._selectAllCallback = self._selectAll.bind(self);
+                                       self.on("expand collapse", self._backgroundRenderCallback, false);
+                                       // support rotation
+                                       eventUtils.on(window, "resize", self._backgroundRenderCallback, false);
+
+                                       if (pageContainer) {
+                                               eventUtils.on(pageContainer, Page.events.BEFORE_SHOW, self._backgroundRenderCallback);
+                                               eventUtils.on(pageContainer, "select-all", self._selectAllCallback, true);
+                                       }
+                                       if (popupContainer) {
+                                               eventUtils.on(popupContainer, Popup.events.transition_start, self._backgroundRenderCallback);
+                                       }
+
+                                       utilsEvents.on(self.element, "animationend webkitAnimationEnd", self, true);
+                                       utilsEvents.on(self.element, "taufocus", self._focusItem, true);
+                                       utilsEvents.on(self.element, "taublur", self._blurItem, true);
+                               }
+                       };
+
+                       /**
+                        * Destroys widget
+                        * @method _destroy
+                        * @param {HTMLElement} element
+                        * @member ns.widget.mobile.Listview
+                        * @protected
+                        */
+                       prototype._destroy = function (element) {
+                               var self = this;
+
+                               //phantom hack
+                               if (element) {
+                                       utilsEvents.off(element, "animationend webkitAnimationEnd", self, true);
+                                       utilsEvents.off(element, "focus", self._focus, true);
+                                       utilsEvents.off(element, "blur", self._blur, true);
+                               }
+
+                               if (self._context) {
+                                       if (self._context.canvas.parentElement) {
+                                               self._context.canvas.parentElement.removeChild(self._context.canvas);
+                                       }
+                                       self._context = null;
+                               }
+
+                               if (self._scrollCallback) {
+                                       if (self._scrollableContainer) {
+                                               eventUtils.off(self._scrollableContainer, "touchstart", self._scrollCallback);
+                                               eventUtils.off(self._scrollableContainer, "touchmove", self._scrollCallback);
+                                               eventUtils.off(self._scrollableContainer, "scroll", self._scrollCallback);
+                                               eventUtils.off(self._scrollableContainer, "touchstart", this._touchStartCallback);
+                                               eventUtils.off(self._scrollableContainer, "touchend", this._touchEndCallback);
+                                               self._scrollableContainer = null;
+                                       }
+                                       self._scrollCallback = null;
+                               }
+
+                               if (self._backgroundRenderCallback) {
+                                       self.off("expand collapse", self._backgroundRenderCallback, false);
+                                       eventUtils.off(window, "resize", self._backgroundRenderCallback, false);
+                                       if (element) {
+                                               eventUtils.off(element, events.BACKGROUND_RENDER, self._backgroundRenderCallback);
+                                       }
+                                       if (self._pageContainer) {
+                                               eventUtils.off(self._pageContainer, Page.events.BEFORE_SHOW, self._backgroundRenderCallback);
+                                               eventUtils.off(self._pageContainer, "select-all", self._selectAllCallback, true);
+                                               self._pageContainer = null;
+                                       }
+                                       if (self._popupContainer) {
+                                               self._popupContainer.classList.remove(classes.POPUP_LISTVIEW);
+                                               eventUtils.off(self._popupContainer, Popup.events.transition_start, self._backgroundRenderCallback);
+                                               self._popupContainer = null;
+                                       }
+                                       self._backgroundRenderCallback = null;
+                               }
+
+                       };
+
+                       /**
+                        * Create holder element to help reordering
+                        * @method _createHolder
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._createHolder = function () {
+                               var holder = document.createElement("li"),
+                                       classList = holder.classList;
+
+                               classList.add(classes.ITEM);
+                               classList.add(classes.HOLDER);
+
+                               return holder;
+                       };
+
+                       /**
+                        * set direction when moving
+                        * Based on the previous position defined as moveTop,
+                        * the new direction is set
+                        * @method _setDirection
+                        * @protected
+                        * @param {number} moveY new position
+                        * @param {number} moveTop previous position
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._setDirection = function (moveY, moveTop) {
+                               var self = this;
+
+                               if (moveY < moveTop) {
+                                       self._direction = direction.PREV;
+                               } else if (moveY === moveTop) {
+                                       self._direction = direction.HOLD;
+                               } else {
+                                       self._direction = direction.NEXT;
+                               }
+                       };
+
+                       /**
+                        * Relocate elements when "move down" event occur
+                        *
+                        * New position is calculated for holder element and for items
+                        * After setting the new position for item, holder change position in DOM
+                        * If we move the pointer for a great length then few items at once should
+                        * change location
+                        *
+                        * When going down we need to go over item for 70% (30% to bottom)
+                        * @method _changeLocationDown
+                        * @protected
+                        * @param {number} range new position for cursor
+                        * @param {HTMLElement} holder temporary replacement element
+                        * @param {Object} helper is a dragging element
+                        * @param {number} length number of items
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._changeLocationDown = function (range, holder, helper, length) {
+                               var item,
+                                       index = 1,
+                                       self = this,
+                                       element = self.element;
+
+                               range = range + helper.height;
+
+                               //skip first element, as it is canvas with gradient
+                               for (; index < length; index++) {
+                                       item = element.children[index];
+                                       //to not go over same element and when cursor is over the item for 70%
+                                       if ((helper.element !== item && holder !== item) &&
+                                               range > (self._snapshotItems[index - 1] + item.offsetHeight * 70 / 100) &&
+                                               //item top should be bigger then holder top when going down
+                                               (self._snapshotItems[index - 1] > holder.offsetTop + 15)) {
+
+                                               //set new top for the moved item, this will consider different height of the elements
+                                               self._snapshotItems[index - 1] = self._snapshotItems[index - 2] + item.offsetHeight;
+                                               self._appendLiStylesToElement(item, self._snapshotItems[index - 2]);
+                                               self._appendLiStylesToElement(holder, self._snapshotItems[index - 1]);
+                                               element.insertBefore(holder, element.children[index].nextSibling);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Relocate elements when "move up" event occur
+                        *
+                        * New position is calculated for holder element and for items
+                        * After setting the new position for item, holder change position in DOM
+                        * If we move the pointer for a great length then few items at once should
+                        * change location
+                        *
+                        * When going up we need to go over item for 30% (70% to bottom)
+                        * @method _changeLocationUp
+                        * @protected
+                        * @param {number} range new position for cursor
+                        * @param {HTMLElement} holder temporary replacement element
+                        * @param {Object} helper is a dragging element
+                        * @param {number} length number of items
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._changeLocationUp = function (range, holder, helper, length) {
+                               var item,
+                                       self = this,
+                                       index = length - 1,
+                                       element = self.element;
+
+                               for (; index > 0; index--) {
+                                       item = element.children[index];
+                                       //to not go over same element
+                                       if ((helper.element !== item && holder !== item) &&
+                                               //when cursor is over the item for 70%
+                                               range < (self._snapshotItems[index - 1] + (item.offsetHeight * 30 / 100)) &&
+                                               //item top should be smaller then holder top when going up
+                                               self._snapshotItems[index - 1] + item.offsetHeight < holder.offsetTop + holder.offsetHeight - 15) {
+
+                                               //set new top for the moved item, this will consider different height of the elements
+                                               self._snapshotItems[index] = self._snapshotItems[index - 1] + holder.offsetHeight;
+                                               element.insertBefore(holder, element.children[index]);
+                                               self._appendLiStylesToElement(holder, self._snapshotItems[index - 1]);
+                                               self._appendLiStylesToElement(item, self._snapshotItems[index]);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Method for drag prepare event
+                        * @method _prepare
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._prepare = function () {
+                               var self = this,
+                                       element = self.element,
+                                       parentElement = element.parentElement;
+
+                               //it means that dragend was not called and handler was just clicked
+                               if (!element.classList.contains(classes.SNAPSHOT)) {
+                                       self._recalculateTop();
+                                       //save before dragging, the position for original list
+                                       self.originalListPosition = parentElement.getBoundingClientRect().top - 55;
+                                       // set element height
+                                       self._styleHeightBackup = element.style.height;
+                                       element.style.height = element.getBoundingClientRect().height + "px";
+                                       element.classList.add(classes.SNAPSHOT);
+                                       //change scrollTop as we use absolute and top positions now
+                                       parentElement.scrollTop = -self.originalListPosition;
+                               }
+                       };
+
+                       /**
+                        * Method for dragstart event
+                        *
+                        * Prepare holder element to replace the drag item
+                        * Drag item is represented as helper and it is replaced
+                        * by holder because we change the location of helper with top
+                        * @method _start
+                        * @protected
+                        * @param {Event} event Event
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._start = function (event) {
+                               var self = this,
+                                       top,
+                                       holder,
+                                       element = self.element,
+                                       helper = self._ui.helper,
+                                       helperElement = event.detail.srcEvent.srcElement.parentElement,
+                                       helperElementComputed = window.getComputedStyle(helperElement, null),
+                                       helperStyle = helperElement.style;
+
+                               top = parseInt(helperElementComputed.getPropertyValue("top"), 10);
+
+                               helperElement.classList.add(classes.HELPER);
+                               holder = self._createHolder();
+                               holder.style.height = parseFloat(helperElementComputed.getPropertyValue("height")) + "px";
+                               holder.style.top = helperElement.style.top;
+
+                               element.insertBefore(holder, helperElement);
+                               element.appendChild(helperElement);
+
+                               self._appendLiStylesToElement(helperElement, top);
+
+                               helper.element = helperElement;
+                               helper.style = helperStyle;
+                               helper.height = parseFloat(helperElementComputed.getPropertyValue("height")) || 0;
+                               helper.startY = event.detail.estimatedY - 55 - helper.height / 2;
+                               helper.position = {
+                                       startTop: top,
+                                       moveTop: helper.startY,
+                                       startIndex: [].indexOf.call(element.children, holder)
+                               };
+
+                               self._ui.holder = holder;
+                               helper.element = helperElement;
+                               self._ui.helper = helper;
+
+                               self.topValue = event.detail.estimatedY;
+                               helper.move = 0;
+                       };
+
+
+                       /**
+                        * callback when drag event
+                        * @method _move
+                        * @protected
+                        * @param {Event} event Event
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._move = function (event) {
+                               var moveY,
+                                       self = this,
+                                       headerHeight,
+                                       ui = self._ui,
+                                       helper = ui.helper,
+                                       holder = ui.holder,
+                                       element = self.element,
+                                       position = helper.position,
+                                       helperElement = helper.element,
+                                       length = element.childElementCount - 1,
+                                       headerElement = document.querySelector(".ui-page-active .ui-header");
+
+                               headerHeight = (headerElement) ? headerElement.offsetHeight : 0;
+                               //move element only in Y axis
+                               moveY = event.detail.estimatedY - headerHeight - helper.height / 2 +
+                                       -self.originalListPosition;
+                               self._appendLiStylesToElement(helperElement, moveY);
+
+                               self._setDirection(moveY, position.moveTop);
+                               helperElement.classList.add("ui-listview-item-moved");
+                               position.moveTop = moveY;
+
+                               if (self._direction > 0) {
+                                       self._changeLocationDown(moveY, holder, helper, length);
+                               } else if (self._direction < 0) {
+                                       self._changeLocationUp(moveY, holder, helper, length);
+                               }
+                       };
+
+                       /**
+                        * Method for dragend event
+                        *
+                        * Replace holder with the draggable item
+                        * @method _end
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._end = function () {
+                               var self = this,
+                                       element = self.element,
+                                       helper = self._ui.helper,
+                                       holder = self._ui.holder,
+                                       helperElement = helper.element;
+
+                               helperElement.classList.remove("ui-listview-item-moved");
+                               helperElement.classList.remove(classes.HELPER);
+                               self._appendLiStylesToElement(helperElement, holder.offsetTop);
+
+                               element.insertBefore(helperElement, holder);
+                               element.removeChild(holder);
+                               self._ui.helper = {};
+
+                               self._removeTopOffsets();
+                               element.classList.remove(classes.SNAPSHOT);
+                               // recovery widget height
+                               element.style.height = self._styleHeightBackup;
+
+                               //change scrollTop as we use absolute and top positions now
+                               element.parentElement.parentElement.scrollTop = -self.originalListPosition;
+                               //refresh cache
+                               self._liElements = slice.call(element.querySelectorAll("li"));
+                               self.trigger("scroll");
+                       };
+
+                       /**
+                        * Method for click event
+                        *
+                        * Because "prepare drag" is run every time when we press handler
+                        * we need to use "click" to revert changes done by "prepare drag"
+                        * Click is not called if we start drag
+                        * @method _click
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._click = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               self._removeTopOffsets();
+                               element.classList.remove(classes.SNAPSHOT);
+                               // recovery widget height
+                               element.style.height = self._styleHeightBackup;
+
+                               //change scrollTop as we use absolute and top positions now
+                               element.parentElement.parentElement.scrollTop = -self.originalListPosition;
+                       };
+
+                       /**
+                        * Method for animationEnd event
+                        *
+                        * Controls the behavior for 2 animations:
+                        * -sliding from right to left
+                        * -sliding from left to right
+                        * @method _animationEnd
+                        * @protected
+                        * @param {Event} event Event
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._animationEnd = function (event) {
+                               var self = this,
+                                       listContainer = event.target.parentElement.parentElement,
+                                       listContainerClasses = listContainer.classList;
+
+                               if (listContainerClasses.contains(classes.ACTIVATE_HANDLERS)) {
+                                       listContainerClasses.remove(classes.ACTIVATE_HANDLERS);
+
+                                       //disable animation, so it will not run when reorder
+                                       listContainerClasses.add(classes.CANCEL_ANIMATION);
+                               } else if (listContainerClasses.contains(classes.DEACTIVATE_HANDLERS)) {
+                                       //remove handlers after animation end
+                                       self._removeHandlers();
+                                       listContainerClasses.remove(classes.DEACTIVATE_HANDLERS);
+                                       listContainerClasses.remove(classes.DRAG_MODE);
+                               }
+                               event.stopImmediatePropagation();
+                               event.preventDefault();
+                       };
+
+                       /**
+                        * Handle events
+                        * @method handleEvent
+                        * @public
+                        * @param {Event} event Event
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this,
+                                       srcElement = (event.detail && event.detail.srcEvent &&
+                                               event.detail.srcEvent.srcElement) || event.srcElement;
+
+                               if (srcElement.classList.contains(classes.HANDLER)) {
+                                       switch (event.type) {
+                                               case "click":
+                                                       self._click(event);
+                                                       event.preventDefault();
+                                                       break;
+                                               case "dragprepare":
+                                                       self._prepare(event);
+                                                       break;
+                                               case "dragstart":
+                                                       self._start(event);
+                                                       event.preventDefault();
+                                                       break;
+                                               case "drag":
+                                                       self._move(event);
+                                                       break;
+                                               case "dragend":
+                                                       self._end(event);
+                                                       break;
+                                               case "animationend":
+                                               case "webkitAnimationEnd":
+                                                       self._animationEnd(event);
+                                                       break;
+                                       }
+                               }
+                       };
+
+                       /**
+                        * add handlers for list elements
+                        * @method _appendHandlers
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._appendHandlers = function () {
+                               var i = 0,
+                                       self = this,
+                                       handler,
+                                       liElement,
+                                       liElements = self._liElements,
+                                       length = liElements.length;
+
+                               for (; i < length; i++) {
+                                       liElement = liElements[i];
+                                       handler = document.createElement("div");
+                                       handler.classList.add(classes.HANDLER);
+                                       handler.classList.add("ui-icon-reorder");
+                                       handler.classList.add("ui-icon");
+                                       liElement.appendChild(handler);
+                               }
+                       };
+
+                       /**
+                        * remove handlers from list elements
+                        * @method _removeHandlers
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._removeHandlers = function () {
+                               var i = 0,
+                                       self = this,
+                                       handler,
+                                       liElement,
+                                       liElements = self._liElements,
+                                       length = liElements.length;
+
+                               for (; i < length; i++) {
+                                       liElement = liElements[i];
+                                       handler = liElement.querySelector("." + classes.HANDLER);
+                                       liElement.removeChild(handler);
+                               }
+                       };
+
+                       /**
+                        * add new tops
+                        * @method _recalculateTop
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._recalculateTop = function () {
+                               var i = 0,
+                                       self = this,
+                                       offsetTop,
+                                       liElement,
+                                       liElements = self._liElements,
+                                       length = liElements.length;
+
+                               for (; i < length; i++) {
+                                       liElement = liElements[i];
+                                       offsetTop = liElement.offsetTop;
+                                       self._snapshotItems.push(offsetTop);
+                                       self._appendLiStylesToElement(liElements[i], self._snapshotItems[i]);
+                               }
+                       };
+
+                       /**
+                        * remove top offsets when going back to standard list mode
+                        * @method _removeTopOffsets
+                        * @protected
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._removeTopOffsets = function () {
+                               var i = 0,
+                                       self = this,
+                                       liElements = self._liElements,
+                                       length = liElements.length;
+
+                               for (; i < length; i++) {
+                                       liElements[i].style.top = "";
+                               }
+                       };
+
+                       /**
+                        * adds top style to the elements
+                        * @method _appendLiStylesToElement
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @param {number} Y distance form top
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype._appendLiStylesToElement = function (element, Y) {
+                               element.style.top = Y + "px";
+                       };
+
+                       /**
+                        * switch list in drag mode, add draggable handlers
+                        * @method toggleDragMode
+                        * @public
+                        * @member ns.widget.mobile.Listview
+                        */
+                       prototype.toggleDragMode = function () {
+                               var self = this,
+                                       element = self.element,
+                                       scrollableContainer = self._scrollableContainer;
+
+                               self._dragMode = !self._dragMode;
+
+                               if (self._dragMode) {
+                                       element.classList.add(classes.DRAG_MODE);
+                                       self._liElements = slice.call(element.querySelectorAll("li"));
+                                       self._appendHandlers();
+                                       element.classList.add(classes.ACTIVATE_HANDLERS);
+
+                                       utilsEvents.on(element, "click drag dragstart dragend dragcancel dragprepare", self, true);
+                                       eventUtils.on(scrollableContainer, "scroll", self._reorderCallback);
+                                       self.trigger("scroll");
+                                       //support drag
+                                       utilsEvents.enableGesture(
+                                               element,
+                                               new utilsEvents.gesture.Drag({
+                                                       blockVertical: false
+                                               })
+                                       );
+                               } else {
+                                       element.classList.remove(classes.CANCEL_ANIMATION);
+                                       element.classList.add(classes.DEACTIVATE_HANDLERS);
+
+                                       utilsEvents.off(element, "click drag dragstart dragend dragcancel dragprepare", self, true);
+                                       utilsEvents.disableGesture(element);
+                               }
+                       };
+
+                       Listview.prototype = prototype;
+                       ns.widget.mobile.Listview = Listview;
+                       engine.defineWidget(
+                               "Listview",
+                               WIDGET_SELECTOR,
+                               [],
+                               Listview,
+                               "mobile",
+                               true,
+                               true,
+                               HTMLUListElement
+                       );
+
+                       }(window, window.document, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* global window, define */
+/* eslint-disable no-console */
+/**
+ * #Core namespace
+ * Object contains main framework methods.
+ * @class ns
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function (document, console) {
+       "use strict";
+                       var idNumberCounter = 0,
+                       currentDate = +new Date(),
+                       slice = [].slice,
+                       rootNamespace = "",
+                       fileName = "",
+                       infoForLog = function (args) {
+                               var dateNow = new Date();
+
+                               args.unshift("[" + rootNamespace + "][" + dateNow.toLocaleString() + "]");
+                       },
+                       ns = window.ns || window.tau || {},
+                       nsConfig = window.nsConfig || window.tauConfig || {},
+                       TAUException = function (message) {
+                               this.message = message;
+                       };
+
+               ns.info = ns.info || {
+                       profile: "custom"
+               };
+               ns.tauPerf = ns.tauPerf || {};
+
+               window.ns = ns;
+               window.nsConfig = nsConfig;
+
+               window.tau = ns;
+               window.tauConfig = nsConfig;
+
+               rootNamespace = nsConfig.rootNamespace;
+               fileName = nsConfig.fileName;
+
+               TAUException.prototype.toString = function () {
+                       return this.message;
+               };
+
+               /**
+                * Return unique id
+                * @method getUniqueId
+                * @static
+                * @return {string}
+                * @member ns
+                */
+               ns.getUniqueId = function () {
+                       return rootNamespace + "-" + ns.getNumberUniqueId() + "-" + currentDate;
+               };
+
+               /**
+                * Return unique id
+                * @method getNumberUniqueId
+                * @static
+                * @return {number}
+                * @member ns
+                */
+               ns.getNumberUniqueId = function () {
+                       return idNumberCounter++;
+               };
+
+               /**
+                * logs supplied messages/arguments
+                * @method log
+                * @static
+                * @member ns
+                */
+               ns.log = function () {
+                       var args = slice.call(arguments);
+
+                       infoForLog(args);
+                       if (console) {
+                               console.log.apply(console, args);
+                       }
+               };
+
+               /**
+                * logs supplied messages/arguments ad marks it as warning
+                * @method warn
+                * @static
+                * @member ns
+                */
+               ns.warn = function () {
+                       var args = slice.call(arguments);
+
+                       infoForLog(args);
+                       if (console) {
+                               console.warn.apply(console, args);
+                       }
+               };
+
+               /**
+                * logs supplied messages/arguments and marks it as error
+                * @method error
+                * @static
+                * @member ns
+                */
+               ns.error = function () {
+                       var args = slice.call(arguments);
+
+                       infoForLog(args);
+                       if (console) {
+                               console.error.apply(console, args);
+                       }
+               };
+
+               /**
+                * get from nsConfig
+                * @method getConfig
+                * @param {string} key
+                * @param {*} [defaultValue] value returned when config is not set
+                * @return {*}
+                * @static
+                * @member ns
+                */
+               ns.getConfig = function (key, defaultValue) {
+                       return nsConfig[key] === undefined ? defaultValue : nsConfig[key];
+               };
+
+               /**
+                * set in nsConfig
+                * @method setConfig
+                * @param {string} key
+                * @param {*} value
+                * @param {boolean} [asDefault=false] value should be treated as default (doesn't overwrites
+                * the config[key] if it already exists)
+                * @static
+                * @member ns
+                */
+               ns.setConfig = function (key, value, asDefault) {
+                       if (!asDefault || nsConfig[key] === undefined) {
+                               nsConfig[key] = value;
+                       }
+               };
+
+               /**
+                * Return path for framework script file.
+                * @method getFrameworkPath
+                * @return {?string}
+                * @member ns
+                */
+               ns.getFrameworkPath = function () {
+                       var scripts = document.getElementsByTagName("script"),
+                               countScripts = scripts.length,
+                               i,
+                               url,
+                               arrayUrl,
+                               count;
+
+                       for (i = 0; i < countScripts; i++) {
+                               url = scripts[i].src;
+                               arrayUrl = url.split("/");
+                               count = arrayUrl.length;
+                               if (arrayUrl[count - 1] === fileName + ".js" ||
+                                       arrayUrl[count - 1] === fileName + ".min.js") {
+                                       return arrayUrl.slice(0, count - 1).join("/");
+                               }
+                       }
+                       return null;
+               };
+
+               ns._TAUException = TAUException;
+
+               /**
+                * Method throws TAU exception with given message
+                * @param {string} message
+                * @method throws
+                * @member ns
+                */
+               ns.throws = function (message) {
+                       if (typeof message !== "string") {
+                               ns.throws("Wrong parameter type. Message must be a string!");
+                       }
+                       throw new ns._TAUException(message);
+               };
+
+               }(window.document, window.console));
+
+/*global ns, define */
+/*jslint nomen: true, browser: true, plusplus: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Utilities
+ *
+ * The Tizen Advanced UI (TAU) framework provides utilities for easy-developing
+ * and fully replaceable with jQuery method. When user using these DOM and
+ * selector methods, it provide more light logic and it proves performance
+ * of web app. The following table displays the utilities provided by the
+ * TAU framework.
+ *
+ * @class ns.util
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var currentFrame = null,
+                               util = ns.util || {},
+                               // frames callbacks which should be run in next request animation frame
+                               waitingFrames = [],
+                               slice = [].slice,
+                               // inform that loop was added to request animation frame callback
+                               loopWork = false;
+
+                       /**
+                        * Function which is use as workaround when any type of request animation frame not exists
+                        * @param {Function} callback
+                        * @method _requestAnimationFrameOnSetTimeout
+                        * @static
+                        * @member ns.util
+                        * @protected
+                        */
+                       util._requestAnimationFrameOnSetTimeout = function (callback) {
+                               if (typeof callback !== "function") {
+                                       ns.throws("Parameter is not a function!");
+                               }
+                               currentFrame = window.setTimeout(callback.bind(callback, +new Date()), 1000 / 60);
+                       };
+
+                       /**
+                        * Function which support every request animation frame.
+                        * @method _loop
+                        * @protected
+                        * @static
+                        * @member ns.util
+                        */
+                       util._loop = function () {
+                               var loopWaitingFrames = slice.call(waitingFrames),
+                                       currentFrameFunction = loopWaitingFrames.shift(),
+                                       loopTime = performance.now();
+
+                               waitingFrames = [];
+
+                               while (currentFrameFunction) {
+                                       currentFrameFunction(loopTime);
+                                       if (performance.now() - loopTime < 15) {
+                                               currentFrameFunction = loopWaitingFrames.shift();
+                                       } else {
+                                               currentFrameFunction = null;
+                                       }
+                               }
+                               if (loopWaitingFrames.length || waitingFrames.length) {
+                                       waitingFrames.unshift.apply(waitingFrames, loopWaitingFrames);
+                                       util.windowRequestAnimationFrame(util._loop);
+                               } else {
+                                       loopWork = false;
+                               }
+                       };
+
+                       /**
+                        * Find browser prefixed request animation frame function.
+                        * @method _getRequestAnimationFrame
+                        * @protected
+                        * @static
+                        * @member ns.util
+                        */
+                       util._getRequestAnimationFrame = function () {
+                               return (window.requestAnimationFrame ||
+                                       window.webkitRequestAnimationFrame ||
+                                       window.mozRequestAnimationFrame ||
+                                       window.oRequestAnimationFrame ||
+                                       window.msRequestAnimationFrame ||
+                                       util._requestAnimationFrameOnSetTimeout).bind(window);
+                       };
+
+                       /**
+                        * Original requestAnimationFrame from object window.
+                        * @method windowRequestAnimationFrame
+                        * @static
+                        * @member ns.util
+                        */
+                       util.windowRequestAnimationFrame = util._getRequestAnimationFrame();
+
+                       /**
+                        * Special requestAnimationFrame function which add functions to queue of callbacks
+                        * @method requestAnimationFrame
+                        * @static
+                        * @member ns.util
+                        */
+                       util.requestAnimationFrame = function (callback) {
+                               waitingFrames.push(callback);
+                               if (!loopWork) {
+                                       util.windowRequestAnimationFrame(util._loop);
+                                       loopWork = true;
+                               }
+                       };
+
+                       util._cancelAnimationFrameOnSetTimeout = function () {
+                               // probably wont work if there is any more than 1
+                               // active animationFrame but we are trying anyway
+                               window.clearTimeout(currentFrame);
+                       };
+
+                       /**
+                        * Remove animation callbacks added by requestAnimationFrame
+                        * @method cancelAnimationFrames
+                        * @static
+                        * @member ns.util
+                        * @param {*} animationId value for identify animation in queue
+                        */
+                       util.cancelAnimationFrames = function (animationId) {
+                               var found = 0,
+                                       len = waitingFrames.length,
+                                       i = 0;
+
+                               if (animationId) {
+                                       // remove selected requests
+                                       while (len > 0 && found > -1) {
+                                               found = -1;
+                                               for (; i < len; i++) {
+                                                       if (waitingFrames[i].animationId === animationId) {
+                                                               found = i;
+                                                               break;
+                                                       }
+                                               }
+
+                                               if (found > -1) {
+                                                       waitingFrames.splice(found, 1);
+                                                       len--;
+                                               }
+                                       }
+                               } else {
+                                       ns.warn("cancelAnimationFrames() require one parameter for request identify");
+                               }
+                       };
+
+                       util._getCancelAnimationFrame = function () {
+                               return (window.cancelAnimationFrame ||
+                                       window.webkitCancelAnimationFrame ||
+                                       window.mozCancelAnimationFrame ||
+                                       window.oCancelAnimationFrame ||
+                                       window.msCancelAnimationFrame ||
+                                       util._cancelAnimationFrameOnSetTimeout).bind(window);
+                       };
+
+                       util.cancelAnimationFrame = util._getCancelAnimationFrame();
+
+                       /**
+                        * fetchSync retrieves a text document synchronously, returns null on error
+                        * @param {string} url
+                        * @param {=string} [mime=""] Mime type of the resource
+                        * @return {string|null}
+                        * @static
+                        * @member ns.util
+                        */
+                       function fetchSync(url, mime) {
+                               var xhr = new XMLHttpRequest(),
+                                       status;
+
+                               xhr.open("get", url, false);
+                               if (mime) {
+                                       xhr.overrideMimeType(mime);
+                               }
+                               xhr.send();
+                               if (xhr.readyState === 4) {
+                                       status = xhr.status;
+                                       if (status === 200 || (status === 0 && xhr.responseText)) {
+                                               return xhr.responseText;
+                                       }
+                               }
+
+                               return null;
+                       }
+
+                       util.fetchSync = fetchSync;
+
+                       /**
+                        * Removes all script tags with src attribute from document and returns them
+                        * @param {HTMLElement} container
+                        * @return {Array.<HTMLElement>}
+                        * @protected
+                        * @static
+                        * @member ns.util
+                        */
+                       function removeExternalScripts(container) {
+                               var scripts = slice.call(container.querySelectorAll("script[src]")),
+                                       i = scripts.length,
+                                       script;
+
+                               while (--i >= 0) {
+                                       script = scripts[i];
+                                       script.parentNode.removeChild(script);
+                               }
+
+                               return scripts;
+                       }
+
+                       util._removeExternalScripts = removeExternalScripts;
+
+                       /**
+                        * Evaluates code, reason for a function is for an atomic call to evaluate code
+                        * since most browsers fail to optimize functions with try-catch blocks, so this
+                        * minimizes the effect, returns the function to run
+                        * @param {string} code
+                        * @return {Function}
+                        * @static
+                        * @member ns.util
+                        */
+                       function safeEvalWrap(code) {
+                               return function () {
+                                       try {
+                                               window.eval(code);
+                                       } catch (e) {
+                                               if (e.stack) {
+                                                       ns.error(e.stack);
+                                               } else if (e.name && e.message) {
+                                                       ns.error(e.name, e.message);
+                                               } else {
+                                                       ns.error(e);
+                                               }
+                                       }
+                               };
+                       }
+
+                       util.safeEvalWrap = safeEvalWrap;
+
+                       /**
+                        * Calls functions in supplied queue (array)
+                        * @param {Array.<Function>} functionQueue
+                        * @static
+                        * @member ns.util
+                        */
+                       function batchCall(functionQueue) {
+                               var i,
+                                       length = functionQueue.length;
+
+                               for (i = 0; i < length; ++i) {
+                                       functionQueue[i]();
+                               }
+                       }
+
+                       util.batchCall = batchCall;
+
+                       /**
+                        * Creates new script elements for scripts gathered from a different document
+                        * instance, blocks asynchronous evaluation (by renaming src attribute) and
+                        * returns an array of functions to run to evaluate those scripts
+                        * @param {Array.<HTMLElement>} scripts
+                        * @param {HTMLElement} container
+                        * @return {Array.<Function>}
+                        * @protected
+                        * @static
+                        * @member ns.util
+                        */
+                       function createScriptsSync(scripts, container) {
+                               var scriptElement,
+                                       scriptBody,
+                                       i,
+                                       length,
+                                       queue = [];
+
+                               // proper order of execution
+                               for (i = 0, length = scripts.length; i < length; ++i) {
+                                       scriptBody = util.fetchSync(scripts[i].src, "text/plain");
+                                       if (scriptBody) {
+                                               scriptElement = document.adoptNode(scripts[i]);
+                                               scriptElement.setAttribute("data-src", scripts[i].src);
+                                               scriptElement.removeAttribute("src"); // block evaluation
+                                               queue.push(util.safeEvalWrap(scriptBody));
+                                               if (container) {
+                                                       container.appendChild(scriptElement);
+                                               }
+                                       }
+                               }
+
+                               return queue;
+                       }
+
+                       util._createScriptsSync = createScriptsSync;
+
+                       function removeInlineScripts(element) {
+                               var result = [],
+                                       script;
+
+                               slice.call(element.querySelectorAll(
+                                       "script:not([data-src]):not([type]):not([id]):not([src])"
+                                       )).forEach(function (item) {
+                                               script = document.createElement("script");
+                                               script.innerText = item.textContent;
+                                               // move attributes from original script element
+                                               slice.call(item.attributes).forEach(function (attribute) {
+                                                       script.setAttribute(attribute.name, item.getAttribute(attribute.name));
+                                               });
+                                               item.parentNode.removeChild(item);
+                                               result.push(script);
+                                       });
+
+                               return result;
+                       }
+
+                       util._removeInlineScripts = removeInlineScripts;
+
+                       /**
+                        * Method make asynchronous call of function
+                        * @method async
+                        * @inheritdoc #requestAnimationFrame
+                        * @member ns.util
+                        * @static
+                        */
+                       util.async = util.requestAnimationFrame;
+
+                       /**
+                        * Appends element from different document instance to current document in the
+                        * container element and evaluates scripts (synchronously)
+                        * @param {HTMLElement} element
+                        * @param {HTMLElement} container
+                        * @return {HTMLElement}
+                        * @method importEvaluateAndAppendElement
+                        * @member ns.util
+                        * @static
+                        */
+                       util.importEvaluateAndAppendElement = function (element, container) {
+                               var externalScriptsQueue =
+                                               util._createScriptsSync(util._removeExternalScripts(element), element),
+                                       inlineScripts = util._removeInlineScripts(element),
+                                       newNode = document.importNode(element, true)
+
+                               container.appendChild(newNode); // append and eval inline
+                               inlineScripts.forEach(function (script) {
+                                       container.appendChild(script);
+                               });
+                               util.batchCall(externalScriptsQueue);
+
+                               return newNode;
+                       };
+
+                       /**
+                        * Checks if specified string is a number or not
+                        * @method isNumber
+                        * @param {string} query
+                        * @return {boolean}
+                        * @member ns.util
+                        * @static
+                        */
+                       util.isNumber = function (query) {
+                               var parsed = parseFloat(query);
+
+                               return !isNaN(parsed) && isFinite(parsed);
+                       };
+
+                       /**
+                        * Reappear script tags to DOM structure to correct run script
+                        * @method runScript
+                        * @param {string} baseUrl
+                        * @param {HTMLScriptElement} script
+                        * @member ns.util
+                        * @deprecated 2.3
+                        */
+                       util.runScript = function (baseUrl, script) {
+                               var newScript = document.createElement("script"),
+                                       scriptData,
+                                       i,
+                                       scriptAttributes = slice.call(script.attributes),
+                                       src = script.getAttribute("src"),
+                                       attribute,
+                                       status;
+
+                               // 'src' may become null when none src attribute is set
+                               if (src !== null) {
+                                       src = util.path.makeUrlAbsolute(src, baseUrl);
+                               }
+
+                               //Copy script tag attributes
+                               i = scriptAttributes.length;
+                               while (--i >= 0) {
+                                       attribute = scriptAttributes[i];
+                                       if (attribute.name !== "src") {
+                                               newScript.setAttribute(attribute.name, attribute.value);
+                                       } else {
+                                               newScript.setAttribute("data-src", attribute.value);
+                                       }
+                               }
+
+                               if (src) {
+                                       scriptData = util.fetchSync(src, "text/plain");
+                                                                       } else {
+                                       scriptData = script.textContent;
+                               }
+
+                               if (scriptData) {
+                                       // add the returned content to a newly created script tag
+                                       newScript.src = window.URL.createObjectURL(new Blob([scriptData], {type: "text/javascript"}));
+                                       newScript.textContent = scriptData; // for compatibility with some libs ex. template systems
+                               }
+                               script.parentNode.replaceChild(newScript, script);
+                       };
+
+                       ns.util = util;
+                       }(window, window.document, ns));
+
+/*global define*/
+(function () {
+       "use strict";
+                       /*eslint-disable*/
+               /**
+                * BezierEasing - use bezier curve for transition easing function
+                * by Gaëtan Renaudeau 2014 - 2015 – MIT License
+                *
+                * Credits: is based on Firefox's nsSMILKeySpline.cpp
+                * Usage:
+                * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
+                * spline.get(x) => returns the easing value | x must be in [0, 1] range
+                *
+                * @class utils.BezierCurve
+                */
+
+
+                       // These values are established by empiricism with tests (tradeoff: performance VS precision)
+               var NEWTON_ITERATIONS = 4;
+               var NEWTON_MIN_SLOPE = 0.001;
+               var SUBDIVISION_PRECISION = 0.0000001;
+               var SUBDIVISION_MAX_ITERATIONS = 10;
+
+               var kSplineTableSize = 11;
+               var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
+
+               var float32ArraySupported = typeof Float32Array === "function";
+
+               /**
+                *
+                * @param aA1
+                * @param aA2
+                * @returns {number}
+                */
+               function a (aA1, aA2) {
+                       return 1.0 - 3.0 * aA2 + 3.0 * aA1;
+               }
+
+               /**
+                *
+                * @param aA1
+                * @param aA2
+                * @returns {number}
+                */
+               function b (aA1, aA2) {
+                       return 3.0 * aA2 - 6.0 * aA1;
+               }
+
+               /**
+                *
+                * @param aA1
+                * @returns {number}
+                */
+               function c (aA1) {
+                       return 3.0 * aA1;
+               }
+
+               /**
+                * Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
+                * @param aT
+                * @param aA1
+                * @param aA2
+                * @returns {number}
+                */
+               function calcBezier (aT, aA1, aA2) {
+                       return ((a(aA1, aA2)*aT + b(aA1, aA2))*aT + c(aA1))*aT;
+               }
+
+
+               /**
+                * Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
+                * @param aT
+                * @param aA1
+                * @param aA2
+                * @returns {*}
+                */
+               function getSlope (aT, aA1, aA2) {
+                       return 3.0 * a(aA1, aA2)*aT*aT + 2.0 * b(aA1, aA2) * aT + c(aA1);
+               }
+
+               /**
+                *
+                * @param aX
+                * @param aA
+                * @param aB
+                * @param mX1
+                * @param mX2
+                * @returns {*}
+                */
+               function binarySubdivide (aX, aA, aB, mX1, mX2) {
+                       var currentX, currentT, i = 0;
+                       do {
+                               currentT = aA + (aB - aA) / 2.0;
+                               currentX = calcBezier(currentT, mX1, mX2) - aX;
+                               if (currentX > 0.0) {
+                                       aB = currentT;
+                               } else {
+                                       aA = currentT;
+                               }
+                       } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
+                       return currentT;
+               }
+
+               /**
+                *
+                * @param aX
+                * @param aGuessT
+                * @param mX1
+                * @param mX2
+                * @returns {*}
+                */
+               function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
+                       for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
+                               var currentSlope = getSlope(aGuessT, mX1, mX2);
+                               if (currentSlope === 0.0) {
+                                       return aGuessT;
+                               }
+                               var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
+                               aGuessT -= currentX / currentSlope;
+                       }
+                       return aGuessT;
+               }
+
+               function validateArguments(points) {
+                       if (!points || points.length !== 4) {
+                               throw new Error("BezierEasing: points must contains 4 values");
+                       }
+                       for (var i = 0; i < 4; ++i) {
+                               if (typeof points[i] !== "number" || isNaN(points[i]) || !isFinite(points[i])) {
+                                       throw new Error("BezierEasing: points should be integers.");
+                               }
+                       }
+                       if (points[0] < 0 || points[0] > 1 || points[2] < 0 || points[2] > 1) {
+                               throw new Error("BezierEasing x values must be in [0, 1] range.");
+                       }
+               }
+
+               /**
+                * points is an array of [ mX1, mY1, mX2, mY2 ]
+                * @param points
+                * @param _b
+                * @param _c
+                * @param _d
+                * @returns {BezierEasing}
+                * @constructor
+                */
+               function BezierEasing (points, _b, _c, _d) {
+                       if (arguments.length === 4) {
+                               return new BezierEasing([points, _b, _c, _d]);
+                       }
+                       if (!(this instanceof BezierEasing)) {
+                               return new BezierEasing(points);
+                       }
+
+                       validateArguments(points);
+
+                       this._str = "BezierEasing(" + points + ")";
+                       this._css = "cubic-bezier(" + points + ")";
+                       this._p = points;
+                       this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : [];
+                       this._precomputed = false;
+
+                       this.get = this.get.bind(this);
+                       return this;
+               }
+
+               BezierEasing.prototype = {
+
+                       /**
+                        *
+                        * @param x
+                        * @returns {*}
+                        */
+                       get: function (x) {
+                               var mX1 = this._p[0],
+                                       mY1 = this._p[1],
+                                       mX2 = this._p[2],
+                                       mY2 = this._p[3];
+                               if (!this._precomputed) {
+                                       this._precompute();
+                               }
+                               if (mX1 === mY1 && mX2 === mY2) {
+                                       return x;
+                               } // linear
+                               // Because JavaScript number are imprecise, we should guarantee the extremes are right.
+                               if (x <= 0) {
+                                       return 0;
+                               }
+                               if (x >= 1) {
+                                       return 1;
+                               }
+                               return calcBezier(this._getTForX(x), mY1, mY2);
+                       },
+
+                       /**
+                        *
+                        * @private
+                        */
+                       _precompute: function () {
+                               var mX1 = this._p[0],
+                                       mY1 = this._p[1],
+                                       mX2 = this._p[2],
+                                       mY2 = this._p[3];
+                               this._precomputed = true;
+                               if (mX1 !== mY1 || mX2 !== mY2) {
+                                       this._calcSampleValues();
+                               }
+                       },
+
+                       /**
+                        *
+                        * @private
+                        */
+                       _calcSampleValues: function () {
+                               var mX1 = this._p[0],
+                                       mX2 = this._p[2];
+                               for (var i = 0; i < kSplineTableSize; ++i) {
+                                       this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
+                               }
+                       },
+
+                       /**
+                        * getTForX chose the fastest heuristic to determine the percentage value precisely from a
+                        * given X projection.
+                        * @param aX
+                        * @returns {*}
+                        * @private
+                        */
+                       _getTForX: function (aX) {
+                               var mX1 = this._p[0],
+                                       mX2 = this._p[2],
+                                       mSampleValues = this._mSampleValues;
+
+                               var intervalStart = 0.0;
+                               var currentSample = 1;
+                               var lastSample = kSplineTableSize - 1;
+
+                               for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX;
+                                      ++currentSample) {
+                                       intervalStart += kSampleStepSize;
+                               }
+                               --currentSample;
+
+                               // Interpolate to provide an initial guess for t
+                               var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample+1] -
+                                       mSampleValues[currentSample]);
+                               var guessForT = intervalStart + dist * kSampleStepSize;
+
+                               var initialSlope = getSlope(guessForT, mX1, mX2);
+                               if (initialSlope >= NEWTON_MIN_SLOPE) {
+                                       return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
+                               } else if (initialSlope === 0.0) {
+                                       return guessForT;
+                               } else {
+                                       return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
+                               }
+                       }
+               };
+
+               // CSS mapping
+               BezierEasing.css = {
+                       ease:        BezierEasing.ease = new BezierEasing(0.25, 0.1, 0.25, 1.0),
+                       easeIn:     BezierEasing.easeIn = new BezierEasing(0.42, 0.0, 1.00, 1.0),
+                       easeOut:    BezierEasing.easeOut = new BezierEasing(0.00, 0.0, 0.58, 1.0),
+                       easeInOut: BezierEasing.easeInOut = new BezierEasing(0.42, 0.0, 0.58, 1.0)
+               };
+
+               if (ns && ns.util) {
+                       ns.util.bezierCurve = BezierEasing;
+               }
+
+               }());
+
+/* global define, ns */
+/**
+ * Main file of applications, which connect other parts
+ */
+// then we can load plugins for libraries and application
+(function (window, document, ns) {
+       "use strict";
+                       var utils = ns.util,
+                       requestAnimationFrame = utils.requestAnimationFrame,
+                       /**
+                        * Util to change value of object property in given time
+                        * @class Animation
+                        */
+                       Animate = function (object) {
+                               var self = this;
+
+                               self._object = object;
+                               self._animate = {
+                                       chain: [],
+                                       chainIndex: 0
+                               };
+                               // This is used to keep track of elapsed time of paused animation
+                               self._pausedTimeDiff = 0;
+                               self._animateConfig = null;
+                       },
+                       linear = function (x, a, b) {
+                               a = (a === undefined) ? 1 : a;
+                               b = (b === undefined) ? 0 : b;
+                               return x * (a || 0) + (b || 0);
+                       },
+                       inverseTiming = function (x) {
+                               return 1 - x;
+                       },
+                       prototype = {};
+
+               utils.bezierCurve = utils.bezierCurve || bezierCurve;
+
+               Animate.prototype = prototype;
+
+               Animate.timing = {
+                       linear: linear,
+                       ease: utils.bezierCurve.ease.get,
+                       easeInOut: utils.bezierCurve.easeInOut.get,
+                       easeIn: utils.bezierCurve.easeIn.get,
+                       easeOut: utils.bezierCurve.easeOut.get
+               };
+
+               function firstDefined() {
+                       var args = [].slice.call(arguments),
+                               i = 0,
+                               length = args.length,
+                               arg;
+
+                       for (; i < length; i++) {
+                               arg = args[i];
+                               if (arg !== undefined) {
+                                       return arg;
+                               }
+                       }
+                       return null;
+               }
+
+               prototype.destroy = function () {
+                       var self = this;
+
+                       self._object = null;
+                       self._animate = null;
+                       self._animateConfig = null;
+               };
+
+               function calculateSteps(option, currentPoint) {
+                       var percent,
+                               step,
+                               steps = option.steps,
+                               from = option.from,
+                               to = null,
+                               percentStart = 0,
+                               percentStop = 100,
+                               floatPoint;
+
+                       for (percent in steps) {
+                               if (steps.hasOwnProperty(percent)) {
+                                       step = steps[percent];
+                                       floatPoint = percent / 100;
+                                       if (currentPoint >= floatPoint) {
+                                               from = step;
+                                               percentStart = floatPoint;
+                                       } else if (to === null) {
+                                               to = step;
+                                               percentStop = floatPoint;
+                                       }
+                               }
+                       }
+                       return from + (currentPoint - percentStart) / (percentStop - percentStart) *
+                               (to - from);
+               }
+
+               function eachOption(config, animateConfig, option) {
+                       var propertyObject,
+                               from,
+                               steps = option.steps || config.steps;
+
+                       option.duration = firstDefined(option.duration, config.duration);
+                       option.delay = firstDefined(option.delay, config.delay, 0);
+                       propertyObject = firstDefined(option.object, this._object);
+                       option.simpleProperty = option.property;
+                       option.property.split(".").forEach(function (property) {
+                               if (typeof propertyObject[property] === "object" && propertyObject[property] !== null) {
+                                       propertyObject = propertyObject[property];
+                                       option.propertyObject = propertyObject;
+                               } else {
+                                       option.simpleProperty = property;
+                               }
+                       });
+                       option.propertyObject = propertyObject;
+                       if (steps) {
+                               option.calculate = calculateSteps.bind(null, option);
+                               steps[0] = firstDefined(steps[0], option.from, propertyObject[option.simpleProperty]);
+                               option.from = steps["0"];
+                               option.to = firstDefined(steps["100"], option.to);
+                               option.diff = 0;
+                               option.current = steps[0];
+                               option.direction = option.from < option.to ? 1 : -1;
+                       } else {
+                               option.calculate = option.calculate || linear;
+                               from = firstDefined(option.from, propertyObject[option.simpleProperty]);
+                               option.from = from;
+                               option.diff = (option.to - from);
+                               option.current = from;
+                               option.direction = from < option.to ? 1 : -1;
+                       }
+
+                       // calculate value change in full time
+                       option.startTime = Date.now() + option.delay;
+
+                       if (this._pausedTimeDiff > 0) {
+                               option.startTime = Date.now() - this._pausedTimeDiff;
+                               this._pausedTimeDiff = 0;
+                       }
+                       // save last time of recalculate options
+                       option.lastCalculationTime = option.startTime;
+                       // set timing function
+                       option.timing = firstDefined(option.timing, config.timing, linear);
+
+                       animateConfig.push(option);
+               }
+
+               prototype.setProgress = function (progress) {
+                       var self = this,
+                               animate = self._animate,
+                               chain;
+
+                       if (animate.chainIndex > 0) {
+                               chain = animate.chain[animate.chainIndex - 1];
+                       } else {
+                               chain = animate.chain[0];
+                       }
+                       if (chain) {
+                               chain.forEach(function (option) {
+                                       option.progress = progress;
+                                       if (self._pausedTimeDiff === 0) {
+                                               option.startTime = Date.now() - option.duration * progress;
+                                       } else {
+                                               self._pausedTimeDiff = option.duration * progress;
+                                       }
+                               });
+                       }
+               };
+
+               prototype.getProgress = function () {
+                       var self = this,
+                               animate = self._animate,
+                               chain;
+
+                       if (animate.chainIndex > 0) {
+                               chain = animate.chain[animate.chainIndex - 1];
+                       } else {
+                               chain = animate.chain[0];
+                       }
+
+                       if (chain) {
+                               return chain[0].progress;
+                       }
+                       return 0;
+               };
+
+               prototype._initAnimate = function () {
+                       var self = this,
+                               animateConfig = [],
+                               options = self._animate.chain[self._animate.chainIndex++];
+
+                       if (options) {
+                               options.forEach(eachOption.bind(self, self._config, animateConfig));
+                               self._animateConfig = animateConfig;
+                       } else {
+                               self._animateConfig = null;
+                       }
+               };
+
+               function animateLoopCallback(self, copiedArgs) {
+                       if (self._animate) {
+                               self._animate.chain = [].slice.call(copiedArgs);
+                               self.start();
+                       }
+               }
+
+               function animateRevertCallback(self, copiedArgs) {
+                       var chain = [].slice.call(copiedArgs),
+                               newChain = [];
+
+                       chain.forEach(function (options) {
+                               newChain.unshift(options);
+                               options.forEach(function (option) {
+                                       option.timing = inverseTiming;
+                               });
+                       });
+                       self._animate.chain = newChain;
+                       self._animate.callback = null;
+                       self.start();
+               }
+
+               /**
+                * Set animate
+                * @param {Object...} options list of animations configs
+                * @return {Animate}
+                */
+               prototype.set = function (options) {
+                       var self = this,
+                               config,
+                               // converts arguments to array
+                               args = [].slice.call(arguments),
+                               copiedArgs;
+
+                       // we get last argument
+                       config = args.pop();
+
+                       if (!Array.isArray(config)) {
+                       // if last arguments is object then we use it as global animation config
+                               self._animate.config = config;
+                       } else {
+                       // otherwise this is description of one animation loop and back to args array
+                               args.push(config);
+                               config = null;
+                       }
+
+                       self._config = config;
+
+                       // copy array to be sure that we have new reference objects
+                       copiedArgs = [].slice.call(args);
+
+                       if (config) {
+                               if (config.loop && config.duration > 0) {
+                               // when animation is in loop then we create callback on animation and to restart animation
+                                       self._animate.callback = animateLoopCallback.bind(null, self, copiedArgs);
+                               } else if (config.withRevert) {
+                                       self._animate.callback = animateRevertCallback.bind(null, self, copiedArgs);
+                               } else {
+                               // otherwise we use callback from options
+                                       self._animate.callback = options.callback || config.callback;
+                               }
+                       }
+
+                       // cache options in object
+                       self._animate.chain = args;
+
+                       return self;
+               };
+
+               /**
+                * Start animation
+                * @param {Function} [callback] function called after finish animation
+                */
+               prototype.start = function (callback) {
+                       var self = this;
+
+                       self.active = true;
+                       // init animate options
+                       self._initAnimate();
+
+                       // setting callback function
+                       self._animate.callback = self._animate.callback || callback;
+                       callback = self._animate.callback;
+
+                       if (self._animate.chainIndex < self._animate.chain.length) {
+                       // if we have many animations in chain that we set callback
+                       // to start next animation from chain after finish current
+                       // animation
+                               self._animationTimeout = self._calculateAnimate.bind(self, self.start.bind(self, callback));
+                       } else {
+                               self._animationTimeout = self._calculateAnimate.bind(self, callback);
+                       }
+                       self._animationId = Math.random() + Date.now();
+                       self._animationTimeout.animationId = self._animationId;
+                       self._calculateAnimate(callback);
+                       return self;
+               };
+
+               /**
+                * Stop animations
+                */
+               prototype.stop = function () {
+                       var self = this;
+
+                       self.active = false;
+                       // reset index of animations chain
+                       self._animate.chainIndex = 0;
+                       // reset current animation config
+                       self._animateConfig = null;
+
+                       ns.util.cancelAnimationFrames(self._animationId);
+                       // clear timeout
+                       self._animationTimeout = null;
+                       return self;
+               };
+
+               prototype.pause = function () {
+                       var self = this;
+
+                       self.active = false;
+                       if (self._animateConfig) {
+                               self._pausedTimeDiff = Date.now() - self._animateConfig[0].startTime;
+                               self.stop();
+                       }
+               };
+
+               /**
+                * Method resets startTime for each animations to current time
+                * @private
+                * @param {*} animateConfig
+                */
+               function resetStartTimeForAnimateConfig(animateConfig) {
+                       var i,
+                               len;
+
+                       if (animateConfig) {
+                               len = animateConfig.length;
+                               for (i = 0; i < len; i++) {
+                                       animateConfig[i].startTime = Date.now();
+                               }
+                       }
+               }
+
+               /**
+                * Reset animations to initial position
+                */
+               prototype.reset = function () {
+                       var self = this,
+                               restart = self.active;
+
+                       if (restart) {
+                               self.stop();
+                       }
+
+                       self._initAnimate();
+                       resetStartTimeForAnimateConfig(self._animateConfig);
+                       self._pausedTimeDiff = 0;
+                       self._animate.chainIndex = 0;
+
+                       self._calculateAnimate();
+
+                       if (restart) {
+                               self.start();
+                       }
+               }
+
+               function calculateOption(option, time) {
+                       var timeDiff,
+                               current = null;
+
+                       if (option && option.startTime <= time) {
+                       // if option is not delayed
+                               timeDiff = time - option.startTime;
+
+                               if (timeDiff >= option.duration) {
+                                       // if current is bigger then end we finish loop and we take next animate from chain
+                                       timeDiff = option.duration;
+                                       if (option.callback) {
+                                               option.callback();
+                                       }
+                               }
+
+                               if (option.duration > 0) {
+                                       option.progress = timeDiff / option.duration;
+                                       current = option.calculate(
+                                               option.timing(timeDiff / option.duration),
+                                               option.diff,
+                                               option.from,
+                                               option.current
+                                       );
+                               }
+
+                               if (current !== null) {
+                                       option.current = current;
+                                       // we set next calculation time
+                                       option.propertyObject[option.simpleProperty] = option.current;
+                                       if (timeDiff >= option.duration) {
+                                               // inform about remove animation config
+                                               return 2;
+                                       }
+                                       // inform widget about redraw
+                                       return 1;
+                               }
+
+                               if (timeDiff >= option.duration) {
+                                       // inform about remove animation config
+                                       return 2;
+                               }
+                       }
+                       return 0;
+               }
+
+               /**
+                * Method called in loop to calculate current state of animation
+                * @param {Function} callback
+                * @private
+                */
+               prototype._calculateAnimate = function (callback) {
+                       var self = this,
+                               // current animation config
+                               animateConfig = self._animateConfig,
+                               // number of animations which is not finished
+                               notFinishedAnimationsCount,
+                               // flag inform that redraw is necessary
+                               redraw = false,
+                               i = 0,
+                               length,
+                               time = Date.now(),
+                               calculatedOption;
+
+                       if (animateConfig) {
+                               notFinishedAnimationsCount = animateConfig.length;
+                               length = animateConfig.length;
+
+                               // calculating options changed in animation
+                               while (i < length) {
+                                       if (animateConfig[i].duration > 0) {
+                                               calculatedOption = calculateOption(animateConfig[i], time);
+                                               if (calculatedOption === 2) {
+                                                       notFinishedAnimationsCount--;
+                                                       // remove current config and recalculate loop arguments
+                                                       animateConfig.splice(i, 1);
+                                                       length--;
+                                                       i--;
+                                                       redraw = true;
+                                               } else if (calculatedOption === 1) {
+                                                       redraw = true;
+                                               }
+                                       } else {
+                                               notFinishedAnimationsCount--;
+                                       }
+                                       i++;
+                               }
+                               // redraw is necessary
+                               if (redraw && self._tickFunction) {
+                                       self._tickFunction(self._object);
+                               }
+                               if (notFinishedAnimationsCount) {
+                                       // setting next loop state
+                                       if (self._animationTimeout) {
+                                               requestAnimationFrame(self._animationTimeout);
+                                       }
+                               } else {
+                                       // Animation state can be change to "stopped"
+                                       self.stop();
+                                       // animation is finished
+                                       if (callback) {
+                                               callback();
+                                       }
+                               }
+                       }
+               };
+
+               /**
+                * Set function which will be called after animation change property of object
+                * @param {Function} tickFunction
+                * @return {Animation}
+                */
+               prototype.tick = function (tickFunction) {
+                       var oldTickFunction = this._tickFunction;
+
+                       if (oldTickFunction) {
+                               this._tickFunction = function (object) {
+                                       oldTickFunction(object);
+                                       tickFunction(object);
+                               };
+                       } else {
+                               this._tickFunction = tickFunction;
+                       }
+                       return this;
+               };
+
+               utils.Animate = Animate;
+               }(window, window.document, ns));
+
+
+/*global window, define, console, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * # Marquee
+ * Shows a component which moves left and right.
+ *
+ * It makes <div> element with text move horizontally like legacy <marquee> tag
+ *
+ * ## Make Marquee Element
+ * If you want to use Marquee widget, you have to declare below attributes in <div> element and make
+ * Marquee widget in JS code.
+ * To use a Marquee widget in your application, use the following code:
+ *
+ *    @example
+ *    <div class="ui-content">
+ *        <ul class="ui-listview">
+ *            <li><div class="ui-marquee" id="marquee">Marquee widget code sample</div></li>
+ *        </ul>
+ *    </div>
+ *    <script>
+ *        var marqueeEl = document.getElementById("marquee"),
+ *            marqueeWidget = new tau.widget.Marquee(marqueeEl,
+ *              {marqueeStyle: "scroll", delay: "3000"});
+ *    </script>
+ *
+ * @author Heeju Joo <heeju.joo@samsung.com>
+ * @class ns.widget.core.Marquee
+ * @component-selector .ui-marquee
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+       
+                       var BaseWidget = ns.widget.BaseWidget,
+                               /**
+                                * Alias for class ns.engine
+                                * @property {ns.engine} engine
+                                * @member ns.widget.core.Marquee
+                                * @private
+                                */
+                               engine = ns.engine,
+                               /**
+                                * Alias for class ns.util.object
+                                * @property {Object} objectUtils
+                                * @member ns.widget.core.Marquee
+                                * @private
+                                */
+                               objectUtils = ns.util.object,
+
+                               Animation = ns.util.Animate,
+
+                               states = {
+                                       RUNNING: "running",
+                                       STOPPED: "stopped",
+                                       IDLE: "idle"
+                               },
+
+                               Marquee = function () {
+                                       this.options = objectUtils.copy(Marquee.defaults);
+                                       // event callbacks
+                                       this._callbacks = {};
+                                       this._ui = {
+                                               content: null
+                                       };
+                               },
+
+                               prototype = new BaseWidget(),
+
+                               /**
+                               * Standard marquee widget
+                               * @style ui-marquee
+                               * @member ns.widget.core.Marquee
+                               */
+                               CLASSES_PREFIX = "ui-marquee",
+
+                               eventType = {
+                                       /**
+                                        * Triggered when the marquee animation end.
+                                        * @event marqueeend
+                                        * @member ns.widget.core.Marquee
+                                        */
+                                       MARQUEE_START: "marqueestart",
+                                       MARQUEE_END: "marqueeend",
+                                       MARQUEE_STOPPED: "marqueestopped"
+                               },
+                               /**
+                                * Dictionary for CSS class of marquee play state
+                                * @property {Object} classes
+                                * @member ns.widget.core.Marquee
+                                * @static
+                                */
+                               classes = {
+                                       /**
+                                       * Content for marquee widget
+                                       * @style ui-marquee-content
+                                       * @member ns.widget.core.Marquee
+                                       */
+                                       MARQUEE_CONTENT: CLASSES_PREFIX + "-content",
+                                       /**
+                                       * Add gradient for marquee widget
+                                       * @style ui-marquee-gradient
+                                       * @member ns.widget.core.Marquee
+                                       */
+                                       MARQUEE_GRADIENT: CLASSES_PREFIX + "-gradient",
+                                       /**
+                                       * Set ellipsis effect for marquee widget
+                                       * @style ui-marquee-ellipsis
+                                       * @member ns.widget.core.Marquee
+                                       */
+                                       MARQUEE_ELLIPSIS: CLASSES_PREFIX + "-ellipsis",
+                                       /**
+                                       * Start animation for marquee widget
+                                       * @style ui-marquee-anim-running
+                                       * @member ns.widget.core.Marquee
+                                       */
+                                       ANIMATION_RUNNING: CLASSES_PREFIX + "-anim-running",
+                                       /**
+                                       * Stop animation for marquee widget
+                                       * @style ui-marquee-anim-stopped
+                                       * @member ns.widget.core.Marquee
+                                       */
+                                       ANIMATION_STOPPED: CLASSES_PREFIX + "-anim-stopped",
+                                       /**
+                                       * Idle animation for marquee widget
+                                       * @style ui-marquee-anim-idle
+                                       * @member ns.widget.core.Marquee
+                                       */
+                                       ANIMATION_IDLE: CLASSES_PREFIX + "-anim-idle"
+                               },
+
+                               /**
+                                * Dictionary for marquee style
+                                */
+                               style = {
+                                       SCROLL: "scroll",
+                                       SLIDE: "slide",
+                                       ALTERNATE: "alternate",
+                                       ENDTOEND: "endToEnd"
+                               },
+
+                               ellipsisEffect = {
+                                       GRADIENT: "gradient",
+                                       ELLIPSIS: "ellipsis", // deprecated effect
+                                       NONE: "none"
+                               },
+
+                               round100 = function (value) {
+                                       return Math.round(value * 100) / 100;
+                               },
+
+                               /**
+                                * Options for widget
+                                * @property {Object} options
+                                * @property {string|"slide"|"scroll"|"alternate|"endToEnd""} [options.marqueeStyle="slide"] Sets the
+                                * default style for the marquee
+                                * @property {number} [options.speed=60] Sets the speed(px/sec) for the marquee
+                                * @property {number|"infinite"} [options.iteration=1] Sets the iteration count number for
+                                * marquee
+                                * @property {number} [options.delay=2000] Sets the delay(ms) for marquee
+                                * @property {"linear"|"ease"|"ease-in"|"ease-out"|"cubic-bezier(n,n,n,n)"}
+                                * [options.timingFunction="linear"] Sets the timing function for marquee
+                                * @property {"gradient"|"none"} [options.ellipsisEffect="gradient"] Sets the
+                                * end-effect(gradient) of marquee
+                                * @property {boolean} [options.autoRun=true] Sets the status of autoRun
+                                * @member ns.widget.core.Marquee
+                                * @static
+                                */
+                               defaults = {
+                                       marqueeStyle: style.SLIDE,
+                                       speed: 60,
+                                       iteration: "1",
+                                       currentIteration: 1,
+                                       delay: 0,
+                                       timingFunction: "linear",
+                                       ellipsisEffect: ellipsisEffect.GRADIENT,
+                                       runOnlyOnEllipsisText: true,
+                                       animation: states.STOPPED,
+                                       autoRun: true
+                               },
+                               GRADIENTS = {
+                                       LEFT: "-webkit-linear-gradient(left, transparent 0, rgb(255, 255, 255) 15%," +
+                                       " rgb(255, 255, 255) 100%)",
+                                       BOTH: "-webkit-linear-gradient(left, transparent 0, rgb(255, 255, 255)" +
+                                       " 15%, rgb(255, 255, 255) 85%, transparent 100%",
+                                       RIGHT: "-webkit-linear-gradient(left, rgb(255, 255, 255) 0, rgb(255," +
+                                       " 255, 255) 85%, transparent 100%)"
+                               };
+
+                       Marquee.classes = classes;
+                       Marquee.defaults = defaults;
+
+                       prototype._calculateTranslateFunctions = {
+                               scroll: function (self, state, diff, from, current) {
+                                       var value = from + state * diff,
+                                               returnValue;
+
+                                       returnValue = "translateX(" + (-1 * round100(value) || 0) + "px)";
+                                       if (current === returnValue) {
+                                               return null;
+                                       }
+                                       return returnValue;
+                               },
+                               slide: function (self, state, diff, from, current) {
+                                       var stateDOM = self._stateDOM,
+                                               containerWidth = stateDOM.offsetWidth,
+                                               textWidth = stateDOM.children[0].offsetWidth,
+                                               value,
+                                               excludeValue,
+                                               returnValue;
+
+                                       // RIGHT gradient is 85% spec.
+                                       excludeValue = (containerWidth * 15 / 100) / 2;
+                                       value = state * (textWidth - containerWidth + excludeValue);
+                                       returnValue = "translateX(" + (-1 * round100(value) || 0) + "px)";
+                                       if (current === returnValue) {
+                                               return null;
+                                       }
+                                       return returnValue;
+                               },
+                               alternate: function (self, state, diff, from, current) {
+                                       var stateDOM = self._stateDOM,
+                                               containerWidth = stateDOM.offsetWidth,
+                                               textWidth = stateDOM.children[0].offsetWidth,
+                                               value = from + state * diff,
+                                               returnValue;
+
+                                       if (value > textWidth / 2) {
+                                               value = textWidth - (value - textWidth / 2) * 2;
+                                       } else {
+                                               value *= 2;
+                                       }
+                                       value = value / textWidth * (textWidth - containerWidth);
+                                       returnValue = "translateX(" + (-1 * round100(value) || 0) + "px)";
+                                       if (current === returnValue) {
+                                               return null;
+                                       }
+                                       return returnValue;
+                               },
+                               endToEnd: function (self, state, diff, from, current) {
+                                       var value = from + state * diff,
+                                               returnValue;
+
+                                       returnValue = "translateX(" + (-1 * round100(value) || 0) + "px)";
+                                       if (current === returnValue) {
+                                               return null;
+                                       }
+                                       return returnValue;
+                               }
+                       };
+
+                       prototype._calculateEndToEndGradient = function (state) {
+                               var self = this,
+                                       stateDOM = self._stateDOM,
+                                       textWidth = stateDOM.children[0].offsetWidth,
+                                       returnTimeFrame = ((textWidth - 50) / textWidth),
+                                       returnValue;
+
+                               if (self.options.ellipsisEffect === "none") {
+                                       return null;
+                               }
+                               if (state > 0 && self.options.currentIteration < self.options.iteration) {
+                                       // don't change gradient between iterations only for lastpass
+                                       returnValue = GRADIENTS.BOTH;
+                               } else if (state > returnTimeFrame) {
+                                       returnValue = GRADIENTS.RIGHT;
+                               } else if (state > 0) {
+                                       returnValue = GRADIENTS.BOTH;
+                               } else {
+                                       returnValue = GRADIENTS.LEFT;
+                               }
+                               return returnValue;
+                       };
+
+                       prototype._calculateStandardGradient = function (state) {
+                               var returnValue;
+
+                               if (isNaN(state)) {
+                                       return null;
+                               }
+                               if (this.options.ellipsisEffect === "none") {
+                                       return null;
+                               }
+                               if (state === 1) {
+                                       returnValue = GRADIENTS.LEFT;
+                               } else if (state > 0) {
+                                       returnValue = GRADIENTS.BOTH;
+                               } else {
+                                       returnValue = GRADIENTS.RIGHT;
+                               }
+                               return returnValue;
+                       };
+
+                       /**
+                        * Build Marquee DOM
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.core.Marquee
+                        */
+                       prototype._build = function (element) {
+                               var marqueeInnerElement = element.querySelector("." + classes.MARQUEE_CONTENT);
+
+                               element.classList.add(CLASSES_PREFIX);
+
+                               // check deprecated class
+                               if (element.classList.contains(classes.MARQUEE_ELLIPSIS)) {
+                                       ns.warn("Class '" + classes.MARQUEE_ELLIPSIS +
+                                               "' for option 'ellipsisEffect' in Marquee widget has been deprecated. " +
+                                               "Allowed values: none, '" + classes.MARQUEE_GRADIENT + "' (default)");
+                               }
+
+                               if (!marqueeInnerElement) {
+                                       marqueeInnerElement = document.createElement("div");
+
+                                       while (element.hasChildNodes()) {
+                                               marqueeInnerElement.appendChild(element.removeChild(element.firstChild));
+                                       }
+                                       marqueeInnerElement.classList.add(classes.MARQUEE_CONTENT);
+                                       element.appendChild(marqueeInnerElement);
+                               }
+
+                               this._ui.content = marqueeInnerElement;
+
+                               return element;
+                       };
+
+                       prototype._initStateDOMstructure = function () {
+                               this._stateDOM = {
+                                       classList: [],
+                                       offsetWidth: null,
+                                       style: {
+                                               webkitMaskImage: null
+                                       },
+                                       children: [
+                                               {
+                                                       offsetWidth: null,
+                                                       style: {
+                                                               webkitTransform: null
+                                                       }
+                                               }
+                                       ]
+                               };
+                       };
+
+                       prototype._initAnimation = function () {
+                               var self = this,
+                                       stateDOM = self._stateDOM,
+                                       stateDOMfirstChild = stateDOM.children[0],
+                                       width = stateDOMfirstChild.offsetWidth +
+                                               ((self.options.marqueeStyle === style.ENDTOEND) ? 100 : 0),
+                                       animation = new Animation({}),
+                                       state = {
+                                               hasEllipsisText: (width > 0),
+                                               animation: [{
+                                                       object: stateDOMfirstChild.style,
+                                                       property: "webkitTransform",
+                                                       calculate: self._calculateTranslateFunctions.scroll.bind(null, self),
+                                                       from: 0,
+                                                       to: width
+                                               }, {
+                                                       object: stateDOM.style,
+                                                       calculate: self._calculateStandardGradient.bind(self),
+                                                       property: "webkitMaskImage",
+                                                       from: 0,
+                                                       to: 1
+                                               }],
+                                               animationConfig: {
+                                                       duration: width / self.options.speed * 1000,
+                                                       timing: Animation.timing.linear
+                                               }
+                                       };
+
+                               self.state = state;
+
+                               animation.tick(self._render.bind(self, true));
+
+                               self._animation = animation;
+                       };
+
+                       /**
+                        * Init Marquee Style
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.core.Marquee
+                        */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self._initStateDOMstructure();
+                               self._initDOMstate();
+                               self._initAnimation();
+                               self.option(self.options);
+
+                               return element;
+                       };
+
+                       prototype._setEllipsisEffect = function (element, value) {
+                               if (value === "ellipsis") {
+                                       ns.warn("Marquee: option value 'ellipsis' for 'ellipsisEffect' is deprecated. Allowed values: 'none', 'gradient' (default)");
+                               }
+                               return this._togglePrefixedClass(this._stateDOM, CLASSES_PREFIX + "-", value);
+                       };
+
+                       prototype._updateDuration = function () {
+                               var self = this,
+                                       stateDOM = self._stateDOM,
+                                       state = self.state,
+                                       firstChild = stateDOM.children[0],
+                                       width = firstChild.offsetWidth,
+                                       dWidth = width - stateDOM.offsetWidth,
+                                       animationConfig = state.animationConfig;
+
+                               animationConfig.duration = (dWidth > 0) ?
+                                       width / self.options.speed * 1000 :
+                                       0;
+                               self._animation.set(state.animation, animationConfig);
+                       };
+
+                       prototype._setSpeed = function (element, value) {
+                               var self = this;
+
+                               self.options.speed = parseInt(value, 10);
+                               self._updateDuration();
+                               return false;
+                       };
+
+                       function animationIterationCallback(self) {
+                               var animation = self._animation,
+                                       state = self.state;
+
+                               if (self.options.currentIteration++ < self.options.iteration || self.options.iteration === "infinite") {
+                                       animation.set(state.animation, state.animationConfig);
+                                       animation.stop();
+                                       animation.start();
+                               } else {
+                                       if (self.options.marqueeStyle === style.ENDTOEND) {
+                                               self._ui.content.classList.remove("ui-visible");
+                                       }
+                                       self.reset();
+                                       self.options.animation = states.STOPPED;
+                                       self.trigger(eventType.MARQUEE_END);
+                               }
+                       }
+
+                       prototype._setIteration = function (element, value) {
+                               var self = this,
+                                       state = self.state,
+                                       animationConfig = state.animationConfig;
+
+                               if (value === "infinite") {
+                                       animationConfig.loop = true;
+                                       animationConfig.callback = function () {
+                                               self.options.animation = states.STOPPED;
+                                               self.trigger.bind(self, eventType.MARQUEE_END);
+                                       };
+                               } else {
+                                       value = parseInt(value, 10);
+                                       self.options.currentIteration = 1;
+                                       animationConfig.loop = false;
+                                       animationConfig.callback = animationIterationCallback.bind(null, self);
+                               }
+                               self._animation.set(state.animation, animationConfig);
+                               self.options.iteration = value;
+                               return false;
+                       };
+
+                       prototype._setDelay = function (element, value) {
+                               var self = this,
+                                       state = self.state,
+                                       animationConfig = state.animationConfig;
+
+                               value = parseInt(value, 10);
+                               animationConfig.delay = value;
+                               self._animation.set(state.animation, animationConfig);
+                               self.options.delay = value;
+                               return false;
+                       };
+
+                       prototype._setTimingFunction = function (element, value) {
+                               var self = this,
+                                       state = self.state,
+                                       animationConfig = state.animationConfig;
+
+                               animationConfig.timing = Animation.timing[value];
+                               self._animation.set(state.animation, animationConfig);
+                               self.options.timing = value;
+                               return false;
+                       };
+
+                       prototype._setAutoRun = function (element, value) {
+                               if (value) {
+                                       this.start();
+                               }
+                               return false;
+                       };
+
+                       prototype._setAnimation = function (element, value) {
+                               var self = this,
+                                       animation = self._animation,
+                                       stateDOM = self._stateDOM,
+                                       options = self.options,
+                                       width = stateDOM.children[0].offsetWidth - stateDOM.offsetWidth,
+                                       runOnlyOnEllipsisText = options.runOnlyOnEllipsisText;
+
+                               if (value !== options.animation) {
+                                       if (value === states.RUNNING) {
+                                               if ((runOnlyOnEllipsisText && width > 0) || (!runOnlyOnEllipsisText)) {
+                                                       // copy of text content to title and after pseudo element
+                                                       self._ui.content.setAttribute("title", self._ui.content.textContent.trim());
+                                                       if (self.options.marqueeStyle === style.ENDTOEND) {
+                                                               self._ui.content.classList.add("ui-visible");
+                                                       }
+                                                       animation.start();
+                                                       options.animation = value;
+                                                       self.trigger(eventType.MARQUEE_START);
+                                               }
+                                       } else {
+                                               if (self.options.marqueeStyle === style.ENDTOEND) {
+                                                       self._ui.content.classList.remove("ui-visible");
+                                               }
+                                               animation.pause();
+                                               options.animation = value;
+                                               self.trigger(eventType.MARQUEE_STOPPED);
+                                       }
+                               }
+                               return false;
+                       };
+
+                       prototype._setMarqueeStyle = function (element, value) {
+                               var self = this,
+                                       animation = self.state.animation;
+
+                               animation[0].calculate = self._calculateTranslateFunctions[value].bind(null, self);
+                               if (value === "endToEnd") {
+                                       animation[1].calculate = self._calculateEndToEndGradient.bind(self);
+                               } else {
+                                       animation[1].calculate = self._calculateStandardGradient.bind(self);
+                               }
+                               self.options.marqueeStyle = value;
+                               return false;
+                       };
+
+                       /**
+                        * Destroy widget
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.core.Marquee
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       marqueeInnerElement;
+
+                               self.state = null;
+                               if (self._animation) {
+                                       self._animation.stop();
+                                       self._animation.destroy();
+                                       self._animation = null;
+                               }
+                               self.element.style.webkitMaskImage = "";
+
+                               marqueeInnerElement = self.element.querySelector("." + classes.MARQUEE_CONTENT);
+                               if (marqueeInnerElement) {
+                                       while (marqueeInnerElement.hasChildNodes()) {
+                                               self.element.appendChild(marqueeInnerElement.removeChild(marqueeInnerElement.firstChild));
+                                       }
+                                       self._stateDOM.children = [];
+                                       if (marqueeInnerElement.parentElement === self.element) {
+                                               self.element.removeChild(marqueeInnerElement);
+                                       }
+                               }
+                               self._stateDOM = null;
+                       };
+
+                       /**
+                        * Start Marquee animation
+                        *
+                        * #####Running example in pure JavaScript:
+                        *
+                        *    @example
+                        *    <div class="ui-marquee" id="marquee">
+                        *        <p>MarqueeTEST TEST message TEST for marquee</p>
+                        *    </div>
+                        *    <script>
+                        *        var marqueeWidget = tau.widget.Marquee(document.getElementById("marquee"));
+                        *        marqueeWidget.start();
+                        *    </script>
+                        *
+                        * @method start
+                        * @member ns.widget.core.Marquee
+                        */
+                       prototype.start = function () {
+                               this.option("animation", "running");
+                       };
+
+                       /**
+                        * Pause Marquee animation
+                        *
+                        * #####Running example in pure JavaScript:
+                        *    @example
+                        *    <div class="ui-marquee" id="marquee">
+                        *        <p>MarqueeTEST TEST message TEST for marquee</p>
+                        *    </div>
+                        *    <script>
+                        *        var marqueeWidget = tau.widget.Marquee(document.getElementById("marquee"));
+                        *        marqueeWidget.stop();
+                        *    </script>
+                        *
+                        * @method stop
+                        * @member ns.widget.core.Marquee
+                        */
+                       prototype.stop = function () {
+                               this.option("animation", "stopped");
+                       };
+
+                       /**
+                        * Reset Marquee animation
+                        *
+                        * #####Running example in pure JavaScript:
+                        *    @example
+                        *    <div class="ui-marquee" id="marquee">
+                        *        <p>MarqueeTEST TEST message TEST for marquee</p>
+                        *    </div>
+                        *    <script>
+                        *        var marqueeWidget = tau.widget.Marquee(document.getElementById("marquee"));
+                        *        marqueeWidget.reset();
+                        *    </script>
+                        *
+                        * @method reset
+                        * @member ns.widget.core.Marquee
+                        */
+                       prototype.reset = function () {
+                               var self = this,
+                                       animation = self._animation;
+
+                               animation.reset();
+
+                               self.element.style.webkitMaskImage = (self.options.ellipsisEffect === "none") ?
+                                       "" : GRADIENTS.RIGHT;
+                       };
+
+                       Marquee.prototype = prototype;
+                       ns.widget.core.Marquee = Marquee;
+
+                       engine.defineWidget(
+                               "Marquee",
+                               ".ui-marquee",
+                               ["start", "stop", "reset"],
+                               Marquee,
+                               "core"
+                       );
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * # Sub Tab Widget
+ * The subTab widget shows an unordered list of tabs on the screen wrapped
+ * together in a single group.
+ *
+ * This widget can be placed in at top of page inside Tabs widget.
+ *
+ * ## Default selectors
+ * In default elements matches to:
+ *
+ *  - HTML elements with class ui-sub-tab
+ *
+ * ##Methods
+ *
+ * To call method on widget you can use one of existing API:
+ *
+ * First API is from tau namespace:
+ *
+ *        @example
+ *        <script>
+ *        var subTabElement = document.getElementById("sub-tab"),
+ *            subTab = tau.widget.SubTab(SubTabElement);
+ *
+ *        subTab.methodName(methodArgument1, methodArgument2, ...);
+ *        </script>
+ *
+ * Second API is jQuery Mobile API and for call _methodName_ you can use:
+ *
+ *        @example
+ *        <script>
+ *        $(".selector").subTab("methodName", methodArgument1, methodArgument2, ...);
+ *        </script>
+ *
+ * @class ns.widget.core.SubTab
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var Tab = ns.widget.core.Tab,
+                               TabPrototype = Tab.prototype,
+                               engine = ns.engine,
+                               domUtils = ns.util.DOM,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+
+                               SubTab = function () {
+                                       var self = this;
+
+                                       BaseKeyboardSupport.call(this);
+
+                                       self._type = {
+                                               orientation: "portrait",
+                                               withIcon: false,
+                                               withTitle: false,
+                                               static: false
+                                       };
+                                       self._ui = {
+                                               tabs: [],
+                                               links: []
+                                       };
+                                       /**
+                                        * Object with default options
+                                        * @property {Object} options
+                                        * @property {string} [options.active="0"] Number of activated tab.
+                                        * @property {string} [options.autoChange=true] Defined if widget should set
+                                        * @member ns.widget.core.SubTab
+                                        */
+                                       self.options = {
+                                               active: 0,
+                                               autoChange: true,
+                                               autoPositionSet: true
+                                       };
+                                       self._marqueeOptions = {
+                                               ellipsisEffect: "none",
+                                               marqueeStyle: "endToEnd",
+                                               iteration: "infinite",
+                                               delay: 1000
+                                       };
+                                       self._actualActiveTab = null;
+                               },
+                               CLASS_PREFIX = "ui-sub-tab",
+                               /**
+                                * Object with class dictionary
+                                * @property {Object} classes
+                                * @static
+                                * @member ns.widget.core.SubTab
+                                * @readonly
+                                */
+                               classes = {
+                                       SUBTAB: CLASS_PREFIX,
+                                       TAB_ACTIVE: "ui-tab-active",
+                                       TAB_NO_TEXT: "ui-tab-no-text",
+                                       TITLE: "ui-title",
+                                       SUBTAB_PORTRAIT: CLASS_PREFIX + "-portrait",
+                                       SUBTAB_LANDSCAPE: CLASS_PREFIX + "-landscape",
+                                       SUBTAB_TEXT: CLASS_PREFIX + "-text",
+                                       SUBTAB_STATIC: CLASS_PREFIX + "-static",
+                                       ANCHOR: CLASS_PREFIX + "-anchor",
+                                       INACTIVE_TOO_LONG_TEXT: CLASS_PREFIX + "-inactive-text-overflow"
+                               },
+                               events = ns.event,
+                               prototype = new Tab();
+
+                       SubTab.prototype = prototype;
+                       SubTab.classes = classes;
+                       SubTab.selector = "." + CLASS_PREFIX +
+                               ",[data-role='tabbar'],.ui-tabbar"; // deprecated selector
+
+                       /**
+                        * Configure widget options, detect active item based on classes
+                        * @method _configure
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.core.SubTab
+                        */
+                       prototype._configure = function (element) {
+                               var links = element.querySelectorAll("li a"),
+                                       activeIndex = -1;
+
+                               [].forEach.call(links, function (linkElement, index) {
+                                       if (linkElement.classList.contains(classes.TAB_ACTIVE)) {
+                                               activeIndex = index;
+                                       }
+                               });
+                               if (activeIndex > -1) {
+                                       this.options.active = activeIndex;
+                               }
+                       };
+
+                       /**
+                        * Build tabs and links, add classes, create span labels
+                        * @method _buildTabsAndLinks
+                        * @param {HTMLElement} element
+                        * @return {boolean}
+                        * @protected
+                        * @member ns.widget.core.SubTab
+                        */
+                       prototype._buildTabsAndLinks = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       tabs = element.querySelectorAll("li"),
+                                       links = element.querySelectorAll("li a"),
+                                       innerText,
+                                       i,
+                                       linksLength,
+                                       link,
+                                       text,
+                                       textRealWidth,
+                                       visibleTextWidth,
+                                       prevTextOverflowVal;
+
+                               if (links.length === 0) {
+                                       links = element.querySelectorAll("li div");
+                               }
+                               if (links.length === 0) {
+                                       ns.warn("There is no tab element, SubTab wasn't build.");
+                                       return false;
+                               }
+                               for (i = 0, linksLength = links.length; i < linksLength; i++) {
+                                       link = links[i];
+                                       text = link.firstChild;
+                                       if (text) {
+                                               innerText = document.createElement("span");
+                                               innerText.classList.add(classes.SUBTAB_TEXT);
+                                               innerText.appendChild(link.firstChild);
+                                               link.appendChild(innerText);
+
+                                               prevTextOverflowVal = innerText.style.overflowX;
+                                               visibleTextWidth = innerText.getBoundingClientRect().width;
+                                               innerText.style.overflowX = "visible";
+                                               textRealWidth = innerText.getBoundingClientRect().width;
+                                               innerText.style.overflowX = prevTextOverflowVal;
+
+                                               if (textRealWidth > visibleTextWidth) {
+                                                       link.classList.add(classes.INACTIVE_TOO_LONG_TEXT);
+                                               }
+
+                                       } else {
+                                               link.classList.add(classes.TAB_NO_TEXT);
+                                       }
+                                       link.classList.add(classes.ANCHOR);
+                               }
+                               ui.links = links;
+                               ui.tabs = tabs;
+                               return true;
+                       };
+
+                       /**
+                        * Build method
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement|null}
+                        * @protected
+                        * @member ns.widget.core.SubTab
+                        */
+                       prototype._build = function (element) {
+                               var self = this;
+
+                               element.classList.add(classes.SUBTAB);
+
+                               if (!self._buildTabsAndLinks(element)) {
+                                       return null;
+                               }
+
+                               return element;
+                       };
+
+                       /**
+                        * Method read current orientation and set state of widget for correct state;
+                        * @param {HTMLElement} element
+                        * @method _initOrientation
+                        * @member ns.widget.core.SubTab
+                        * @protected
+                        */
+                       prototype._initOrientation = function (element) {
+                               var type = this._type,
+                                       classList = element.classList;
+
+                               if (window.innerWidth < window.innerHeight) {
+                                       classList.remove(classes.SUBTAB_LANDSCAPE);
+                                       classList.add(classes.SUBTAB_PORTRAIT);
+                                       type.orientation = "portrait";
+                               } else {
+                                       classList.remove(classes.SUBTAB_PORTRAIT);
+                                       classList.add(classes.SUBTAB_LANDSCAPE);
+                                       type.orientation = "landscape";
+                               }
+                       };
+
+                       /**
+                        * Method init all width of elements and update state of widget.
+                        * @param {HTMLElement} element
+                        * @method _initStaticAndWidths
+                        * @private
+                        */
+                       prototype._initStaticAndWidths = function (element) {
+                               var self = this,
+                                       isStatic,
+                                       tabs = self._ui.tabs,
+                                       offsetWidth = element.getBoundingClientRect().width,
+                                       length = tabs.length,
+                                       wholeWidth = 0,
+                                       elementWidth,
+                                       i;
+
+                               // check that element is visible
+                               if (offsetWidth) {
+                                       // get from class
+                                       isStatic = element.classList.contains(classes.SUBTAB_STATIC);
+
+                                       // check if we have enough elements to make the list dynamic again
+                                       if (!isStatic && tabs[0]) {
+                                               elementWidth = domUtils.getElementWidth(tabs[0]);
+                                               // check NaN
+                                               if (elementWidth === elementWidth && (elementWidth * length < offsetWidth)) {
+                                                       isStatic = true;
+                                               }
+                                       }
+
+                                       self._type.static = isStatic;
+
+                                       for (i = 0; i < length; i++) {
+                                               // make the elements "fit"
+                                               if (isStatic) {
+                                                       elementWidth = parseInt(offsetWidth / length, 10) || 0;
+                                                       tabs[i].style.width = elementWidth + "px";
+                                               } else {
+                                                       // just get each element with for scroll support
+                                                       elementWidth = domUtils.getElementWidth(tabs[i]);
+                                               }
+                                               wholeWidth += elementWidth;
+                                       }
+
+                                       self._wholeWidth = wholeWidth;
+                               }
+                       };
+
+                       /**
+                        * Init method
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.SubTab
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self._initOrientation(element);
+                               self._initStaticAndWidths(element);
+
+                               self._translatedX = 0;
+                               self._lastX = 0;
+
+                               self._setActive(self.options.active);
+
+                               return element;
+                       };
+
+                       /**
+                        * Bind events for widget
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.core.SubTab
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       tabs = self._ui.tabs;
+
+                               events.on(tabs, "vclick", self, false);
+                               window.addEventListener("resize", self, false);
+                       };
+
+                       /**
+                        * Unbind events for widget
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.core.SubTab
+                        */
+                       prototype._unBindEvents = function () {
+                               var self = this,
+                                       tabs = self._ui.tabs;
+
+                               events.off(tabs, "vclick", self, false);
+                               window.removeEventListener("resize", self, false);
+                       };
+
+                       /**
+                        * Handle events
+                        * @method handleEvent
+                        * @param {Event} event
+                        * @member ns.widget.core.SubTab
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "vclick":
+                                               self._onClick(event);
+                                               break;
+                                       case "resize":
+                                               self._init(self.element);
+                               }
+                       };
+
+                       /**
+                        * click event handler
+                        * @method _onClick
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.core.SubTab
+                        */
+                       prototype._onClick = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       selectTab = event.currentTarget.querySelector("A"),
+                                       index,
+                                       i,
+                                       tabLength;
+
+                               for (i = 0, tabLength = ui.links.length; i < tabLength; i++) {
+                                       if (ui.links[i] === selectTab) {
+                                               index = i;
+                                               break;
+                                       }
+                                       index = 0;
+                               }
+
+                               if (options.autoChange) {
+                                       self._setActive(index);
+                               }
+                       };
+
+                       /**
+                        * set the active tab
+                        * @method _setActive
+                        * @param {number} index
+                        * @protected
+                        * @member ns.widget.core.SubTab
+                        */
+                       prototype._setActive = function (index) {
+                               var self = this,
+                                       options = self.options,
+                                       ui = self._ui,
+                                       link,
+                                       text,
+                                       marquee,
+                                       prevStyleValue,
+                                       textWidth,
+                                       allTextWidth;
+
+                               if (ui.links.length === 0 || index === self._actualActiveTab) {
+                                       return;
+                               }
+                               // disable previous link
+                               link = ui.links[options.active]
+                               link.classList.remove(classes.TAB_ACTIVE);
+                               text = link.querySelector("." + classes.SUBTAB_TEXT);
+                               if (text) {
+                                       marquee = ns.engine.getBinding(text);
+                                       if (marquee) {
+                                               marquee.reset();
+                                               ns.engine.destroyWidget(text);
+                                               link.classList.add(classes.INACTIVE_TOO_LONG_TEXT);
+                                       }
+                               }
+
+                               // if keyboard support
+                               if (self.isKeyboardSupport === true) {
+                                       ui.links[index].focus();
+                               }
+
+                               // enable new link
+                               link = ui.links[index];
+                               link.classList.add(classes.TAB_ACTIVE);
+                               options.active = index;
+
+                               // enable Marquee widget on text content for active tab
+                               // if text content is longer then link
+                               text = link.querySelector("." + classes.SUBTAB_TEXT);
+                               if (text) {
+                                       prevStyleValue = text.style.overflowX;
+                                       textWidth = text.getBoundingClientRect().width;
+                                       text.style.overflowX = "visible";
+                                       allTextWidth = text.getBoundingClientRect().width;
+                                       text.style.overflowX = prevStyleValue;
+
+                                       if (allTextWidth > textWidth) {
+                                               link.classList.remove(classes.INACTIVE_TOO_LONG_TEXT);
+                                               ns.widget.Marquee(text, self._marqueeOptions);
+                                       }
+                               }
+
+                               TabPrototype._setActive.call(self, index);
+                               self._actualActiveTab = index;
+                       };
+
+                       /**
+                        * Destroy widget
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.core.SubTab
+                        */
+                       prototype._destroy = function () {
+                               var self = this;
+
+                               self._unBindEvents();
+                               self._type = null;
+                               self._ui = null;
+                               self.options = null;
+                       };
+
+                       ns.widget.core.SubTab = SubTab;
+                       engine.defineWidget(
+                               "SubTab",
+                               SubTab.selector,
+                               [
+                                       "setActive",
+                                       "getActive"
+                               ],
+                               SubTab
+                       );
+                       }(window.document, ns));
+
+/*global ns, define */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Main Tab
+ * Main Tab component is dedicated to control page change in app.
+ * The component is positioned always on bottom of the screen.
+ *
+ * @class ns.widget.core.MainTab
+ * @extends ns.widget.BaseWidget
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               utilSelectors = ns.util.selectors,
+                               FILE_REGEXP = /[^\/]+$/,
+                               classes = {
+                                       /**
+                                        * Standard widget
+                                        * @style ui-main-tab
+                                        * @member ns.widget.core.MainTab
+                                        */
+                                       MAIN_TAB: "ui-main-tab",
+                                       /**
+                                        * Set Main Tab widget as visible
+                                        * @style ui-main-tab-visible
+                                        * @member ns.widget.core.MainTab
+                                        */
+                                       VISIBLE: "ui-main-tab-visible",
+                                       /**
+                                        * Set Tab as active
+                                        * @style ui-tab-active
+                                        * @member ns.widget.core.MainTab
+                                        */
+                                       ACTIVE_TAB: "ui-tab-active"
+                               },
+                               MainTab = function () {
+                                       this._ui = {};
+                               },
+                               prototype = new BaseWidget();
+
+                       MainTab.classes = classes;
+                       MainTab.prototype = prototype;
+
+                       /**
+                        * Build MainTab component
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} Returns built element
+                        * @member ns.widget.core.MainTab
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               element.classList.add(classes.MAIN_TAB);
+
+                               return element;
+                       };
+
+                       /**
+                        * Init MainTab component
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} Returns built element
+                        * @member ns.widget.core.MainTab
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       pageContainer = null;
+
+                               self._ui.parentPage = utilSelectors.getClosestBySelector(element, ".ui-page");
+
+                               self._ui.links = [].slice.call(element.querySelectorAll("li > a"));
+                               self._ui.links.forEach(function (link) {
+                                       var wrap = document.createElement("span"),
+                                               content = link.textContent.trim();
+
+                                       wrap.textContent = content;
+                                       link.textContent = "";
+                                       link.appendChild(wrap);
+
+                                       ns.widget.Marquee(wrap, {
+                                               iteration: 1,
+                                               delay: 0,
+                                               marqueeStyle: "endToEnd",
+                                               autoRun: false
+                                       });
+                                       link.setAttribute("data-rel", "maintab");
+                               });
+
+                               element.classList.add(classes.VISIBLE);
+
+                               // change parent to pageContainer instead of page
+                               pageContainer = utilSelectors.getClosestBySelector(element, ".ui-page-container");
+                               pageContainer.appendChild(element);
+
+                               return element;
+                       };
+
+                       /**
+                        * Handle events
+                        * @param {Event} event
+                        * @method handleEvent
+                        * @protected
+                        * @member ns.widget.core.MainTab
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "pagebeforeshow":
+                                               self._onPageBeforeShow(event);
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * Bind events for MainTab
+                        * @method _bindEvents
+                        * @member ns.widget.core.MainTab
+                        * @protected
+                        */
+                       prototype._bindEvents = function () {
+                               document.addEventListener("pagebeforeshow", this, true);
+                       };
+
+                       /**
+                        * Unbind events for MainTab
+                        * @method _bindEvents
+                        * @member ns.widget.core.MainTab
+                        * @protected
+                        */
+                       prototype._unbindEvents = function () {
+                               document.removeEventListener("pagebeforeshow", this, true);
+                       };
+
+                       /**
+                        * Handler for "pagebeforeshow" event on page
+                        * which is parent to MainTab widget
+                        * @param {Event} event
+                        * @method _onPageBeforeShow
+                        * @member ns.widget.core.MainTab
+                        * @protected
+                        */
+                       prototype._onPageBeforeShow = function (event) {
+                               var self = this,
+                                       target = event.target,
+                                       element = self.element,
+                                       links = self._ui.links,
+                                       router,
+                                       activeLink,
+                                       url,
+                                       file;
+
+                               if (self._ui.parentPage === target) {
+                                       // try to find active tab
+                                       activeLink = links.filter(function (link) {
+                                               return link.classList.contains(classes.ACTIVE_TAB);
+                                       })[0] || element.querySelector("a");
+
+                                       if (activeLink) {
+                                               // show widget main tab
+                                               element.classList.add(classes.VISIBLE);
+
+                                               // open active tab
+                                               router = ns.router.Router.getInstance();
+                                               router.open(activeLink.getAttribute("href"), {rel: "maintab"});
+                                       } else {
+                                               ns.warn("MainTab: The widget requires at least one tab with link");
+                                       }
+                               } else if (element.classList.contains(classes.VISIBLE)) {
+                                       // select active tab
+                                       url = target.getAttribute("data-url");
+                                       file = url.match(FILE_REGEXP)[0];
+                                       if (file) { // current page matches to links
+                                               activeLink = links.filter(function (link) {
+                                                       return link.getAttribute("href").indexOf(file) > -1;
+                                               })[0];
+                                               if (activeLink) { // current active page is still in scope of MainTab
+                                                       if (!activeLink.classList.contains(classes.ACTIVE_TAB)) {
+                                                               links.forEach(function (link) {
+                                                                       link.classList.toggle(classes.ACTIVE_TAB, (link.getAttribute("href").indexOf(file) > -1));
+                                                               });
+                                                       }
+                                                       // Content area without appbar has disabled top rounds on MainTab
+                                                       self._disableTopRounds(target);
+                                               } else {
+                                                       // active page is out of Main Tab (hide MainTab)
+                                                       element.classList.remove(classes.VISIBLE);
+                                               }
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Disable top round in content area
+                        * @param {HTMLElement} page
+                        * @method _disableTopRounds
+                        * @member ns.widget.core.MainTab
+                        * @protected
+                        */
+                       prototype._disableTopRounds = function (page) {
+                               var appbar = page.querySelector(".ui-appbar"),
+                                       contentArea;
+
+                               if (!appbar) {
+                                       contentArea = page.querySelector(".ui-content-area");
+                                       contentArea.classList.add("ui-content-area-disabled-top-rounding");
+                               }
+                       };
+
+                       /**
+                        * Destroy MainTab component
+                        * @method _destroy
+                        * @member ns.widget.core.MainTab
+                        * @protected
+                        */
+                       prototype._destroy = function () {
+                               this._unbindEvents();
+                       };
+
+                       // definition
+                       ns.widget.core.MainTab = MainTab;
+
+                       engine.defineWidget(
+                               "MainTab",
+                               "[data-role='main-tab'], .ui-main-tab",
+                               [],
+                               MainTab,
+                               "core"
+                       );
+                       }(window.document, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, ns, define, NodeList, HTMLCollection */
+/*
+ * @author Jadwiga Sosnowska <j.sosnowska@partner.samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+       
+                       var /**
+                                * @property {number} [containerCounter=0]
+                                * @member ns.util.DOM
+                                * @private
+                                * @static
+                                */
+                               containerCounter = 0,
+                               /**
+                                * Alias to Array.slice method
+                                * @method slice
+                                * @member ns.util.DOM
+                                * @private
+                                * @static
+                                */
+                               slice = [].slice,
+                               DOM = ns.util.DOM,
+                               contentRegex = /(\$\{content\})/gi;
+
+                       /**
+                        * Checks if element was converted via WebComponentsJS,
+                        * this will return false if WC support is native
+                        * @param {HTMLElement} node
+                        * @return {boolean}
+                        * @static
+                        * @member ns.util.DOM
+                        */
+                       function isNodeWebComponentPolyfilled(node) {
+                               var keys;
+
+                               if (!node) {
+                                       return false;
+                               }
+                               // hacks
+                               keys = Object.keys(node).join(":");
+                               return (keys.indexOf("__impl") > -1 || keys.indexOf("__upgraded__") > -1 ||
+                                               keys.indexOf("__attached__") > -1);
+                       }
+
+                       /**
+                        * Returns wrapped element which was normal HTML element
+                        * by WebComponent polyfill
+                        * @param {HTMLElement} element
+                        * @return {?HTMLElement}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function wrapWebComponentPolyfill(element) {
+                               var wrap = window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.wrap;
+
+                               if (element && wrap) {
+                                       return wrap(element);
+                               }
+                               
+                               return element;
+                       }
+
+                       /**
+                        * Returns normal element which was wrapped
+                        * by WebComponent polyfill
+                        * @param {HTMLElement} element
+                        * @return {?HTMLElement}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       function unwrapWebComponentPolyfill(element) {
+                               var unwrap = window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.unwrap;
+
+                               if (element && unwrap) {
+                                       return unwrap(element);
+                               }
+
+                               ns.error("Unwrap method not available");
+                               return element;
+                       }
+                       /**
+                        * Creates a selector for given node
+                        * @param {HTMLElement} node
+                        * @return {string}
+                        * @member ns.util.DOM
+                        * @method getNodeSelector
+                        */
+                       function getNodeSelector(node) {
+                               var attributes = node.attributes,
+                                       attributeLength = attributes.length,
+                                       attr,
+                                       i = 0,
+                                       selector = node.tagName.toLowerCase();
+
+                               for (; i < attributeLength; ++i) {
+                                       attr = attributes.item(i);
+                                       selector += "[" + attr.name + "=\"" + attr.value + "\"]";
+                               }
+                               return selector;
+                       }
+
+                       /**
+                        * Creates selector path (node and its parents) for given node
+                        * @param {HTMLElement} node
+                        * @return {string}
+                        * @member ns.util.DOM
+                        * @method getNodeSelectorPath
+                        */
+                       function getNodeSelectorPath(node) {
+                               var path = getNodeSelector(node),
+                                       parent = node.parentNode;
+
+                               while (parent) {
+
+                                       path = getNodeSelector(parent) + ">" + path;
+
+                                       parent = parent.parentNode;
+                                       if (parent === document) {
+                                               parent = null;
+                                       }
+                               }
+                               return path;
+                       }
+
+                       DOM.getNodeSelector = getNodeSelector;
+                       DOM.getNodeSelectorPath = getNodeSelectorPath;
+
+                       /**
+                        * Compares a node to another node
+                        * note: this is needed because of broken WebComponents node wrapping
+                        * @param {HTMLElement} nodeA
+                        * @param {HTMLElement} nodeB
+                        * @return {boolean}
+                        * @member ns.util.DOM
+                        * @method isNodeEqual
+                        */
+                       DOM.isNodeEqual = function (nodeA, nodeB) {
+                               var nodeAPolyfilled,
+                                       nodeBPolyfilled,
+                                       foundNodeA = nodeA,
+                                       foundNodeB = nodeB,
+                                       unwrap = (window.ShadowDOMPolyfill && window.ShadowDOMPolyfill.unwrap); // hack
+
+                               if (nodeA === null || nodeB === null) {
+                                       return false;
+                               } else {
+                                       nodeAPolyfilled = isNodeWebComponentPolyfilled(nodeA);
+                                       nodeBPolyfilled = isNodeWebComponentPolyfilled(nodeB);
+                               }
+
+                               if (nodeAPolyfilled) {
+                                       if (unwrap) {
+                                               foundNodeA = unwrap(nodeA);
+                                       } else {
+                                               foundNodeA = document.querySelector(getNodeSelectorPath(nodeA));
+                                       }
+                               }
+                               if (nodeBPolyfilled) {
+                                       if (unwrap) {
+                                               foundNodeB = unwrap(nodeB);
+                                       } else {
+                                               foundNodeB = document.querySelector(getNodeSelectorPath(nodeB));
+                                       }
+                               }
+
+                               return foundNodeA === foundNodeB;
+                       };
+
+                       /**
+                        * Checks if element was converted via WebComponentsJS,
+                        * this will return false if WC support is native
+                        * @method isNodeWebComponentPolyfilled
+                        * @param {HTMLElement} node
+                        * @return {boolean}
+                        * @static
+                        * @member ns.util.DOM
+                        */
+                       DOM.isNodeWebComponentPolyfilled = isNodeWebComponentPolyfilled;
+
+                       DOM.unwrapWebComponentPolyfill = unwrapWebComponentPolyfill;
+                       DOM.wrapWebComponentPolyfill = wrapWebComponentPolyfill;
+
+                       DOM.isElement = function (element) {
+                               var raw = element;
+
+                               if (!raw) {
+                                       return false;
+                               }
+
+                               // Dirty hack for bogus WebComponent polyfill
+                               if (typeof raw.localName === "string" && raw.localName.length > 0) {
+                                       return true;
+                               }
+
+                               if (!(element instanceof Element)) {
+                                       if (isNodeWebComponentPolyfilled(element)) {
+                                               raw = unwrapWebComponentPolyfill(element);
+                                       }
+                               }
+
+                               return raw instanceof Element;
+                       };
+
+                       /**
+                        * Appends node or array-like node list array to context
+                        * @method appendNodes
+                        * @member ns.util.DOM
+                        * @param {HTMLElement} context
+                        * @param {HTMLElement|HTMLCollection|NodeList|Array} elements
+                        * @return {HTMLElement|Array|null}
+                        * @static
+                        * @throws {string}
+                        */
+                       DOM.appendNodes = function (context, elements) {
+                               var i,
+                                       length,
+                                       arrayElements;
+
+                               if (context) {
+                                       if (elements instanceof Array || elements instanceof NodeList ||
+                                               elements instanceof HTMLCollection) {
+                                               arrayElements = slice.call(elements);
+                                               for (i = 0, length = arrayElements.length; i < length; i += 1) {
+                                                       context.appendChild(arrayElements[i]);
+                                               }
+                                       } else {
+                                               context.appendChild(elements);
+                                               arrayElements = elements;
+                                       }
+                                       return arrayElements;
+                               }
+
+                               throw "Context empty!";
+                       };
+
+                       /**
+                        * Replaces context with node or array-like node list
+                        * @method replaceWithNodes
+                        * @member ns.util.DOM
+                        * @param {HTMLElement} context
+                        * @param {HTMLElement|HTMLCollection|NodeList|Array} elements
+                        * @return {HTMLElement|Array|null}
+                        * @static
+                        */
+                       DOM.replaceWithNodes = function (context, elements) {
+                               var returnElements = null;
+
+                               if (context.parentNode) {
+                                       if (elements instanceof Array || elements instanceof NodeList ||
+                                               elements instanceof HTMLCollection) {
+                                               returnElements = this.insertNodesBefore(context, elements);
+                                               context.parentNode.removeChild(context);
+                                       } else {
+                                               context.parentNode.replaceChild(elements, context);
+                                               returnElements = elements;
+                                       }
+                               }
+                               return returnElements;
+                       };
+
+                       /**
+                        * Remove all children
+                        * @method removeAllChildren
+                        * @member ns.util.DOM
+                        * @param {HTMLElement} context
+                        * @static
+                        */
+                       DOM.removeAllChildren = function (context) {
+                               context.innerHTML = "";
+                       };
+
+                       /**
+                        * Inserts node or array-like node list before context
+                        * @method insertNodesBefore
+                        * @member ns.util.DOM
+                        * @param {HTMLElement} context
+                        * @param {HTMLElement|HTMLCollection|NodeList|Array} elements
+                        * @return {HTMLElement|Array|null}
+                        * @static
+                        * @throws {string}
+                        */
+                       DOM.insertNodesBefore = function (context, elements) {
+                               var i,
+                                       length,
+                                       parent,
+                                       returnElements;
+
+                               if (context) {
+                                       parent = context.parentNode;
+                                       if (elements instanceof Array || elements instanceof NodeList ||
+                                               elements instanceof HTMLCollection) {
+                                               returnElements = slice.call(elements);
+                                               for (i = 0, length = returnElements.length; i < length; ++i) {
+                                                       parent.insertBefore(returnElements[i], context);
+                                               }
+                                       } else {
+                                               parent.insertBefore(elements, context);
+                                               returnElements = elements;
+                                       }
+                                       return returnElements;
+                               }
+
+                               throw "Context empty!";
+
+                       };
+
+                       /**
+                        * Inserts node after context
+                        * @method insertNodeAfter
+                        * @member ns.util.DOM
+                        * @param {HTMLElement} context
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @static
+                        * @throws {string}
+                        */
+                       DOM.insertNodeAfter = function (context, element) {
+                               if (context) {
+                                       context.parentNode.insertBefore(element, context.nextSibling);
+                                       return element;
+                               }
+                               throw "Context empty!";
+                       };
+
+                       /**
+                        * Remove all children of node.
+                        * @param {Node} fragment
+                        */
+                       function cleanFragment(fragment) {
+                               // clean up
+                               while (fragment.firstChild) {
+                                       fragment.removeChild(fragment.firstChild);
+                               }
+                       }
+
+                       /**
+                        * Move nodes from one node to another.
+                        * @param {Node} fromNode
+                        * @param {Node} toNode
+                        */
+                       function moveChildren(fromNode, toNode) {
+                               // move the nodes
+                               while (fromNode.firstChild) {
+                                       toNode.appendChild(fromNode.firstChild);
+                               }
+                       }
+
+                       /**
+                        * Prepare container for filling template
+                        * @param {Node} fragment
+                        * @param {string} html
+                        * @return {{container: *, contentFlag: boolean}}
+                        */
+                       function prepareContainer(fragment, html) {
+                               var container = document.createElement("div"),
+                                       contentFlag = false;
+
+                               fragment.appendChild(container);
+
+                               container.innerHTML = html.replace(contentRegex, function () {
+                                       contentFlag = true;
+                                       return "<span id='temp-container-" + (++containerCounter) + "'></span>";
+                               });
+
+                               return {
+                                       container: container,
+                                       contentFlag: contentFlag
+                               };
+                       }
+
+                       /**
+                        * Wraps element or array-like node list in html markup
+                        * @method wrapInHTML
+                        * @param {HTMLElement|NodeList|HTMLCollection|Array} elements
+                        * @param {string} html
+                        * @return {HTMLElement|NodeList|Array} wrapped element
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       DOM.wrapInHTML = function (elements, html) {
+                               var fragment = document.createDocumentFragment(),
+                                       fragment2 = document.createDocumentFragment(),
+                                       elementsLen = elements.length,
+                                       //if elements is nodeList, retrieve parentNode of first node
+                                       originalParentNode = elementsLen ? elements[0].parentNode : elements.parentNode,
+                                       next = elementsLen ? elements[elementsLen - 1].nextSibling : elements.nextSibling,
+                                       innerContainer,
+                                       resultElements,
+                                       containerData;
+
+                               containerData = prepareContainer(fragment, html);
+
+                               if (containerData.contentFlag === true) {
+                                       innerContainer = containerData.container.querySelector("span#temp-container-" +
+                                               containerCounter);
+                                       resultElements = this.replaceWithNodes(innerContainer, elements);
+                               } else {
+                                       innerContainer = containerData.container.children[0];
+                                       resultElements = this.appendNodes(innerContainer || containerData.container, elements);
+                               }
+
+                               moveChildren(fragment.firstChild, fragment2);
+                               cleanFragment(fragment);
+
+                               if (originalParentNode) {
+                                       originalParentNode.insertBefore(fragment2, next);
+                               } else {
+                                       cleanFragment(fragment2);
+                               }
+
+                               return resultElements;
+                       };
+
+                       /**
+                        * Check if element is child of element
+                        * @method isChildElementOf
+                        * @param {HTMLElement|null} child
+                        * @param {HTMLElement|null} parent
+                        * @return {boolean}
+                        * @member ns.util.DOM
+                        * @static
+                        */
+                       DOM.isChildElementOf = function (child, parent) {
+                               if (parent) {
+                                       while (child && child.parentElement) {
+                                               if (parent === child.parentElement) {
+                                                       return true;
+                                               }
+                                               child = child.parentElement
+                                       }
+                               }
+                               return false;
+                       };
+
+                       }(window, window.document, ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * # OnOff Switch
+ * OnOff switch component is a common UI element used for binary on/off or true/false data input.
+ *
+ * The OnOff switch widget shows a 2-state switch on the screen.
+ * If defined with select type with options it creates toggles
+ * On the toggle its possible to tap one side of the switch.
+ *
+ * We still support toggles defined with select tag for backward compatibility
+ *
+ * ## Default selectors
+ * INPUT tags with _data-role=on-off-switch_ or SELECT tags
+ * with _data-role=on-off-switch_
+ * changed to on-off switch
+ * To add a on-off switch widget to the application, use the following code:
+ *
+ *        @example
+ *        <input type="checkbox" data-role="on-off-switch">
+ *
+ *        @example
+ *        <input type="checkbox" class="ui-on-off-switch">
+ *
+ *        @example
+ *        <select name="flip-11" id="flip-11" data-role="on-off-switch">
+ *            <option value="off"></option>
+ *            <option value="on"></option>
+ *        </select>
+ *
+ *        @example
+ *        <select name="flip-11" id="flip-11" class="ui-on-off-switch">
+ *            <option value="off">off option</option>
+ *            <option value="on">on option</option>
+ *        </select>
+ *
+ * ## Manual constructor
+ * For manual creation of on-off switch widget you can use constructor of
+ * widget from **tau** namespace:
+ *
+ *        @example
+ *        <select id="toggle" name="flip-11" id="flip-11" data-role="on-off-switch"
+ *        data-mini="true">
+ *            <option value="off"></option>
+ *            <option value="on"></option>
+ *        </select>
+ *        <script>
+ *            var element = document.getElementById("toggle"),
+ *                onOffSwitch = tau.widget.OnOffSwitch(element);
+ *        </script>
+ *
+ * ## JavaScript API
+ *
+ * OnOffSwitch widget hasn't JavaScript API.
+ *
+ * @since 1.2
+ * @class ns.widget.core.OnOffSwitch
+ * @component-selector .ui-on-off-switch, [data-role]="on-off-switch, .ui-toggleswitch, [data-role]="toggleswitch"
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var OnOffSwitch = function () {
+                                       var self = this;
+
+                                       /**
+                                        * Options for widget
+                                        * @property {Object} options
+                                        * @property {"circle"|"slider"} [options.appearance="circle"] On-Off-Switch display appearance
+                                        * @member ns.widget.core.OnOffSwitch
+                                        */
+                                       self.options = {
+                                               appearance: "slider"
+                                       };
+                                       self._ui = {};
+                                       self._callbacks = {};
+                                       self._transform = {
+                                               bgColor: {from: {r: 0, g: 0, b: 0, a: 0}, to: {r: 3, g: 129, b: 254, a: 1}},
+                                               borderColor: {from: {r: 143, g: 143, b: 143, a: 1}, to: {r: 0, g: 0, b: 0, a: 0}}
+                                       };
+                               },
+                               BaseWidget = ns.widget.BaseWidget,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               engine = ns.engine,
+                               stringUtils = ns.util.string,
+                               events = ns.event,
+                               widgetClass = "ui-on-off-switch",
+
+                               classes = {
+                                       /**
+                                        * Set container for toggle switch widget
+                                        * @member ns.widget.core.OnOffSwitch
+                                        */
+                                       toggleContainer: widgetClass + "-container",
+                                       /**
+                                        * Standard toggle switch widget
+                                        * @member ns.widget.core.OnOffSwitch
+                                        */
+                                       toggle: widgetClass,
+                                       /**
+                                        * Set handler for toggle switch widget
+                                        * @member ns.widget.core.OnOffSwitch
+                                        */
+                                       toggleHandler: widgetClass + "-button",
+                                       /**
+                                        * Set class for input type checkbox
+                                        * @member ns.widget.core.OnOffSwitch
+                                        */
+                                       toggleInput: widgetClass + "-input",
+                                       /**
+                                        * Set class for handler during drag
+                                        * @member ns.widget.core.OnOffSwitch
+                                        */
+                                       onDrag: widgetClass + "-button-on-drag",
+                                       moveToOff: widgetClass + "-button-move-to-off",
+                                       moveToOn: widgetClass + "-button-move-to-on",
+                                       /**
+                                        * Set class for focused state (keyboard support)
+                                        * @member ns.widget.core.OnOffSwitch
+                                        */
+                                       toggleContainerFocus: widgetClass + "-focus"
+                               },
+                               keyCode = {
+                                       HOME: 36,
+                                       END: 35,
+                                       PAGE_UP: 33,
+                                       PAGE_DOWN: 34,
+                                       UP: 38,
+                                       RIGHT: 39,
+                                       DOWN: 40,
+                                       LEFT: 37,
+                                       ENTER: 13,
+                                       SPACE: 32
+                               },
+                               widgetSelector = "";
+
+                       OnOffSwitch.prototype = new BaseWidget();
+
+                       /**
+                        * Dictionary for OnOffSwitch related css class names
+                        * @property {Object} classes
+                        * @member ns.widget.core.OnOffSwitch
+                        * @static
+                        * @readonly
+                        */
+                       OnOffSwitch.classes = classes;
+
+                       /**
+                        * Dictionary for keyboard codes
+                        * @property {Object} keyCode
+                        * @member ns.widget.core.OnOffSwitch
+                        * @static
+                        * @readonly
+                        */
+                       OnOffSwitch.keyCode = keyCode;
+
+
+                       /**
+                        * Callback change the value of input type=checkbox
+                        * (method strictly for toggleswitch based oninput tag)
+                        * @method onChangeValue
+                        * @param {ns.widget.core.OnOffSwitch} self
+                        * @private
+                        * @static
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       function onChangeValue(self) {
+                               var element = self.element;
+
+                               element.selectedIndex = (self._ui.input.checked) ? 1 : 0;
+
+                               if (self._type === "select") {
+                                       events.trigger(element, "change");
+                               }
+                       }
+
+                       /**
+                        * Simplify creating dom elements
+                        * (method strictly for toggleswitch based oninput tag)
+                        * @method createElement
+                        * @param {string} name
+                        * @return {HTMLElement}
+                        * @private
+                        * @static
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       function createElement(name) {
+                               return document.createElement(name);
+                       }
+
+                       /**
+                        * Creates and set up input element
+                        * @method setUpInput
+                        * @return {HTMLElement}
+                        * @private
+                        * @static
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       function setUpInput() {
+                               var inputElement = createElement("input");
+
+                               inputElement.type = "checkbox";
+                               inputElement.setAttribute("data-role", "none");
+                               return inputElement;
+                       }
+
+                       /**
+                        * Build Toggle based on Select Tag
+                        * @method buildToggleBasedOnSelectTag
+                        * @param {HTMLElement} element
+                        * @param {HTMLElement} divHandler
+                        * @param {HTMLElement} toggleContainer
+                        * @private
+                        * @static
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       function buildToggleBasedOnSelectTag(element, divHandler, toggleContainer) {
+                               var inputElement;
+
+                               element.style.display = "none";
+                               element.parentNode.insertBefore(toggleContainer, element);
+                               inputElement = setUpInput();
+
+                               if (element.hasAttribute("disabled")) {
+                                       inputElement.setAttribute("disabled", "disabled");
+                               }
+
+                               inputElement.className = classes.toggleInput;
+                               toggleContainer.className = stringUtils.removeExactTags(
+                                       element.className,
+                                       classes.toggleContainer,
+                                       inputElement.className
+                               );
+
+                               toggleContainer.className = classes.toggleContainer;
+
+                               toggleContainer.appendChild(inputElement);
+                               toggleContainer.appendChild(divHandler);
+                               toggleContainer.appendChild(element);
+
+                       }
+
+                       /**
+                        * Build Toggle based on Input Tag
+                        * @method buildToggleBasedOnInputTag
+                        * @param {HTMLElement} element
+                        * @param {HTMLElement} divHandler
+                        * @param {HTMLElement} toggleContainer
+                        * @private
+                        * @static
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       function buildToggleBasedOnInputTag(element, divHandler, toggleContainer) {
+                               toggleContainer.className = classes.toggleContainer;
+
+                               element.classList.add(classes.toggleInput);
+                               divHandler.classList.add(classes.toggleHandler);
+
+                               element.parentNode.insertBefore(toggleContainer, element);
+                               toggleContainer.appendChild(element);
+                               toggleContainer.appendChild(divHandler);
+                       }
+
+                       /**
+                        * Build OnOffSwitch
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       OnOffSwitch.prototype._build = function (element) {
+                               var divHandler = createElement("div"),
+                                       toggleContainer = createElement("div"),
+                                       controlType = element.nodeName.toLowerCase();
+
+                               if (controlType === "input") {
+                                       buildToggleBasedOnInputTag(element, divHandler, toggleContainer);
+                               }
+                               if (controlType === "select") {
+                                       buildToggleBasedOnSelectTag(element, divHandler, toggleContainer);
+                               }
+
+                               divHandler.className = classes.toggleHandler;
+
+                               this._type = controlType;
+                               this._ui.handler = divHandler;
+                               this._ui.toggleContainer = toggleContainer;
+
+                               return element;
+                       };
+
+                       /**
+                        * Initiate widget
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.OnOffSwitch
+                        * @instance
+                        */
+                       OnOffSwitch.prototype._init = function (element) {
+                               var self = this;
+
+                               self._ui.input = element.parentElement.querySelector("input");
+                               if (self._type === "select") {
+                                       self._ui.input.checked = !!element.selectedIndex;
+                                       if (element.hasAttribute("disabled")) {
+                                               self._disable();
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Common method to set disabled state of Switch
+                        * @method _disable
+                        * @member ns.widget.core.OnOffSwitch
+                        * @instance
+                        * @since 1.2
+                        */
+                       OnOffSwitch.prototype._disable = function () {
+                               this._ui.input.setAttribute("disabled", "true");
+                       };
+
+                       /**
+                        * Common method to set enabled state of Switch
+                        * @method _enable
+                        * @member ns.widget.core.OnOffSwitch
+                        * @instance
+                        * @since 1.2
+                        */
+                       OnOffSwitch.prototype._enable = function () {
+                               this._ui.input.removeAttribute("disabled");
+                       };
+
+                       /**
+                        * Get value of toggle switch. If widget is based on input type
+                        * tag otherwise it return index of the element
+                        * @method _getValue
+                        * @protected
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       OnOffSwitch.prototype._getValue = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               if (["checkbox", "radio"].indexOf(element.type) > -1) {
+                                       return element.checked;
+                               }
+                               return element.selectedIndex;
+                       };
+
+                       /**
+                        * Set value of toggle switch
+                        * @method _setValue
+                        * @param {string} value
+                        * @protected
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       OnOffSwitch.prototype._setValue = function (value) {
+                               var self = this,
+                                       element = self.element;
+
+                               if (self._type === "input") {
+                                       element.value = value;
+                               }
+
+                               if (["checkbox", "radio"].indexOf(element.type) > -1) {
+                                       element.checked = !!value;
+                               }
+
+                               if (self._type === "select") {
+                                       element.selectedIndex = value;
+                                       self._ui.input.checked = !!value;
+                               }
+                       };
+
+                       OnOffSwitch.prototype._onDragStart = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       checkbox = ui.input,
+                                       handler = ui.handler,
+                                       checkboxRect,
+                                       handlerRect,
+                                       checkboxStyle;
+
+                               if (!self.element.disabled) {
+                                       checkboxRect = checkbox.getBoundingClientRect();
+                                       handlerRect = handler.getBoundingClientRect();
+                                       checkboxStyle = window.getComputedStyle(checkbox);
+                                       self._moveWidth = checkboxRect.width - handlerRect.width +
+                                       parseInt(checkboxStyle.borderLeftWidth, 10) +
+                                       parseInt(checkboxStyle.borderRightWidth, 10);
+
+                                       handler.classList.add(classes.onDrag);
+                               }
+                       }
+
+                       OnOffSwitch.prototype._onDragEnd = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       checkbox = ui.input,
+                                       handler = ui.handler,
+                                       moveWidth = self._moveWidth,
+                                       initialPos = checkbox.checked ? moveWidth : 0,
+                                       currentPos,
+                                       checkedByPosition;
+
+                               if (!self.element.disabled) {
+                                       currentPos = initialPos + event.detail.deltaX;
+                                       currentPos = Math.min(Math.max(currentPos, 0), moveWidth);
+
+                                       handler.classList.remove(classes.onDrag);
+
+                                       checkedByPosition = currentPos > (moveWidth / 2);
+
+                                       // add animation
+                                       if (checkedByPosition) {
+                                               handler.classList.add(classes.moveToOn);
+                                       } else {
+                                               handler.classList.add(classes.moveToOff);
+                                       }
+                                       // remove temporary styles from drag
+                                       ui.input.style.backgroundColor = null;
+                                       ui.input.style.borderColor = null;
+                                       ui.input.style.borderWidth = null;
+
+                                       if (checkedByPosition !== checkbox.checked) {
+                                               // toggle on-off switch
+                                               self._setValue(checkedByPosition ? 1 : 0);
+
+                                               // trigger change event
+                                               onChangeValue(self);
+                                       }
+                               }
+                       }
+
+                       function calculateColor(data, progress) {
+                               var from = data.from,
+                                       to = data.to;
+
+                               return [
+                                       progress * Math.abs(to.r - from.r),
+                                       progress * Math.abs(to.g - from.g),
+                                       progress * Math.abs(to.b - from.b),
+                                       progress * Math.abs(to.a - from.a)
+                               ];
+                       }
+
+                       OnOffSwitch.prototype._onDrag = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       moveWidth = self._moveWidth,
+                                       initialPos = ui.input.checked ? moveWidth : 0,
+                                       currentPos,
+                                       progress;
+
+                               if (!self.element.disabled) {
+                                       currentPos = initialPos + event.detail.deltaX;
+                                       currentPos = Math.min(Math.max(currentPos, 0), moveWidth);
+
+                                       ui.handler.style.transform = "translateX(" + currentPos + "px)";
+
+                                       progress = moveWidth ? currentPos / moveWidth : 1;
+                                       ui.input.style.backgroundColor = "rgba(" +
+                                               calculateColor(self._transform.bgColor, progress).join(",") +
+                                               ")";
+                                       ui.input.style.borderColor = "rgba(" +
+                                               calculateColor(self._transform.borderColor, 1 - progress).join(",") +
+                                               ")";
+                                       ui.input.style.borderWidth = (1 - progress) + "px";
+                               }
+                       };
+
+                       OnOffSwitch.prototype._onAnimationEnd = function (event) {
+                               var targetClassList = event.target.classList;
+
+                               targetClassList.remove(classes.moveToOff);
+                               targetClassList.remove(classes.moveToOn);
+                               this._ui.handler.style.transform = null;
+                       };
+
+                       OnOffSwitch.prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "change":
+                                               onChangeValue(self);
+                                               break;
+                                       case "focus":
+                                               self._focus(event);
+                                               break;
+                                       case "blur":
+                                               self._blur(event);
+                                               break;
+                                       case "keyup":
+                                               self._keyUp(event);
+                                               break;
+                                       case "drag":
+                                               self._onDrag(event);
+                                               break;
+                                       case "dragstart":
+                                               self._onDragStart(event);
+                                               break;
+                                       case "dragend":
+                                               self._onDragEnd(event);
+                                               break;
+                                       case "animationend":
+                                       case "animationEnd":
+                                       case "webkitAnimationEnd":
+                                               self._onAnimationEnd(event);
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * Binds events to widget
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.core.OnOffSwitch
+                        * @instance
+                        */
+                       OnOffSwitch.prototype._bindEvents = function () {
+                               var self = this,
+                                       input = self._ui.input;
+
+                               ns.event.enableGesture(input,
+                                       new ns.event.gesture.Drag({
+                                               threshold: 0
+                                       }));
+
+                               input.addEventListener("change", self, true);
+                               input.addEventListener("focus", self, true);
+                               input.addEventListener("blur", self, true);
+                               input.addEventListener("keyup", self, true);
+                               input.addEventListener("dragstart", self, true);
+                               input.addEventListener("drag", self, true);
+                               input.addEventListener("dragend", self, true);
+                               events.on(self._ui.handler, "animationend animationEnd webkitAnimationEnd", self, false);
+                       };
+
+                       /**
+                        * Unbinds events from widget
+                        * @method _unbindEvents
+                        * @protected
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       OnOffSwitch.prototype._unbindEvents = function () {
+                               var self = this,
+                                       input = self._ui.input;
+
+                               input.removeEventListener("change", self, true);
+                               input.removeEventListener("focus", self, true);
+                               input.removeEventListener("blur", self, true);
+                               input.removeEventListener("keyup", self, true);
+                               input.removeEventListener("drag", self, true);
+                               input.removeEventListener("dragstart", self, true);
+                               input.removeEventListener("dragend", self, true);
+                               events.off(self._ui.handler, "animationend animationEnd webkitAnimationEnd", self, false);
+
+                               ns.event.disableGesture(input);
+                       };
+
+                       /**
+                        * remove attributes when destroyed
+                        * @method removeAttributesWhenDestroy
+                        * @param {HTMLElement} element
+                        * @private
+                        * @static
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       function removeAttributesWhenDestroy(element) {
+                               element.removeAttribute("data-tau-name");
+                               element.removeAttribute("aria-disabled");
+                               element.removeAttribute("data-tau-bound");
+                               element.removeAttribute("data-tau-built");
+                       }
+
+                       /**
+                        * Destroy widget
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.core.OnOffSwitch
+                        */
+                       OnOffSwitch.prototype._destroy = function () {
+                               var self = this,
+                                       element = self.element,
+                                       tagName = self._type,
+                                       container = element.parentElement;
+
+                               self._ui.input.removeEventListener("change",
+                                       self._onChangeValue, true);
+
+                               removeAttributesWhenDestroy(element);
+
+                               //remove visible representative
+                               if (tagName === "input" || tagName === "select") {
+                                       if (container.parentElement) {
+                                               container.parentElement.insertBefore(element, container);
+                                               container.parentElement.removeChild(container);
+                                       }
+                               }
+
+                               if (tagName === "input") {
+                                       element.classList.remove(classes.toggle);
+                               }
+
+                               events.trigger(document, "destroyed", {
+                                       widget: "OnOffSwitch",
+                                       parent: element.parentNode
+                               });
+                       };
+
+                       OnOffSwitch.prototype._focus = function () {
+                               var elementClassList;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       elementClassList = this.element.parentElement.classList;
+                                       elementClassList.add(classes.toggleContainerFocus);
+                                       this.element.focus();
+                               }
+                       };
+
+                       OnOffSwitch.prototype._blur = function () {
+                               var elementClassList;
+
+                               if (ns.getConfig("keyboardSupport", false)) {
+                                       elementClassList = this.element.parentElement.classList;
+                                       elementClassList.remove(classes.toggleContainerFocus);
+                                       this.element.blur();
+                               }
+                       };
+
+                       OnOffSwitch.prototype._keyUp = function (event) {
+                               if (event.keyCode === keyCode.ENTER) {
+                                       this._ui.input.checked = !this._ui.input.checked;
+                               }
+                       };
+
+                       OnOffSwitch.prototype._getContainer = function () {
+                               return this._ui.toggleContainer;
+                       }
+
+                       widgetSelector = "input[data-role='on-off-switch']," +
+                               "select[data-role='on-off-switch']," +
+                               "select.ui-on-off-switch," +
+                               "input.ui-on-off-switch";
+
+                       OnOffSwitch.widgetSelector = widgetSelector;
+
+                       ns.widget.core.OnOffSwitch = OnOffSwitch;
+                       engine.defineWidget(
+                               "OnOffSwitch",
+                               widgetSelector,
+                               [],
+                               OnOffSwitch,
+                               "core"
+                       );
+
+                       BaseKeyboardSupport.registerActiveSelector(widgetSelector);
+
+                       }(window.document, ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * # Master OnOff Switch
+ * Master OnOff switch component is a common UI element used for binary on/off data input.
+ * In difference to standard switch the master controls all switches in depended listview.
+ * If Master On/Off switch is "Off", the lower items are switched to disabled state.
+ * If Master On/Off switch is "On", the lower items are switched to enabled state.
+ *
+ * The Master OnOff switch widget shows a 2-state switch on the screen.
+ * On the toggle its possible to tap one side of the switch.
+ *
+ * ## Default selectors
+ * HTML element with class ui-master-on-off-switch" will changed to master on-off switch
+ * To add a Master on-off switch widget to the application, use the following code:
+ *
+ *        @example
+ *        <div class="ui-master-on-off-switch" data-target="list-1"></div>
+ *
+ * ## JavaScript API
+ *
+ * MasterOnOffSwitch widget hasn't JavaScript API.
+ *
+ * @since 1.2
+ * @class ns.widget.core.MasterOnOffSwitch
+ * @component-selector .ui-master-on-off-switch
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var MasterOnOffSwitch = function () {
+                                       var self = this;
+
+                                       /**
+                                        * Options for widget
+                                        * @property {Object} options
+                                        * @member ns.widget.core.MasterOnOffSwitch
+                                        */
+                                       self.options = {
+                                               target: null
+                                       },
+                                       self._ui = {};
+                                       self._onChangeMasterOnOff = null;
+                               },
+                               BaseWidget = ns.widget.BaseWidget,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               engine = ns.engine,
+                               widgetClass = "ui-master-on-off-switch",
+
+                               classes = {
+                                       /**
+                                        * Standard toggle switch widget
+                                        * @member ns.widget.core.MasterOnOffSwitch
+                                        */
+                                       WIDGET: widgetClass
+                               },
+                               keyCode = {
+                                       ENTER: 13,
+                                       SPACE: 32
+                               },
+                               widgetSelector = ".ui-master-on-off-switch",
+                               prototype = new BaseWidget();
+
+                       MasterOnOffSwitch.prototype = prototype;
+
+                       /**
+                        * Dictionary for MasterOnOffSwitch related css class names
+                        * @property {Object} classes
+                        * @member ns.widget.core.MasterOnOffSwitch
+                        * @static
+                        * @readonly
+                        */
+                       MasterOnOffSwitch.classes = classes;
+
+                       /**
+                        * Dictionary for keyboard codes
+                        * @property {Object} keyCode
+                        * @member ns.widget.core.MasterOnOffSwitch
+                        * @static
+                        * @readonly
+                        */
+                       MasterOnOffSwitch.keyCode = keyCode;
+
+                       /**
+                        * Build OnOffSwitch
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.core.MasterOnOffSwitch
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       label = document.createElement("label"),
+                                       labelText = document.createElement("span"),
+                                       onOff = document.createElement("input");
+
+                               onOff.classList.add("ui-on-off-switch");
+                               onOff.type = "checkbox";
+                               label.classList.add("ui-on-off-label");
+
+                               labelText.innerHTML = "Off";
+                               label.appendChild(labelText);
+                               label.appendChild(onOff);
+
+                               element.appendChild(label);
+                               element.classList.add(classes.WIDGET);
+
+                               self._ui.onOff = onOff;
+                               self._ui.labelOnOff = label;
+                               self._ui.labelTextOnOff = labelText;
+
+                               // create instance of widget
+                               ns.widget.OnOffSwitch(onOff);
+
+                               return element;
+                       };
+
+                       /**
+                        * Initiate widget
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.core.MasterOnOffSwitch
+                        * @instance
+                        */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self._ui.input = element.querySelector("input.ui-on-off-switch");
+                               // set initial look
+                               onChangeMasterOnOff(self);
+                       };
+
+                       function onChangeMasterOnOff(self) {
+                               var onOff = self._ui.onOff,
+                                       label = self._ui.labelOnOff,
+                                       labelText = self._ui.labelTextOnOff;
+
+                               if (onOff.checked) {
+                                       label.classList.add("ui-on-off-label-on");
+                                       labelText.innerHTML = "On";
+                               } else {
+                                       label.classList.remove("ui-on-off-label-on");
+                                       labelText.innerHTML = "Off";
+                               }
+                               self._disableAllOnOff(!onOff.checked);
+                       }
+
+                       function onTouchStart(self) {
+                               self._ui.labelOnOff.classList.add("ui-on-off-label-active");
+                       }
+
+                       function onTouchEnd(self) {
+                               self._ui.labelOnOff.classList.remove("ui-on-off-label-active");
+                       }
+
+                       /**
+                        * Binds events to widget
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.core.MasterOnOffSwitch
+                        * @instance
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       onOff = self._ui.onOff,
+                                       labelOnOff = self._ui.labelOnOff,
+                                       _onChangeMasterOnOff = onChangeMasterOnOff.bind(null, self),
+                                       _onTouchStart = onTouchStart.bind(null, self),
+                                       _onTouchEnd = onTouchEnd.bind(null, self);
+
+
+                               onOff.addEventListener("change", _onChangeMasterOnOff);
+                               labelOnOff.addEventListener("vmousedown", _onTouchStart);
+                               labelOnOff.addEventListener("vmouseup", _onTouchEnd);
+
+                               self._onChangeMasterOnOff = _onChangeMasterOnOff;
+                       };
+
+                       prototype._unbindEvents = function () {
+                               var self = this,
+                                       onOff = self._ui.onOff;
+
+                               onOff.removeEventListener("change", self._onChangeMasterOnOff);
+                               onOff.removeEventListener("vmousedown", self._onTouchStart);
+                               onOff.removeEventListener("vmouseup", self._onTouchEnd);
+
+                               self._onChangeMasterOnOff = null;
+                               self._onTouchStart = null;
+                               self._onTouchEnd = null;
+                       };
+
+                       /**
+                        * Disables / enables on/off switches on list
+                        * @method _disableAllOnOff
+                        * @param {boolean} disabled
+                        * @member ns.widget.core.MasterOnOffSwitch
+                        * @protected
+                        */
+                       prototype._disableAllOnOff = function (disabled) {
+                               var targetElement = document.getElementById(this.options.target),
+                                       allOnOff = [],
+                                       ui = this._ui,
+                                       onOffSwitch = null;
+
+                               if (targetElement) {
+                                       allOnOff = [].slice.call(targetElement.querySelectorAll(".ui-on-off-switch")),
+                                       allOnOff.filter(function (item) {
+                                               return item !== ui.onOff;
+                                       }).forEach(function (onOff) {
+                                               onOffSwitch = ns.widget.OnOffSwitch(onOff);
+                                               if (disabled) {
+                                                       onOffSwitch.disable();
+                                               } else {
+                                                       onOffSwitch.enable();
+                                               }
+                                       });
+                               } else {
+                                       ns.warn("MasterOnOffSwitch: indicated target element (" + this.options.target + ") not found");
+                               }
+                       };
+
+                       /**
+                        * Destroy widget
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.core.MasterOnOffSwitch
+                        */
+                       prototype._destroy = function () {
+                               this._unbindEvents();
+                       };
+
+                       prototype._keyUp = function (event) {
+                               if (event.keyCode === keyCode.ENTER) {
+                                       this._ui.onOff.checked = !this._ui.onOff.checked;
+                               }
+                       };
+
+                       MasterOnOffSwitch.widgetSelector = widgetSelector;
+
+                       ns.widget.core.MasterOnOffSwitch = MasterOnOffSwitch;
+                       engine.defineWidget(
+                               "MasterOnOffSwitch",
+                               widgetSelector,
+                               [],
+                               MasterOnOffSwitch,
+                               "core"
+                       );
+
+                       BaseKeyboardSupport.registerActiveSelector(widgetSelector);
+
+                       }(window.document, ns));
+
+/*global window, define, ns, HTMLTextAreaElement, HTMLInputElement */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Text Input
+ * TextInput component is decorator for input elements.
+ *
+ * ## Default selectors
+ * In default elements matches to :
+ *
+ *  - INPUT with type "text" or "number" or "password" or "email" or "url" or "tel" or "month" or "week" or "datetime-local" or "color" or without any
+ *    type
+ *  - TEXTAREA
+ *  - HTML elements with class _ui-text-input_
+ *
+ * ###HTML Examples
+ *
+ * ####Create simple text input on INPUT element
+ *
+ *             @example
+ *             <form>
+ *                     <label for="text-1">Text input:</label>
+ *                     <input type="text" name="text-1" id="text-1" value="">
+ *                     <input type="text" name="text-1" id="text-1" value="">
+ *             </form>
+ *
+ * ####Create simple text input on TEXTAREA element
+ *
+ *             @example
+ *             <form>
+ *                     <label for="text-1">Text input:</label>
+ *                     <textarea name="text-1" id="text-1"></textarea>
+ *             </form>
+ *
+ * ####Create simple text input on INPUT element with class ui-text-input
+ *
+ *             @example
+ *             <form>
+ *                     <label for="text-1">Text input:</label>
+ *                     <input name="text-1" id="text-1" class="ui-text-input">
+ *             </form>
+ *
+ * ## Manual constructor
+ * For manual creation of TextInput widget you can use constructor of widget
+ * from **tau** namespace:
+ *
+ *             @example
+ *             <form>
+ *                     <label for="text-1">Text input:</label>
+ *                     <input type="search" name="text-1" id="text-1" value="">
+ *             </form>
+ *             <script>
+ *                     var inputElement = document.getElementById("text-1"),
+ *                             textInput = tau.widget.TextInput(inputElement);
+ *             </script>
+ *
+ * ##Options for widget
+ *
+ * Options for widget can be defined as _data-..._ attributes or give as
+ * parameter in constructor.
+ *
+ * You can change option for widget using method **option**.
+ *
+ * ##Methods
+ *
+ * To call method on widget you can use one of existing API:
+ *
+ * First API is from tau namespace:
+ *
+ *             @example
+ *             <input id="text-1" />
+ *             <script>
+ *                     var inputElement = document.getElementById('text-1'),
+ *                             textInput = tau.widget.TextInput(inputElement);
+ *                     // textInput.methodName(argument1, argument2, ...);
+ *                     // for example:
+ *                     textInput.value("text");
+ *             </script>
+ *
+ * @since 2.0
+ * @class ns.widget.mobile.TextInput
+ * @component-selector .ui-text-input
+ * @extends ns.widget.BaseWidget
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Piotr Kusztal <p.kusztal@samsung.com>
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Hyunkook Cho <hk0713.cho@samsung.com>
+ * @author Junhyeon Lee <juneh.lee@samsung.com>
+ * @author Heeju Joo <heeju.joo@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               engine = ns.engine,
+                               util = ns.util,
+                               domUtils = util.DOM,
+                               utilSelector = util.selectors,
+                               objectUtils = util.object,
+                               utilEvent = ns.event,
+
+                               TextInput = function () {
+                                       var self = this;
+
+                                       self.options = objectUtils.merge({}, TextInput.defaults);
+                                       self._ui = {
+                                               textLineElement: null,
+                                               textClearButtonElement: null,
+                                               errorMessageElement: null
+                                       };
+                                       self._callbacks = {};
+
+                                       BaseKeyboardSupport.call(self);
+                               },
+                               buttonClasses = ns.widget.core.Button.classes,
+
+                               listviewClasses = ns.widget.core.Listview.classes,
+                               popupClasses = ns.widget.core.Popup.classes,
+
+                               prototype = new BaseWidget(),
+
+                               CLASSES_PREFIX = "ui-text-input",
+
+                               /**
+                                * Dictionary for TextInput related css class names
+                                * @property {Object} classes
+                                * @member ns.widget.mobile.TextInput
+                                * @static
+                                */
+                               classes = {
+                                       /**
+                                        * Standard text input widget
+                                        * @style ui-text-input
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       uiTextInput: CLASSES_PREFIX,
+                                       /**
+                                        * Create text input widget with clear button
+                                        * @style ui-text-input-clear
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       uiTextInputClear: CLASSES_PREFIX + "-clear",
+                                       /**
+                                        * Hide clear button in text input widget
+                                        * @style ui-text-input-clear-hidden
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       uiTextInputClearHidden: CLASSES_PREFIX + "-clear-hidden",
+                                       /**
+                                        * Set clear button to active in text input widget
+                                        * @style ui-text-input-clear-active
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       uiTextInputClearActive: CLASSES_PREFIX + "-clear-active",
+                                       /**
+                                        * Set text line to text input widget
+                                        * @style ui-text-input-textline
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       uiTextInputTextLine: CLASSES_PREFIX + "-textline",
+                                       /**
+                                        * Set error message to text input widget.
+                                        * Will be visible once input is invalid according to input type.
+                                        * @style ui-text-input-error-message
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       uiTextInputErrorMessage: CLASSES_PREFIX + "-error-message",
+                                       /**
+                                        * Set text input as disabled in text input widget
+                                        * @style ui-text-input-disabled
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       uiTextInputDisabled: CLASSES_PREFIX + "-disabled",
+                                       /**
+                                        * Set text input as focus in text input widget
+                                        * @style ui-text-input-focused
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       uiTextInputFocused: CLASSES_PREFIX + "-focused",
+                                       HEADER_WITH_SEARCH: "ui-header-searchbar",
+                                       /**
+                                        * Set search-input widget in text input widget
+                                        * @style ui-search-input
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       SEARCHINPUT: "ui-search-input",
+                                       HEADER: "ui-header",
+                                       /**
+                                        * Set container for text input widget
+                                        * @style ui-text-input-container
+                                        * @member ns.widget.mobile.TextInput
+                                        */
+                                       CONTAINER: CLASSES_PREFIX + "-container",
+                                       WIDGET_FOCUSED: CLASSES_PREFIX + "-widget-focused"
+                               },
+                               /**
+                                * Selector for clear button appended to TextInput
+                                * @property {string} CLEAR_BUTTON_SELECTOR
+                                * @member ns.widget.mobile.TextInput
+                                * @static
+                                * @private
+                                * @readonly
+                                */
+                               selector = {
+                                       uiTextInput: "." + classes.uiTextInput,
+                                       uiTextInputClearButton: "." + classes.uiTextInputClear,
+                                       uiTextInputTextLine: "." + classes.uiTextInputTextLine
+                               },
+                               /**
+                                * Object with default options
+                                * @property {Object} options
+                                * @property {boolean} [options.clearBtn=false] option indicates that the clear button will be shown
+                                * @property {boolean} [options.textLine=true] option indicates that the text underline will be shown
+                                * @property {boolean} [options.maxHeight=null] set max height for textarea
+                                * @property {boolean} [options.outsideDiv=false] created outsider div as container of input elements
+                                * @property {string} [options.errorMessageString="Custom string"] set message string when input value is invalid
+                                * @member ns.widget.mobile.TextInput
+                                */
+                               defaults = {
+                                       clearBtn: false,
+                                       textLine: true,
+                                       maxHeight: null,
+                                       outsideDiv: false,
+                                       errorMessageString: "Enter a valid email address"
+                               },
+                               eventName = {
+                                       SEARCH: "search",
+                                       ANIMATIONEND: "animationend"
+                               };
+
+                       TextInput.prototype = prototype;
+                       TextInput.classes = classes;
+                       TextInput.defaults = defaults;
+
+                       /**
+                        * Resize textarea, called after text input
+                        * @method _resizeTextArea
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @member ns.widget.mobile.TextInput
+                        */
+                       prototype._resizeTextArea = function (element) {
+                               var listviewElement,
+                                       listviewWidget,
+                                       popupElement = util.selectors.getClosestByClass(element, popupClasses.popup),
+                                       popupWidget,
+                                       maxHeight = parseInt(this.options.maxHeight, 10),
+                                       newHeight,
+                                       style = element.style,
+                                       previousHeight = style.height;
+
+                               style.height = "auto"; // reset for the browser to recalculate scrollHeight
+                               newHeight = element.scrollHeight; // apply scrollHeight as new height
+
+                               element.scrollTop = newHeight;
+                               if (maxHeight && newHeight > maxHeight) {
+                                       newHeight = maxHeight;
+                               }
+                               style.height = newHeight + "px";
+
+                               if ((previousHeight !== (newHeight + "px")) && popupElement && previousHeight !== "") {
+                                       popupWidget = engine.getBinding(popupElement);
+                                       popupWidget.refresh();
+                               }
+                               listviewElement = util.selectors.getClosestByClass(element, listviewClasses.LISTVIEW);
+                               if (listviewElement) {
+                                       listviewWidget = engine.getBinding(listviewElement);
+                                       if (listviewWidget) {
+                                               listviewWidget.refresh();
+                                       }
+                               }
+                       };
+                       /**
+                        * Toggle visibility of the clear button
+                        * @method _toggleClearButton
+                        * @param {HTMLElement} clearBtn
+                        * @param {HTMLInputElement} inputElement
+                        * @static
+                        * @protected
+                        */
+                       prototype._toggleClearButton = function (clearBtn, inputElement) {
+                               if (clearBtn) {
+                                       if (!inputElement.classList.contains(classes.uiTextInputFocused)) {
+                                               if (!clearBtn.classList.contains("ui-btn-active")) {
+                                                       clearBtn.classList.add(classes.uiTextInputClearHidden);
+                                               }
+                                       } else {
+                                               clearBtn.classList.remove(classes.uiTextInputClearHidden);
+                                               inputElement.classList.add(classes.uiTextInputClearActive);
+                                       }
+                               }
+                       };
+                       /**
+                        * Method clears text in input field and sets focus
+                        * @method _onClearBtnClick
+                        * @param {ns.widget.core.Button} self
+                        * @static
+                        * @protected
+                        * @member ns.widget.mobile.TextInput
+                        */
+                       prototype._onClearBtnClick = function (self) {
+                               self.element.focus();
+                               self.element.value = "";
+                               self.trigger(eventName.SEARCH);
+                       };
+                       /**
+                        * Method hides button after its animation ends
+                        * @method _onClearBtnAnimationEnd
+                        * @param {ns.widget.core.Button} self
+                        * @param {Event} event
+                        * @static
+                        * @protected
+                        * @member ns.widget.mobile.TextInput
+                        */
+                       prototype._onClearBtnAnimationEnd = function (self, event) {
+                               if (event.animationName === "btn_pressup_animation" && self.element.value === "") {
+                                       event.target.classList.add(classes.uiTextInputClearHidden);
+                               }
+                       };
+
+                       /**
+                        * Method adds class ui-text-input-focused to target element of event.
+                        * @method _onFocus
+                        * @param {ns.widget.mobile.TextInput} self
+                        * @protected
+                        * @static
+                        * @member ns.widget.mobile.TextInput
+                        */
+                       prototype._onFocus = function (self) {
+                               var element = self.element,
+                                       currentValueLength = element.value.length;
+
+                               element.classList.add(classes.uiTextInputFocused);
+                               if (element.value !== "" && self._ui.textClearButtonElement) {
+                                       self._ui.textClearButtonElement.classList.remove(classes.uiTextInputClearHidden);
+                               }
+
+                               // setting caret position at the end
+                               element.selectionStart = currentValueLength;
+                               element.selectionEnd = currentValueLength;
+                       };
+
+                       /**
+                        * Method adds event for showing clear button and optional resizing textarea.
+                        * @method _onInput
+                        * @param {ns.widget.mobile.TextInput} self
+                        * @protected
+                        * @static
+                        * @member ns.widget.mobile.TextInput
+                        */
+                       prototype._onInput = function (self) {
+                               var element = self.element,
+                                       btn = self._ui.textClearButtonElement;
+
+                               if (element.value === "" && btn) {
+                                       btn.classList.add(classes.uiTextInputClearHidden);
+                                       element.classList.remove(classes.uiTextInputClearActive);
+                               } else {
+                                       self._toggleClearButton(self._ui.textClearButtonElement, element);
+                               }
+
+                               if (element.nodeName.toLowerCase() === "textarea") {
+                                       self._resizeTextArea(element);
+                               }
+                       };
+                       /**
+                        * Method removes class ui-text-input-focused from target element of event.
+                        * @method _onBlur
+                        * @param {ns.widget.mobile.TextInput} self
+                        * @private
+                        * @static
+                        * @member ns.widget.mobile.TextInput
+                        */
+                       prototype._onBlur = function (self) {
+                               var element = self.element;
+
+                               element.classList.remove(classes.uiTextInputFocused);
+                               self._toggleClearButton(self._ui.textClearButtonElement, element);
+                       };
+
+                       function setAria(element) {
+                               element.setAttribute("role", "textinput");
+                               element.setAttribute("aria-label", "Keyboard opened");
+                       }
+
+                       function createSpanAfter(element, classStyle, content) {
+                               var span = document.createElement("span");
+
+                               if (classStyle) {
+                                       span.classList.add(classStyle);
+                               }
+                               if (content) {
+                                       span.innerHTML = content;
+                               }
+
+                               domUtils.insertNodeAfter(element, span);
+                               return span;
+                       }
+
+                       prototype._createClearButton = function (element, header) {
+                               var clearButton = document.createElement("a");
+
+                               clearButton.classList.add(buttonClasses.BTN);
+                               clearButton.classList.add(buttonClasses.BTN_ICON);
+                               clearButton.classList.add(buttonClasses.BTN_NOBG);
+                               clearButton.classList.add(classes.uiTextInputClear);
+                               clearButton.classList.add(classes.uiTextInputClearHidden);
+
+                               clearButton.tabindex = 0;
+                               if (header) {
+                                       element.parentNode.appendChild(clearButton);
+                               } else {
+                                       element.parentNode.insertBefore(clearButton, element.nextSibling.nextSibling);
+                               }
+
+                               return clearButton;
+                       };
+
+                       /**
+                       * build TextInput Widget
+                       * @method _build
+                       * @param {HTMLElement} element
+                       * @member ns.widget.mobile.TextInput
+                       * @return {HTMLElement}
+                       * @protected
+                       */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       options = self.options,
+                                       type = element.type,
+                                       pattern = element.pattern,
+                                       ui = self._ui,
+                                       header;
+
+
+                               self._setOutsideDiv(element, options.outsideDiv);
+
+                               /* set Aria and TextLine */
+                               switch (type) {
+                                       case "text":
+                                       case "password":
+                                       case "number":
+                                       case "email":
+                                       case "url":
+                                       case "tel":
+                                       case "search":
+                                               setAria(element);
+                                               ui.textLineElement = createSpanAfter(element, classes.uiTextInputTextLine);
+                                               break;
+                                       default:
+                                               if (element.tagName.toLowerCase() === "textarea") {
+                                                       setAria(element);
+                                                       if (options.textLine) {
+                                                               ui.textLineElement = createSpanAfter(element, classes.uiTextInputTextLine);
+                                                       }
+                                               }
+                               }
+
+                               element.classList.add(classes.uiTextInput);
+                               element.tabindex = 0;
+
+                               if (options.clearBtn) {
+                                       ui.textClearButtonElement = self._createClearButton(element);
+                               }
+
+                               if (type === "search") {
+                                       header = utilSelector.getClosestByClass(element, classes.HEADER);
+                                       element.classList.add(classes.SEARCHINPUT);
+
+                                       if (header) {
+                                               header.classList.add(classes.HEADER_WITH_SEARCH);
+                                               if (element.nextElementSibling.classList.contains(classes.uiTextInputTextLine)) {
+                                                       element.parentElement.removeChild(element.nextElementSibling);
+                                               }
+                                       }
+
+                                       if (!options.clearBtn) {
+                                               ui.textClearButtonElement = self._createClearButton(element, header);
+                                       }
+
+                                       if (!element.getAttribute("placeholder")) {
+                                               element.setAttribute("placeholder", "Search");
+                                       }
+                               }
+
+                               if (type === "email" || pattern) {
+                                       ui.errorMessageElement = createSpanAfter(ui.textLineElement, classes.uiTextInputErrorMessage, options.errorMessageString);
+                               }
+
+                               return element;
+                       };
+
+                       prototype._setOutsideDiv = function (element, newDiv) {
+                               var container = document.createElement("div"),
+                                       ui = this._ui;
+
+                               if (newDiv) {
+                                       container.className = classes.CONTAINER;
+                                       element.parentElement.replaceChild(container, element);
+                                       container.classList.add(CLASSES_PREFIX + "-type-" + element.type);
+                                       container.appendChild(element);
+                                       ui.container = container;
+                               }
+
+                               this.options.outsideDiv = newDiv;
+                       };
+
+                       /**
+                       * Init TextInput Widget
+                       * @method _init
+                       * @param {HTMLElement} element
+                       * @member ns.widget.mobile.TextInput
+                       * @return {HTMLElement}
+                       * @protected
+                       */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       type = element.type,
+                                       parentNode = element.parentNode;
+
+                               if (options.clearBtn) {
+                                       ui.textClearButtonElement = ui.textClearButtonElement || parentNode.querySelector(selector.uiTextInputClearButton);
+                               }
+                               if (options.textLine) {
+                                       switch (type) {
+                                               case "text":
+                                               case "password":
+                                               case "number":
+                                               case "email":
+                                               case "url":
+                                               case "tel":
+                                                       ui.textLineElement = ui.textLineElement || parentNode.querySelector(selector.uiTextInputTextLine);
+                                                       break;
+                                               default:
+                                                       if (element.nodeName.toLowerCase() === "textarea") {
+                                                               ui.textLineElement = ui.textLineElement || parentNode.querySelector(selector.uiTextInputTextLine);
+                                                       }
+                                       }
+                               }
+
+                               if (element.nodeName.toLowerCase() === "textarea") {
+                                       if (element.hasAttribute("rows") === false) {
+                                               element.rows = 1;
+                                       }
+                                       self._resizeTextArea(element);
+                               }
+
+                               return element;
+                       };
+
+
+                       /**
+                       * Bind events to widget
+                       * @method _bindEvents
+                       * @protected
+                       * @member ns.widget.mobile.TextInput
+                       */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       element = self.element,
+                                       clearBtn = self._ui.textClearButtonElement,
+                                       onInputCallback = self._onInput.bind(null, self),
+                                       onFocusCallback = self._onFocus.bind(null, self),
+                                       onBlurCallback = self._onBlur.bind(null, self),
+                                       onClearBtnClickCallback = self._onClearBtnClick.bind(null, self),
+                                       onClearBtnAnimationEndCallback = self._onClearBtnAnimationEnd.bind(null, self);
+
+                               self._callbacks = {
+                                       onInputCallback: onInputCallback,
+                                       onFocusCallback: onFocusCallback,
+                                       onBlurCallback: onBlurCallback,
+                                       onClearBtnClickCallback: onClearBtnClickCallback,
+                                       onClearBtnAnimationEndCallback: onClearBtnAnimationEndCallback
+                               };
+
+                               utilEvent.on(element, "input", onInputCallback);
+                               utilEvent.on(element, "focus", onFocusCallback);
+                               utilEvent.on(element, "blur", onBlurCallback);
+                               if (clearBtn) {
+                                       utilEvent.on(clearBtn, "click", onClearBtnClickCallback);
+                                       utilEvent.on(clearBtn, eventName.ANIMATIONEND, onClearBtnAnimationEndCallback);
+                               }
+
+                       };
+                       /**
+                        * unbind events to widget
+                        * @method _unbindEvents
+                        * @protected
+                        * @member ns.widget.mobile.TextInput
+                        */
+                       prototype._unbindEvents = function () {
+                               var self = this,
+                                       element = self.element,
+                                       clearBtn = self._ui.textClearButtonElement,
+                                       callbacks = self._callbacks;
+
+                               utilEvent.off(element, "input", callbacks.onInputCallback);
+                               utilEvent.off(element, "focus", callbacks.onFocusCallback);
+                               utilEvent.off(element, "blur", callbacks.onBlurCallback);
+                               if (clearBtn) {
+                                       utilEvent.off(clearBtn, "click", callbacks.onClearBtnClickCallback);
+                                       utilEvent.off(clearBtn, eventName.ANIMATIONEND, callbacks.onClearBtnAnimationEndCallback);
+                               }
+                       };
+
+                       /**
+                        * Enables the TextInput
+                        *
+                        * Method removes disabled attribute on input and changes look of
+                        * input to enabled state.
+                        *
+                        *      @example
+                        *      <input id="input" />
+                        *      <script>
+                        *              var inputElement = document.getElementById("input"),
+                        *                      textInputWidget = tau.widget.TextInput();
+                        *
+                        *              textInputWidget.enable();
+                        *      </script>
+                        *
+                        * @method enable
+                        * @chainable
+                        * @member ns.widget.mobile.TextInput
+                        */
+
+                       /**
+                        * Method enables TextInput.
+                        * @method _enable
+                        * @member ns.widget.mobile.TextInput
+                        * @protected
+                        */
+                       prototype._enable = function () {
+                               var element = this.element;
+
+                               if (element) {
+                                       element.removeAttribute("disabled");
+                                       element.classList.remove(classes.uiTextInputDisabled);
+                               }
+                       };
+
+                       /**
+                        * Disables the TextInput
+                        *
+                        * Method adds disabled attribute on input and changes look of
+                        * input to disable state.
+                        *
+                        *      @example
+                        *      <input id="input" />
+                        *      <script>
+                        *              var inputElement = document.getElementById("input"),
+                        *                      textInputWidget = tau.widget.TextInput();
+                        *
+                        *              textInputWidget.disable();
+                        *      </script>
+                        *
+                        *
+                        * @method disable
+                        * @chainable
+                        * @member ns.widget.mobile.TextInput
+                        */
+
+                       /**
+                        * Method disables TextInput
+                        * @method _disable
+                        * @member ns.widget.mobile.TextInput
+                        * @protected
+                        */
+                       prototype._disable = function () {
+                               var element = this.element;
+
+                               if (element) {
+                                       element.setAttribute("disabled", "disabled");
+                                       element.classList.add(classes.uiTextInputDisabled);
+                               }
+                       };
+
+                       /**
+                        * Get element value
+                        * @method _getValue
+                        * @return {?string}
+                        * @member ns.widget.mobile.TextInput
+                        * @protected
+                        * @since 2.3.1
+                        */
+                       prototype._getValue = function () {
+                               var element = this.element;
+
+                               if (element) {
+                                       return element.value;
+                               }
+                               return null;
+                       };
+
+                       /**
+                        * Set element value
+                        * @method _setValue
+                        * @param {string} value
+                        * @member ns.widget.mobile.TextInput
+                        * @return {ns.widget.mobile.TextInput}
+                        * @protected
+                        * @since 2.3.1
+                        */
+                       prototype._setValue = function (value) {
+                               var element = this.element;
+
+                               if (element) {
+                                       element.value = value;
+                               }
+                               return this;
+                       };
+
+                       /**
+                        * Destroys additional elements created by the widget,
+                        * removes classes and event listeners
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.mobile.TextInput
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       textLine = ui.textLineElement,
+                                       clearButton = ui.textClearButtonElement,
+                                       errorMessage = ui.errorMessageElement;
+
+                               self._unbindEvents();
+
+                               if (textLine && textLine.parentElement) {
+                                       textLine.parentElement.removeChild(ui.textLineElement);
+                               }
+
+                               if (clearButton) {
+                                       clearButton.parentElement.removeChild(ui.textClearButtonElement);
+                               }
+
+                               if (errorMessage) {
+                                       errorMessage.parentElement.removeChild(ui.errorMessageElement);
+                               }
+                       };
+
+                       /**
+                        * Returns widget container if it has one,
+                        * otherwise returns base element
+                        * @method _getContainer
+                        * @protected
+                        * @member ns.widget.mobile.TextInput
+                        */
+                       prototype._getContainer = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       container = ui.container,
+                                       element = self.element;
+
+                               return container ? container : element;
+                       }
+
+
+                       prototype._focus = function (element) {
+                               var classList = element.classList;
+
+                               classList.add(classes.WIDGET_FOCUSED);
+                       }
+
+                       prototype._blur = function (element) {
+                               var classList = element.classList;
+
+                               classList.remove(classes.WIDGET_FOCUSED);
+                               element.blur();
+                       }
+
+                       prototype._actionEnter = function (element) {
+                               var self = this;
+
+                               self._blur(element);
+                               element.focus();
+                       }
+
+                       prototype._actionEscape = function (element) {
+                               var self = this;
+
+                               element.blur();
+                               self.focus();
+                       }
+
+                       BaseKeyboardSupport.registerActiveSelector("input[type='text']:not([data-role])" +
+                               ", input[type='number']:not([data-role])" +
+                               ", input[type='password']:not([data-role])" +
+                               ", input[type='email']:not([data-role])" +
+                               ", input[type='url']:not([data-role])" +
+                               ", input[type='tel']:not([data-role])" +
+                               ", input[type='search']:not([data-role]), .ui-search-input" +
+                               ", textarea" +
+                               ", input:not([type])." + classes.uiTextInput);
+
+                       ns.widget.mobile.TextInput = TextInput;
+                       engine.defineWidget(
+                               "TextInput",
+                               "input[type='text']:not([data-role])" +
+                                       ", input[type='number']:not([data-role])" +
+                                       ", input[type='password']:not([data-role])" +
+                                       ", input[type='email']:not([data-role])" +
+                                       ", input[type='url']:not([data-role])" +
+                                       ", input[type='tel']:not([data-role])" +
+                                       ", input[type='search']:not([data-role]), .ui-search-input" +
+                                       ", textarea" +
+                                       ", input:not([type])." + classes.uiTextInput,
+                               [],
+                               TextInput,
+                               "mobile",
+                               false,
+                               false,
+                               HTMLInputElement
+                       );
+
+                       ns.widget.mobile.TextArea = TextInput;
+                       engine.defineWidget(
+                               "TextArea",
+                               null,
+                               [],
+                               TextInput,
+                               "mobile",
+                               false,
+                               false,
+                               HTMLTextAreaElement
+                       );
+
+                       engine.defineWidget(
+                               "SearchInput",
+                               "",
+                               [],
+                               TextInput,
+                               "mobile"
+                       );
+                       }(window.document, ns));
+
+/*global window, ns, define, HTMLSelectElement */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Dropdown Menu
+ * Dropdown menu component is used to select one option. It is created as a drop-down list form.
+ *
+ * ##Default selector
+ * In default all select elements are changed to Tizen WebUI DropdownMenu.
+ * Additionally elements with _data-native-menu=false_ will use custom popups for option selection
+ *
+ * ###  HTML Examples
+ *
+ * ####  Create DropdownMenu
+ * Default value of data-native-menu attribute is true and it makes native DropdownMenu.
+ * This widget also offers the possibility of having custom DropdownMenu.
+ *
+ *        @example
+ *        <select data-native-menu="false">
+ *            <option value="1">Item1</option>
+ *            <option value="2">Item2</option>
+ *            <option value="3">Item3</option>
+ *            <option value="4">Item4</option>
+ *        </select>
+ *
+ * ## Manual constructor
+ * For manual creation of DropdownMenu widget you can use constructor of widget.
+ *
+ *        @example
+ *        <select id="dropdownmenu" data-native-menu="false">
+ *            <option value="1">Item1</option>
+ *            <option value="2">Item2</option>
+ *            <option value="3">Item3</option>
+ *            <option value="4">Item4</option>
+ *        </select>
+ *        <script>
+ *            var element = document.getElementById("dropdownmenu"),
+ *                widget = tau.widget.DropdownMenu(element);
+ *        </script>
+ *
+ *
+ * ##Inline type
+ * When data-inline attribute is set to true, width of the DropdownMenu is determined by its text.
+ * (Default is false.)
+ *
+ *            @example
+ *            <select id="dropdownmenu" data-native-menu="false" data-inline="true">
+ *                <option value="1">Item1</option>
+ *                <option value="2">Item2</option>
+ *                <option value="3">Item3</option>
+ *                <option value="4">Item4</option>
+ *            </select>
+ *
+ * ##Placeholder options
+ * If you use <option> with data-placeholder="true" attribute, you can make a default placeholder.
+ * Default value of data-hide-placeholder-menu-items attribute is true and data-placeholder option
+ * is hidden. If you don't want that, you can use data-hide-placeholder-menu-items="false"
+ * attribute.
+ *
+ *        @example
+ *        <select id="dropdownmenu" data-native-menu="false"
+ *            data-hide-placeholder-menu-items="false">
+ *            <option value="choose-one" data-placeholder="true">Choose an option</option>
+ *            <option value="1">Item1</option>
+ *            <option value="2">Item2</option>
+ *            <option value="3">Item3</option>
+ *            <option value="4">Item4</option>
+ *        </select>
+ *
+ * ##Methods
+ * To call method on widget you can use one of existing API:
+ *
+ * First API is from tau namespace: RECOMMEND
+ *
+ *        @example
+ *        var element = document.getElementById("dropdownmenu"),
+ *            widget = tau.widget.DropdownMenu(element);
+ *        widget.methodName(methodArgument1, methodArgument2, ...);
+ *
+ * Second API is jQuery Mobile API and for call _methodName_ you can use: Support for backward
+ * compatibility
+ *
+ *        @example
+ *        $(".selector").dropdownmenu("methodName", methodArgument1, methodArgument2, ...);
+ *
+ * - "open" - DropdownMenu open
+ *
+ *        @example
+ *        var elDropdownMenu = document.getElementById("dropdownmenu"),
+ *            widget = tau.widget.DropdownMenu(elDropdownMenu);
+ *        widget.open();
+ *
+ * - "close" - DropdownMenu close
+ *
+ *        @example
+ *        var elDropdownMenu = document.getElementById("dropdownmenu"),
+ *            widget = tau.widget.DropdownMenu(elDropdownMenu);
+ *        widget.close();
+ *
+ * - "refresh" - This method refreshes the DropdownMenu widget.
+ *
+ *        @example
+ *        var elDropdownMenu = document.getElementById("dropdownmenu"),
+ *            widget = tau.widget.DropdownMenu(elDropdownMenu);
+ *        widget.refresh();
+ *
+ * @since 2.4
+ * @class ns.widget.mobile.DropdownMenu
+ * @component-selector .ui-dropdownmenu
+ * @extends ns.widget.mobile.BaseWidgetMobile
+ * @author Hagun Kim <hagun.kim@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               engine = ns.engine,
+                               domUtils = ns.util.DOM,
+                               eventUtils = ns.event,
+                               selectors = ns.util.selectors,
+                               slice = [].slice,
+                               Page = ns.widget.core.Page,
+                               indexOf = [].indexOf,
+                               DropdownMenu = function () {
+                                       var self = this;
+                                       /**
+                                        * @property {boolean} _isOpen Open/Close status of DropdownMenu
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+
+                                       self._isOpen = false;
+                                       self._isClosing = false;
+                                       /**
+                                        * @property {number} _selectedIndex Index of selected option in DropdownMenu
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       self._selectedIndex = null;
+                                       /**
+                                        * @property {Object} _ui Object with html elements connected with DropdownMenu
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       self._ui = {
+                                               elSelectWrapper: null,
+                                               elPlaceHolder: null,
+                                               elSelect: null,
+                                               screenFilter: null,
+                                               elOptionContainer: null,
+                                               elOptions: null,
+                                               elPage: null,
+                                               elContent: null,
+                                               elDefaultOption: null
+                                       };
+
+                                       self._horizontalPosition = null;
+
+                                       /**
+                                        * @property {Object} options Object with default options
+                                        * @property {boolean} [options.nativeMenu=true] Sets the DropdownMenu widget as native/custom type.
+                                        * @property {boolean} [options.inline=false] Sets the DropdownMenu widget as inline/normal type.
+                                        * @property {boolean} [options.hidePlaceholderMenuItems=true] Hide/Reveal the placeholder option in dropdown list of the DropdownMenu.
+                                        * @property {string}  [options.items=''] List of <option>: 'key1:value1, key2:value2, key3:value3 .....'
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       self.options = {
+                                               nativeMenu: true,
+                                               inline: false,
+                                               hidePlaceholderMenuItems: true,
+                                               items: ""
+                                       };
+                                       /**
+                                        * @property {Function|null} _toggleMenuBound callback for select action
+                                        * @protected
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       self._toggleMenuBound = null;
+                                       /**
+                                        * @property {Function|null} _changeOptionBound callback for change value
+                                        * @protected
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       self._changeOptionBound = null;
+                                       /**
+                                        * @property {Function|null} _onResizeBound callback for throttledresize
+                                        * @protected
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       self._onResizeBound = null;
+                                       /**
+                                        * @property {Function|null} _nativeChangeOptionBound callback for change value
+                                        * @protected
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       self._nativeChangeOptionBound = null;
+                                       /**
+                                        * @property {Function|null} _focusBound callback for focus action
+                                        * @protected
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       self._focusBound = null;
+                                       /**
+                                        * @property {Function|null} _blurBound callback for blur action
+                                        * @protected
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       self._blurBound = null;
+                                       // event callbacks
+                                       self._callbacks = {};
+
+                                       BaseKeyboardSupport.call(self);
+                               },
+                               widgetSelector = "select:not([data-role='slider']):not([data-role='range'])" +
+                                       ":not([data-role='toggleswitch']):not(.ui-toggleswitch):not(.ui-slider)" +
+                                       ":not([data-role='on-off-switch']):not(.ui-on-off-switch)," +
+                                       "select.ui-select-menu:not([data-role='slider']):not([data-role='range'])" +
+                                       ":not([data-role='toggleswitch'])" +
+                                       ":not([data-role='on-off-switch']):not(.ui-on-off-switch)," +
+                                       ".ui-dropdownmenu",
+                               /**
+                                * Dictionary for DropdownMenu related css class names
+                                * @property {Object} classes
+                                * @member ns.widget.mobile.DropdownMenu
+                                * @static
+                                */
+                               classes = {
+                                       /**
+                                        * Standard dropdown menu widget
+                                        * @style ui-dropdownmenu
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       selectWrapper: "ui-dropdownmenu",
+                                       /**
+                                        * Set an option group in dropdown menu widget
+                                        * @style ui-dropdownmenu-optiongroup
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       optionGroup: "ui-dropdownmenu-optiongroup",
+                                       /**
+                                        * Set a placeholder in dropdown menu widget
+                                        * @style ui-dropdownmenu-placeholder
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       placeHolder: "ui-dropdownmenu-placeholder",
+                                       /**
+                                        * Set an option list in dropdown menu widget
+                                        * @style ui-dropdownmenu-options
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       optionList: "ui-dropdownmenu-options",
+                                       /**
+                                        * Set a wrapper for options in dropdown menu widget
+                                        * @style ui-dropdownmenu-options-wrapper
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       optionsWrapper: "ui-dropdownmenu-options-wrapper",
+                                       /**
+                                        * Set selected to dropdown menu widget
+                                        * @style ui-dropdownmenu-selected
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       selected: "ui-dropdownmenu-selected",
+                                       /**
+                                        * Set active to dropdown menu widget
+                                        * @style ui-dropdownmenu-active
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       active: "ui-dropdownmenu-active",
+                                       /**
+                                        * Opens options in dropdown menu widget
+                                        * @style ui-dropdownmenu-options-opening
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       opening: "ui-dropdownmenu-options-opening",
+                                       /**
+                                        * Closes options in dropdown menu widget
+                                        * @style ui-dropdownmenu-options-closing
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       closing: "ui-dropdownmenu-options-closing",
+                                       /**
+                                        * Set class for opened options in dropdown menu widget
+                                        * @style ui-dropdownmenu-options-opened
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       opened: "ui-dropdownmenu-options-opened",
+                                       /**
+                                        * Set filter structure in dropdown menu widget
+                                        * @style ui-dropdownmenu-overlay
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       filter: "ui-dropdownmenu-overlay",
+                                       /**
+                                        * Set hidden filter structure in dropdown menu widget
+                                        * @style ui-dropdownmenu-overlay-hidden
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       filterHidden: "ui-dropdownmenu-overlay-hidden",
+                                       /**
+                                        * Set disabled in dropdownmenu widget
+                                        * @style ui-dropdownmenu-disabled
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       disabled: "ui-dropdownmenu-disabled",
+                                       /**
+                                        * Set dropdown menu widget as disabled
+                                        * @style ui-disabled
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       widgetDisabled: "ui-disabled",
+                                       /**
+                                        * Set dropdown menu widget as inline
+                                        * @style ui-dropdownmenu-inline
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       inline: "ui-dropdownmenu-inline",
+                                       /**
+                                        * Set dropdown menu widget as native
+                                        * @style ui-dropdownmenu-native
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       native: "ui-dropdownmenu-native",
+                                       /**
+                                        * Set dropdown menu options to displayed on top
+                                        * @style ui-dropdownmenu-top
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       top: "ui-dropdownmenu-options-top",
+                                       /**
+                                        * Set dropdown menu options to displayed on bottom
+                                        * @style ui-dropdownmenu-bottom
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       bottom: "ui-dropdownmenu-options-bottom",
+                                       /**
+                                        * Set dropdown menu widget as focus
+                                        * @style ui-focus
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       focus: BaseKeyboardSupport.classes.focus,
+                                       /**
+                                        * Set top and bottom margins for dropdownmenu
+                                        * @style "ui-dropdownmenu-options-vertical-margins"
+                                        * @member ns.widget.mobile.DropdownMenu
+                                        */
+                                       verticalMargins: "ui-dropdownmenu-options-vertical-margins"
+                               },
+                               prototype = new BaseWidget();
+
+                       DropdownMenu.prototype = prototype;
+                       DropdownMenu.classes = classes;
+
+                       /**
+                        * vclick to toggle menu event handler
+                        * @method toggleMenu
+                        * @private
+                        * @static
+                        * @param {ns.widget.mobile.DropdownMenu} self
+                        * @param {Event} event
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function toggleMenu(self, event) {
+                               self._toggleSelect(event);
+                               eventUtils.stopPropagation(event);
+                               eventUtils.preventDefault(event);
+                       }
+
+                       /**
+                        * vclick to change option event handler
+                        * @method changeOption
+                        * @private
+                        * @static
+                        * @param {ns.widget.mobile.DropdownMenu} self
+                        * @param {Event} event
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function changeOption(self, event) {
+                               var target = event.target,
+                                       tag = target.tagName,
+                                       classList = target.classList;
+
+                               if (tag === "LI" && !classList.contains(classes.optionGroup) && !classList.contains(classes.disabled)) {
+                                       self._selectedIndex = indexOf.call(self._ui.elOptions, target);
+                                       self._changeOption();
+                                       self._toggleSelect(event);
+                               }
+                               event.stopPropagation();
+                               event.preventDefault();
+                       }
+
+                       /**
+                        * Change option in native DropdownMenu
+                        * @method nativeChangeOption
+                        * @private
+                        * @static
+                        * @param {ns.widget.mobile.DropdownMenu} self
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function nativeChangeOption(self) {
+                               var ui = self._ui,
+                                       selectedOption = ui.elSelect[ui.elSelect.selectedIndex];
+
+                               ui.elPlaceHolder.textContent = selectedOption.textContent;
+                       }
+
+                       /**
+                        * Function fires on window resizing
+                        * @method onResize
+                        * @private
+                        * @static
+                        * @param {ns.widget.mobile.DropdownMenu} self
+                        * @param {Event} event
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function onResize(self, event) {
+                               if (self._isOpen === true) {
+                                       self._isOpen = !self._isOpen;
+                                       self._toggleSelect(event);
+                                       event.stopPropagation();
+                                       event.preventDefault();
+                               }
+                       }
+
+                       /**
+                        * Function adds ui-focus class on focus
+                        * @private
+                        * @static
+                        * @param {ns.widget.mobile.DropdownMenu} self
+                        * @param {Event} event
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function onFocus(self, event) {
+                               var ui = self._ui,
+                                       target = event.target;
+
+                               if (ns.getConfig("keyboardSupport")) {
+                                       if (target === ui.elSelectWrapper ||
+                                               target.parentNode === ui.elOptionContainer) {
+                                               target.classList.add(classes.focus);
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Function stops propagation of events to appbar
+                        * @private
+                        * @static
+                        * @param {ns.widget.mobile.DropdownMenu} self
+                        * @param {Event} event
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function onTouchMove(self, event) {
+                               event.stopPropagation();
+                       }
+
+                       /**
+                        * Function removes ui-focus class on focus
+                        * @private
+                        * @static
+                        * @param {ns.widget.mobile.DropdownMenu} self
+                        * @param {Event} event
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function onBlur(self, event) {
+                               var ui = self._ui,
+                                       target = event.target;
+
+                               if (ns.getConfig("keyboardSupport")) {
+                                       if (target === ui.elSelectWrapper ||
+                                               target.parentNode === ui.elOptionContainer) {
+                                               target.classList.remove(classes.focus);
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Toggle enable/disable DropdownMenu
+                        * @method setDisabledStatus
+                        * @private
+                        * @static
+                        * @param {HTMLElement} element
+                        * @param {boolean} isDisabled
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function setDisabledStatus(element, isDisabled) {
+                               var classList = element.classList;
+
+                               if (isDisabled) {
+                                       classList.add(classes.disabled);
+                                       classList.add(classes.widgetDisabled);
+                                       classList.add(BaseWidget.classes.disable);
+                               } else {
+                                       classList.remove(classes.disabled);
+                                       classList.remove(classes.widgetDisabled);
+                                       classList.remove(BaseWidget.classes.disable);
+                               }
+                       }
+                       /**
+                        * Return data array used to fill select tag options elements
+                        * @method dataItemsToArray
+                        * @private
+                        * @static
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function dataItemsToArray(dataItems) {
+                               var items = dataItems,
+                                       it,
+                                       len = 0,
+                                       i = 0,
+                                       result = [];
+
+                               items = items.split(",");
+                               len = items.length;
+
+                               for (i = 0; i < len; i++) {
+                                       it = items[i].split(":");
+                                       result.push({
+                                               textContent: it[0],
+                                               value: it[1]
+                                       });
+                               }
+
+                               return result;
+                       }
+
+                       /**
+                        * Add options element to DropdownMenu (if element has data-item)
+                        * @method addSelectDataItems
+                        * @private
+                        * @static
+                        * @param {HTMLElement} element
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function addSelectDataItems(element, dataIt) {
+                               var dataItems = dataItemsToArray(dataIt),
+                                       len = dataItems.length,
+                                       val = 0,
+                                       i = 0;
+
+                               element.innerHTML = "";
+                               for (i = 0; i < len; i++) {
+                                       val = typeof dataItems[i].value !== "undefined" ? dataItems[i].value : (i + 1);
+                                       element.innerHTML += "<option value=\"" + val + "\">" +
+                                       dataItems[i].textContent + "</option>";
+                               }
+                       }
+
+                       /**
+                        * Convert option tag to li element
+                        * @method _convertOptionToHTML
+                        * @protected
+                        * @param {boolean} hidePlaceholderMenuItems
+                        * @param {HTMLElement} option
+                        * @param {boolean} isDisabled
+                        * @return {string}
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._convertOptionToHTML = function (hidePlaceholderMenuItems, option, isDisabled) {
+                               var className = option.className;
+
+                               if (!hidePlaceholderMenuItems || !domUtils.getNSData(option, "placeholder")) {
+                                       if (isDisabled) {
+                                               className += " " + classes.disabled;
+                                       }
+                                       return "<li data-value='" + option.value + "'" +
+                                               (className ? " class='" + className + "'" : "") +
+                                               (!isDisabled ? " tabindex='0'" : "") + ">" +
+                                               option.textContent +
+                                               "</li>";
+                               }
+                               return "";
+                       };
+
+                       /**
+                        * Return top offset of element
+                        * @method getTopOffsetOfElement
+                        * @private
+                        * @static
+                        * @param {HTMLElement} element
+                        * @param {HTMLElement} container
+                        * @return {number}
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function getTopOffsetOfElement(element, container) {
+                               var offsetTop = element.offsetTop,
+                                       offsetParent;
+
+                               while (element.offsetParent) {
+                                       offsetParent = element.offsetParent;
+                                       offsetTop += offsetParent.offsetTop;
+                                       if (element === container) {
+                                               break;
+                                       }
+                                       element = offsetParent;
+                               }
+                               return offsetTop;
+                       }
+
+                       /**
+                        * Construct element of option of DropdownMenu
+                        * @method _constructOption
+                        * @protected
+                        * @return {string}
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._constructOption = function () {
+                               var self = this,
+                                       i = 0,
+                                       j,
+                                       forElement,
+                                       tag,
+                                       resultHTML = "",
+                                       optionArray = slice.call(self._ui.elSelect.children),
+                                       optionCount = optionArray.length,
+                                       groupOptionArray,
+                                       groupOptCount,
+                                       isDisabled,
+                                       hidePlaceholderMenuItems = self.options.hidePlaceholderMenuItems;
+
+                               // This part is for optgroup tag.
+                               for (; i < optionCount; i++) {
+                                       forElement = optionArray[i];
+                                       isDisabled = forElement.disabled;
+                                       tag = forElement.tagName;
+                                       // for <option> tag
+                                       if (tag === "OPTION") {
+                                               /* When data-hide-placeholder-menu-items is true,
+                                                * <option> with data-placeholder="true" is hidden in DropdownMenu.
+                                                * It means that the <option> doesn't have to be DropdownMenu element.
+                                                */
+                                               resultHTML += self._convertOptionToHTML(hidePlaceholderMenuItems, forElement, isDisabled);
+                                       } else if (tag === "OPTGROUP") {
+                                               // for <optgroup> tag
+                                               resultHTML += "<li class='" + classes.optionGroup +
+                                                       (isDisabled ? (" " + classes.disabled + "'") : "'") + ">" + forElement.label +
+                                                       "</li>";
+                                               groupOptionArray = slice.call(forElement.children);
+                                               for (j = 0, groupOptCount = groupOptionArray.length; j < groupOptCount; j++) {
+                                                       // If <optgroup> is disabled, all child of the optgroup are also disabled.
+                                                       isDisabled = forElement.disabled || groupOptionArray[j].disabled;
+                                                       resultHTML += self._convertOptionToHTML(hidePlaceholderMenuItems, groupOptionArray[j],
+                                                               isDisabled);
+                                               }
+                                       }
+                               }
+                               return resultHTML;
+                       };
+
+                       /**
+                        * Setter for option inline
+                        * @method _setInline
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @param {boolean} value
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._setInline = function (element, value) {
+                               var ui = this._ui;
+
+                               ui.elSelectWrapper.classList.toggle(classes.inline, value);
+                               if (value) {
+                                       ui.elPlaceHolder.removeAttribute("style");
+                               }
+
+                               this.options.inline = value;
+                       };
+
+                       prototype._configure = function (element) {
+                               // check if the element is widget wrapper
+                               if (element.webkitMatchesSelector("." + classes.selectWrapper)) {
+                                       element = element.querySelector(DropdownMenu.widgetSelector);
+                                       if (element) {
+                                               return element;
+                                       }
+                               }
+                               return null;
+                       }
+
+                       prototype._getContainer = function () {
+                               return this._ui.elSelectWrapper;
+                       }
+
+                       /**
+                        * Build structure of DropdownMenu widget
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._build = function (element) {
+                               return this._generate(element, true);
+                       };
+
+                       /**
+                        * Generate Placeholder and Options elements for DropdownMenu
+                        * @method _generate
+                        * @param {HTMLElement} element
+                        * @param {boolean} create
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._generate = function (element, create) {
+                               var self = this,
+                                       options = self.options,
+                                       selectedOption,
+                                       elementId = element.id,
+                                       ui = self._ui,
+                                       pageClasses = Page.classes;
+
+                               if (self.options.items) {
+                                       addSelectDataItems(element, self.options.items);
+                               }
+
+                               ui.elSelect = element;
+                               ui.page = selectors.getParentsByClass(element, pageClasses.uiPage)[0] || document.body;
+                               ui.content = selectors.getParentsByClass(element, pageClasses.uiContent)[0] ||
+                                       selectors.getParentsByClass(element, pageClasses.uiHeader)[0];
+                               ui.elDefaultOption = element.querySelector("option[data-placeholder='true']");
+
+                               // check if selected index is after data placeholder item
+                               if (ui.elDefaultOption && element.selectedIndex > ui.elDefaultOption.index) {
+                                       self._selectedIndex = element.selectedIndex - 1;
+                               } else {
+                                       self._selectedIndex = element.selectedIndex;
+                               }
+
+                               if (create) {
+                                       selectedOption = ui.elDefaultOption || element[element.selectedIndex] || element.options.item(element.selectedIndex);
+
+                                       self._buildWrapper(element);
+                                       self._buildPlaceholder(element, ui.elSelectWrapper, elementId,
+                                               selectedOption ? selectedOption.textContent : "");
+                               }
+
+                               self._setNativeMenu(element, options.nativeMenu);
+                               self._setInline(element, options.inline);
+
+                               return element;
+                       };
+
+                       /**
+                        * Build wrapper for whole UI structure
+                        * @method _buildWrapper
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._buildWrapper = function (element) {
+                               var self = this,
+                                       selectWrapperElement = self._createWrapper();
+
+                               selectWrapperElement.className = classes.selectWrapper;
+                               selectWrapperElement.id = element.id + "-dropdownmenu";
+                               selectWrapperElement.setAttribute("tabindex", "0");
+                               selectWrapperElement.setAttribute("data-role", "none");
+
+                               domUtils.insertNodesBefore(element, selectWrapperElement);
+
+                               selectWrapperElement.appendChild(element);
+
+                               self._ui.elSelectWrapper = selectWrapperElement;
+                       };
+
+                       /**
+                        * Build placeholder HTML structure
+                        * @method _buildPlaceholder
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @param {HTMLElement} selectWrapperElement
+                        * @param {string} elementId
+                        * @param {string} text
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._buildPlaceholder = function (element, selectWrapperElement, elementId, text) {
+                               var placeholderElement = document.createElement("span");
+
+                               placeholderElement.id = elementId + "-placeholder";
+                               placeholderElement.className = classes.placeHolder;
+                               placeholderElement.textContent = text;
+
+                               selectWrapperElement.insertBefore(placeholderElement, element);
+                               this._ui.elPlaceHolder = placeholderElement;
+                       };
+
+                       /**
+                        * Build HTML for filter structure
+                        * @method _buildFilter
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @param {string} elementId
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._buildFilter = function (element, elementId) {
+                               var ui = this._ui,
+                                       screenFilterElement = ui.screenFilter,
+                                       optionWrapperElement = ui.elOptionWrapper,
+                                       optionContainerElement = ui.elOptionContainer,
+                                       fragment = document.createDocumentFragment();
+
+                               if (!screenFilterElement) {
+                                       screenFilterElement = document.createElement("div");
+                                       screenFilterElement.classList.add(classes.filter, classes.filterHidden);
+                                       screenFilterElement.id = elementId + "-overlay";
+                                       fragment.appendChild(screenFilterElement);
+                               }
+
+                               if (!optionWrapperElement) {
+                                       optionWrapperElement = document.createElement("div");
+                                       optionWrapperElement.className = classes.optionsWrapper;
+                                       optionWrapperElement.id = elementId + "-options-wrapper";
+                                       fragment.appendChild(optionWrapperElement);
+                               }
+
+                               if (!optionContainerElement) {
+                                       optionContainerElement = document.createElement("ul"),
+                                       optionContainerElement.className = classes.optionList;
+                                       optionContainerElement.id = elementId + "-options";
+                                       optionWrapperElement.appendChild(optionContainerElement);
+                               }
+                               ui.page.appendChild(fragment);
+
+                               ui.elOptionContainer = optionContainerElement;
+                               ui.elOptionWrapper = optionWrapperElement;
+                               ui.screenFilter = screenFilterElement;
+                       };
+
+                       /**
+                        * Setter for option nativeMenu
+                        * @method _setNativeMenu
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @param {boolean} value
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._setNativeMenu = function (element, value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       optionElements,
+                                       elOptionContainer,
+                                       selectWrapperElement = ui.elSelectWrapper,
+                                       optionsAsText;
+
+                               if (value) {
+                                       optionElements = element.querySelectorAll("option");
+                                       selectWrapperElement.classList.add(classes.native);
+                               } else {
+                                       self._buildFilter(element, element.id);
+                                       elOptionContainer = ui.elOptionContainer;
+                                       optionsAsText = self._constructOption();
+                                       elOptionContainer.innerHTML = optionsAsText;
+                                       optionElements = elOptionContainer.querySelectorAll("li[data-value]");
+                                       optionElements[self._selectedIndex] &&
+                                               optionElements[self._selectedIndex].classList.add(classes.selected);
+                               }
+
+                               ui.elOptions = optionElements;
+                               self.options.nativeMenu = value;
+                       };
+
+                       /**
+                        * Init of DropdownMenu widget
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       elementId = element.id;
+
+                               if (!ui.elSelectWrapper) {
+                                       ui.elSelectWrapper = document.getElementById(elementId + "-dropdownmenu");
+                                       ui.elPlaceHolder = document.getElementById(elementId + "-placeholder");
+                                       ui.elOptionWrapper = document.getElementById(elementId + "-options-wrapper");
+                                       ui.elSelect = element;
+                                       if (!self.options.nativeMenu) {
+                                               ui.screenFilter = document.getElementById(elementId + "-overlay");
+                                               ui.elOptionContainer = document.getElementById(elementId + "-options");
+                                               ui.elOptions = ui.elOptionContainer.querySelectorAll("li[data-value]");
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Refresh of DropdownMenu widget
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._refresh = function () {
+                               var self = this;
+
+                               self._generate(self.element, false);
+                       };
+
+                       /**
+                        * Enables widget
+                        * @method _enable
+                        *  @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._enable = function () {
+                               setDisabledStatus(this._ui.elSelectWrapper, false);
+                               domUtils.removeAttribute(this.element, "disabled");
+                       };
+
+                       /**
+                        * Disables widget
+                        * @method _disable
+                        *  @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._disable = function () {
+                               setDisabledStatus(this._ui.elSelectWrapper, true);
+                               domUtils.setAttribute(this.element, "disabled", true);
+                       };
+
+                       /**
+                        * Open DropdownMenu
+                        * @method open
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype.open = function () {
+                               var self = this;
+
+                               if (self._isOpen === false) {
+                                       self._toggleSelect();
+                               }
+                       };
+
+                       /**
+                        * Close DropdownMenu
+                        * @method close
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype.close = function () {
+                               var self = this;
+
+                               if (self._isOpen === true) {
+                                       self._toggleSelect();
+                               }
+                       };
+
+                       /**
+                        * Bind events of DropdownMenu widget
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       elOptionContainer = ui.elOptionContainer,
+                                       elSelectWrapper = ui.elSelectWrapper;
+
+                               self._toggleMenuBound = toggleMenu.bind(null, self);
+                               self._changeOptionBound = changeOption.bind(null, self);
+                               self._onResizeBound = onResize.bind(null, self);
+                               self._nativeChangeOptionBound = nativeChangeOption.bind(null, self);
+                               self._focusBound = onFocus.bind(null, self);
+                               self._blurBound = onBlur.bind(null, self);
+                               self._touchMoveBound = onTouchMove.bind(null, self);
+
+                               elSelectWrapper.addEventListener("focus", self._focusBound);
+                               elSelectWrapper.addEventListener("blur", self._blurBound);
+                               if (!self.options.nativeMenu) {
+                                       elSelectWrapper.addEventListener("vclick", self._toggleMenuBound);
+                                       elOptionContainer.addEventListener("touchmove", self._touchMoveBound);
+                                       elOptionContainer.addEventListener("vclick", self._changeOptionBound);
+                                       elOptionContainer.addEventListener("focusin", self._focusBound); // bubble
+                                       elOptionContainer.addEventListener("focusout", self._blurBound); // bubble
+                                       if (ui.screenFilter) {
+                                               ui.screenFilter.addEventListener("vmousedown", self._toggleMenuBound);
+                                       }
+                                       window.addEventListener("throttledresize", self._onResizeBound, true);
+                               } else {
+                                       ui.elSelect.addEventListener("change", self._nativeChangeOptionBound);
+                               }
+                       };
+
+                       /**
+                        * Coordinate Option ul element
+                        * @method _coordinateOption
+                        * @return {string}
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._coordinateOption = function () {
+                               var self = this,
+                                       offsetTop,
+                                       offsetLeft,
+                                       width,
+                                       areaInfo,
+                                       optionStyle,
+                                       ui = self._ui,
+                                       optionHeight = ui.elOptionContainer.offsetHeight,
+                                       listItemWidthOffsets = [].slice.call(ui.elOptionContainer.children).map(mapItemWidth),
+                                       optionContainerStyle = window.getComputedStyle(ui.elOptionContainer),
+                                       biggestListItemWidth = Math.max.apply(Math, listItemWidthOffsets) +
+                                               parseInt(optionContainerStyle.borderLeftWidth, 10) +
+                                               parseInt(optionContainerStyle.borderRightWidth, 10),
+                                       wrapperMinWidth = parseInt(window.getComputedStyle(ui.elOptionWrapper).minWidth, 10),
+                                       options = self.options,
+                                       scrollTop = ui.elOptionWrapper.parentNode.querySelector(".ui-scrollview-clip").scrollTop,
+                                       height,
+                                       // maxHeight,
+                                       widgetParent = ui.elSelectWrapper.parentNode,
+                                       widgetParentStyle = window.getComputedStyle(widgetParent),
+                                       widgetParentRect = widgetParent.getBoundingClientRect(),
+                                       hiddenPart = 0, // hidden part of selected list element
+                                       maxContainerWidth;
+
+                               ui.elSelectWrapper.classList.add("ui-dropdownmenu-force-display");
+                               self._offsetTop = getTopOffsetOfElement(ui.elSelectWrapper, ui.page);
+                               ui.elSelectWrapper.classList.remove("ui-dropdownmenu-force-display");
+                               areaInfo = self._chooseDirection();
+
+                               width = Math.max(biggestListItemWidth, wrapperMinWidth);
+                               height = optionHeight;
+
+                               // This part decides the location and direction of option list.
+                               offsetLeft = self._horizontalPosition === "right" ? widgetParentRect.right - width : widgetParentRect.left;
+                               // if drop down menu goes out screen eg. more menu
+                               // left position has to be corrected
+                               if (offsetLeft + width > window.screen.width) {
+                                       offsetLeft -= offsetLeft + width - window.screen.width;
+                               }
+                               optionStyle = "left: " + offsetLeft + "px; ";
+
+                               if (options.inline === true) {
+                                       height = ui.elOptionContainer.children[0].offsetHeight * 5;
+                                       maxContainerWidth = widgetParent.offsetWidth -
+                                                                               (parseFloat(widgetParentStyle.paddingLeft) + parseFloat(widgetParentStyle.paddingRight));
+                                       width = Math.min(maxContainerWidth, Math.max(width, ui.elOptionContainer.offsetWidth));
+                               }
+
+                               if (areaInfo.direction === "top") {
+                                       // check if we clicked on the element which is partially covered on the bottom of list
+                                       if (areaInfo.belowArea < 0) {
+                                               hiddenPart = areaInfo.belowArea;
+                                       }
+                                       offsetTop = self._offsetTop - height - scrollTop + ui.elPlaceHolder.offsetHeight;
+                                       ui.elOptionWrapper.classList.add(classes.top);
+                               } else {
+                                       // check if we clicked on the element which is partially covered on the top of list
+                                       if (areaInfo.topArea < ui.elPlaceHolder.offsetHeight) {
+                                               hiddenPart = scrollTop % ui.elPlaceHolder.offsetHeight;
+                                       }
+                                       offsetTop = (self._offsetTop - scrollTop) < 0 ? 0 : self._offsetTop - scrollTop;
+                                       ui.elOptionWrapper.classList.add(classes.bottom);
+                               }
+                               // take into account part of clicked list item which is partially hidden
+                               offsetTop += hiddenPart;
+
+                               // List does not require vertical paddings.
+                               if (selectors.getParentsByTag(ui.elSelect, "li").length == 0) {
+                                       ui.elOptionWrapper.classList.add(classes.verticalMargins);
+                               }
+
+                               optionStyle += "top: " + offsetTop + "px; width: " + width + "px; max-height: " + height + "px;";
+
+                               return optionStyle;
+                       };
+
+                       /**
+                        * Choose a spreading direction of option list and calculate area to display the option list
+                        * @method _chooseDirection
+                        * @return {Object}
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._chooseDirection = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       areaInfo = {
+                                               belowArea: 0,
+                                               topArea: 0,
+                                               direction: ""
+                                       };
+
+                               areaInfo.belowArea = ui.page.offsetHeight - self._offsetTop - ui.elPlaceHolder.offsetHeight + ui.content.scrollTop;
+                               areaInfo.topArea = self._offsetTop - ui.content.scrollTop;
+
+                               if ((areaInfo.belowArea < areaInfo.topArea) && (ui.elOptionContainer.offsetHeight > areaInfo.belowArea)) {
+                                       areaInfo.direction = "top";
+                               } else {
+                                       areaInfo.direction = "bottom";
+                               }
+                               return areaInfo;
+                       };
+
+                       /**
+                        * Open and Close Option List
+                        * @method _toggleSelect
+                        * @param {event} [clickEvent=null] click event
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._toggleSelect = function (clickEvent) {
+                               var self = this,
+                                       ui = self._ui,
+                                       optionContainer = ui.elOptionContainer,
+                                       optionWrapperClassList = ui.elOptionWrapper.classList;
+
+                               self._horizontalPosition = (clickEvent && clickEvent.clientX > (window.screen.width / 2)) ? "right" : "left";
+
+                               if (self._isOpen && !optionWrapperClassList.contains(classes.opening)) {
+                                       optionWrapperClassList.remove(classes.opened);
+                                       self._callbacks.hideAnimationEnd = hideAnimationEndHandler.bind(null, self);
+                                       eventUtils.prefixedFastOn(optionContainer, "animationEnd", self._callbacks.hideAnimationEnd, false);
+                                       self._hide();
+                               } else if (optionWrapperClassList.contains(classes.closing) || optionWrapperClassList.contains(classes.opening)) {
+                                       return;
+                               } else {
+                                       ui.elSelectWrapper.focus();
+                                       optionWrapperClassList.add(classes.opening);
+                                       self._callbacks.showAnimationEnd = showAnimationEndHandler.bind(null, self);
+                                       eventUtils.prefixedFastOn(optionContainer, "animationEnd", self._callbacks.showAnimationEnd, false);
+                                       self._show();
+                               }
+                               self._isOpen = !self._isOpen;
+                       };
+
+                       /**
+                        * Function animationEnd event handler when showing
+                        * @private
+                        * @static
+                        * @param {ns.widget.mobile.DropdownMenu} self
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function showAnimationEndHandler(self) {
+                               var ui = self._ui;
+
+                               ui.elOptionWrapper.classList.add(classes.opened);
+                               eventUtils.prefixedFastOff(ui.elOptionContainer, "animationEnd", self._callbacks.showAnimationEnd, false);
+                               ui.elOptionWrapper.classList.remove(classes.opening);
+                       }
+
+                       /**
+                        * Function animationEnd event handler when hiding
+                        * @private
+                        * @static
+                        * @param {ns.widget.mobile.DropdownMenu} self
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       function hideAnimationEndHandler(self) {
+                               var wrapper = self._ui.elOptionWrapper,
+                                       wrapperClassList = wrapper.classList,
+                                       optionContainer = self._ui.elOptionContainer;
+
+                               wrapperClassList.remove(classes.active);
+                               wrapper.removeAttribute("style");
+                               eventUtils.prefixedFastOff(optionContainer, "animationEnd", self._callbacks.hideAnimationEnd, false);
+                               wrapperClassList.remove(classes.closing);
+                               wrapperClassList.remove(classes.top);
+                               wrapperClassList.remove(classes.bottom);
+                       }
+
+                       /**
+                        * Returns offset width of given element
+                        * @method mapItemWidth
+                        * @private
+                        * @param {HTMLElement} li
+                        * @member ns.widget.mobile.DropdownMenu
+                        * @return {number}
+                        */
+                       function mapItemWidth(li) {
+                               return li.offsetWidth;
+                       }
+
+                       /**
+                        * Hide DropdownMenu options
+                        * @method _hide
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._hide = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       wrapper = ui.elOptionWrapper;
+
+                               if (ui.screenFilter) {
+                                       ui.screenFilter.classList.add(classes.filterHidden);
+                               }
+
+                               if (options.inline) {
+                                       ui.elSelectWrapper.style.removeProperty("width");
+                               }
+
+                               self._ui.elSelectWrapper.classList.remove(classes.active);
+                               wrapper.classList.add(classes.closing);
+
+                               if (self.isKeyboardSupport) {
+                                       self.enableDisabledFocusableElements(ui.page);
+                               }
+                       };
+
+                       /**
+                        * Show DropdownMenu options
+                        * @method _hide
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._show = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       wrapper = ui.elOptionWrapper;
+
+                               wrapper.setAttribute("style", self._coordinateOption());
+                               if (ui.screenFilter) {
+                                       ui.screenFilter.classList.remove(classes.filterHidden);
+                               }
+                               ui.elSelectWrapper.classList.add(classes.active);
+                               wrapper.classList.add(classes.active);
+
+                               if (options.inline) {
+                                       ui.elSelectWrapper.style.width = wrapper.offsetWidth + "px";
+                               }
+
+                               wrapper.setAttribute("tabindex", "0");
+                               wrapper.firstElementChild.focus();
+
+                               if (self.isKeyboardSupport) {
+                                       self.disableFocusableElements(ui.page);
+                                       self.enableDisabledFocusableElements(wrapper);
+                                       BaseKeyboardSupport.focusElement(wrapper);
+                               }
+                       };
+
+                       /**
+                        * Change Value of Select tag and Placeholder
+                        * @method changeOption
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._changeOption = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       selectedOption = ui.elOptions[self._selectedIndex],
+                                       previousOption = ui.elOptionContainer.querySelector("." + classes.selected),
+                                       getData = domUtils.getNSData;
+
+                               if ((selectedOption !== previousOption) || (ui.elDefaultOption && (ui.elPlaceHolder.textContent === ui.elDefaultOption.textContent))) {
+                                       ui.elSelect.value = getData(selectedOption, "value");
+                                       if (ui.elSelect.value === "") {
+                                               ui.elSelect.value = getData(previousOption, "value");
+                                               ui.elPlaceHolder.textContent = previousOption.textContent;
+                                               return;
+                                       }
+                                       eventUtils.trigger(ui.elSelect, "change");
+                                       if (previousOption) {
+                                               previousOption.classList.remove(classes.selected);
+                                       }
+                                       selectedOption.classList.add(classes.selected);
+                               }
+                       };
+
+                       /**
+                        * Method returns widget value
+                        * @method _getValue
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        * @return {string}
+                        */
+                       prototype._getValue = function () {
+                               var self = this,
+                                       optionsElements = self.element.options,
+                                       selected,
+                                       value = "";
+
+                               if (optionsElements) {
+                                       selected = optionsElements[self._selectedIndex];
+                                       if (selected) {
+                                               value = selected.value;
+                                       }
+                               }
+                               return value;
+                       }
+
+                       /**
+                        * Destroy DropdownMenu widget
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.mobile.DropdownMenu
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       elSelectWrapper = ui.elSelectWrapper,
+                                       elOptionContainer = ui.elOptionContainer,
+                                       screenFilter = ui.screenFilter;
+
+                               elSelectWrapper.removeEventListener("focus", self._focusBound);
+                               elSelectWrapper.removeEventListener("blur", self._blurBound);
+                               domUtils.replaceWithNodes(ui.elSelectWrapper, ui.elSelect);
+                               if (!self.options.nativeMenu) {
+                                       elSelectWrapper.removeEventListener("vclick", self._toggleMenuBound);
+                                       elOptionContainer.removeEventListener("touchmove", self._touchMoveBound);
+                                       elOptionContainer.removeEventListener("vclick", self._changeOptionBound);
+                                       elOptionContainer.removeEventListener("focusin", self._focusBound);
+                                       elOptionContainer.removeEventListener("focusout", self._blurBound);
+                                       ui.elOptionWrapper.parentNode.removeChild(ui.elOptionWrapper);
+                                       if (screenFilter) {
+                                               screenFilter.removeEventListener("vmousedown", self._toggleMenuBound);
+                                               screenFilter.parentNode.removeChild(screenFilter);
+                                       }
+                                       window.removeEventListener("throttledresize", self._onResizeBound, true);
+                               } else {
+                                       ui.elSelect.removeEventListener("change", self._nativeChangeOptionBound);
+                               }
+                       };
+
+                       DropdownMenu.widgetSelector = widgetSelector;
+
+                       ns.widget.mobile.DropdownMenu = DropdownMenu;
+
+                       BaseKeyboardSupport.registerActiveSelector(".ui-dropdownmenu:not(.ui-disabled):not(.ui-dropdownmenu-disabled), " +
+                               ".ui-dropdownmenu-options li:not(.ui-dropdownmenu-disabled):not(.ui-dropdownmenu-optiongroup):not(.ui-disabled)");
+
+                       engine.defineWidget(
+                               "DropdownMenu",
+                               widgetSelector,
+                               ["open", "close"],
+                               DropdownMenu,
+                               "mobile",
+                               false,
+                               false,
+                               HTMLSelectElement
+                       );
+
+                       }(window.document, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Text Enveloper
+ * Text enveloper component changes a text item to a button.
+ *
+ * The TextEnveloper component is that makes text to a chunk divided by delimiter.
+ * When you managed various word block, this component is very useful.
+ * This component was consisted by input area and word block area.
+ * Word block was made after insert text to input area and press enter key.
+ * If you want to delete word block, you should press the backspace key.
+ * If you focus out the input area, word block is changed to minimize.
+ *
+ * ##HTML Examples
+ * ###Create simple TextEnveloper from div using data-role:
+ *
+ *             @example
+ *                     <div data-role="textenveloper"></div>
+
+ * ###Create simple TextEnveloper from div using class:
+ *
+ *             @example
+ *                     <div class="ui-text-enveloper"></div>
+ *
+ * ##Manual constructor
+ * ###For manual creation of progressbar component you can use constructor
+ * of component:
+ *
+ *             @example
+ *                     <div id="TextEnveloper"><div>
+ *                      <script>
+ *                             var textEnveloper = tau.widget.TextEnveloper(
+ *                                     document.getElementById('TextEnveloper')
+ *                             );
+ *                     </script>
+ *
+ * If jQuery library is loaded, it's method can be used:
+ *
+ *             @example
+ *                     <div id="TextEnveloper"><div>
+ *                      <script>
+ *                             $("#TextEnveloper").TextEnveloper();
+ *                     </script>
+ *
+ * Initialize the component
+ *
+ *             @example
+ *                     <script>
+ *                             var textEnveloperElement = document.getElementById("ns-TextEnveloper"),
+ *                             TextEnveloper = tau.component.TextEnveloper(textEnveloperElement);
+ *                     </script>
+ *
+ * To call method on component you can use one of existing API:
+ *
+ * First API is from tau namespace:
+ *
+ *             @example
+ *             var textEnveloperElement = document.getElementById("ns-tokentext"),
+ *                     TextEnveloper = tau.component.TextEnveloper(textEnveloperElement);
+ *
+ *             TextEnveloper.methodName(methodArgument1, methodArgument2, ...);
+ *
+ * Second API is jQuery Mobile API and for call _methodName_ you can use:
+ *
+ *             @example
+ *             $(".selector").TextEnveloper("methodName", methodArgument1, ...);
+ *
+ * ##Events
+ *
+ * TextEnveloper trigger various events.
+ * - newvalue : 'newvalue' event is triggered when user press the ENTER key after insert text to input tag.
+ * - added: 'added' event is triggered when textEnveloper button was added.
+ * - removed: 'removed' event is triggered when textEnveloper button was removed.
+ *
+ * @since 2.4
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ * @class ns.widget.mobile.TextEnveloper
+ * @component-selector .ui-text-enveloper, [data-role]="textenveloper"
+ * @extends ns.widget.BaseWidget
+ */
+
+(function (window, ns) {
+       "use strict";
+       
+                       /**
+                        * BaseWidget alias variable
+                        * @property {Object} BaseWidget alias variable
+                        * @private
+                        * @static
+                        */
+                       var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+
+                               /**
+                                * Engine alias variable
+                                * @property {ns.engine} engine alias variable
+                                * @private
+                                * @static
+                                * @member ns.widget.mobile.TextEnveloper
+                                */
+                               engine = ns.engine,
+
+                               events = ns.event,
+                               /**
+                                * Dictionary object containing commonly used component classes
+                                * @property {Object} classes
+                                * @static
+                                * @private
+                                * @readonly
+                                * @member ns.widget.mobile.TextEnveloper
+                                */
+                               classes = {
+                                       /**
+                                        * Standard text enveloper widget
+                                        * @style ui-text-enveloper
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       TEXT_ENVELOPER: "ui-text-enveloper",
+                                       /**
+                                        * Create text enveloper widget with container
+                                        * @style ui-text-enveloper-with-container
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       WITH_CONTAINER: "ui-text-enveloper-with-container",
+                                       /**
+                                        * Set container for text enveloper widget
+                                        * @style ui-text-enveloper-container
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       CONTAINER: "ui-text-enveloper-container",
+                                       /**
+                                        * Set input for text enveloper widget
+                                        * @style ui-text-enveloper-input
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       TEXT_ENVELOPER_INPUT: "ui-text-enveloper-input",
+                                       /**
+                                        * Set button for text enveloper widget
+                                        * @style ui-text-enveloper-btn
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       TEXT_ENVELOPER_BTN: "ui-text-enveloper-btn",
+                                       /**
+                                        * Set selected to button in text enveloper widget
+                                        * @style ui-text-enveloper-btn-selected
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       BTN_SELECTED: "ui-text-enveloper-btn-selected",
+                                       /**
+                                        * Set active to button in text enveloper widget
+                                        * @style ui-text-enveloper-btn-active
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       TEXT_ENVELOPER_BTN_ACTIVE: "ui-text-enveloper-btn-active",
+                                       /**
+                                        * Set blur to button in text enveloper widget
+                                        * @style ui-text-enveloper-btn-blur
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       TEXT_ENVELOPER_BTN_BLUR: "ui-text-enveloper-btn-blur",
+                                       /**
+                                        * Set button as expanded in text enveloper widget
+                                        * @style ui-text-enveloper-btn-expanded
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       TEXT_ENVELOPER_BTN_EXPANDED: "ui-text-enveloper-btn-expanded",
+                                       /**
+                                        * Set a label to text enveloper widget
+                                        * @style ui-text-enveloper-start
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       TEXT_ENVELOPER_START: "ui-text-enveloper-start",
+                                       TEXT_ENVELOPER_TEXTLINE: "ui-text-input-textline",
+                                       /**
+                                        * Add slash to text enveloper widget
+                                        * @style ui-text-enveloper-slash
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       SLASH: "ui-text-enveloper-slash",
+                                       /**
+                                        * Hide slash in text enveloper widget
+                                        * @style ui-text-enveloper-slash-hidden
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       SLASH_HIDDEN: "ui-text-enveloper-slash-hidden",
+                                       /**
+                                        * Add slash to be a separator for button in text enveloper widget
+                                        * @style ui-text-enveloper-btn-separator
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       TEXT_ENVELOPER_BTN_SLASH: "ui-text-enveloper-btn-separator",
+                                       INPUT_STYLE_PREFIX: "ui-text-enveloper-input-",
+                                       /**
+                                        * Add blur to input in text enveloper widget
+                                        * @style ui-text-enveloper-input-blur
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+                                       INPUT_BLUR: "ui-text-enveloper-input-blur"
+                               },
+
+                               keyCode = {
+                                       BACKSPACE: 8,
+                                       ENTER: 13
+                               },
+
+                               eventName = {
+                                       NEW_VALUE: "newvalue",
+                                       ADDED: "added",
+                                       REMOVED: "removed",
+                                       SELECT: "select",
+                                       UNSELECT: "unselect",
+                                       RESIZE: "resize",
+                                       EXPAND: "expand",
+                                       FOLD: "fold"
+                               },
+                               /**
+                                * Local constructor function
+                                * @method TextEnveloper
+                                * @private
+                                * @member ns.widget.mobile.TextEnveloper
+                                */
+                               TextEnveloper = function () {
+                                       var self = this;
+                                       /**
+                                        * Object with default options
+                                        * @property {Object} options
+                                        * @property {boolean} [options.groupOnBlur=true] Group elements when blur form input
+                                        * @property {string} [options.label=null] Sets a label as a guide for the user
+                                        * @property {string} [options.link=""] Sets the ID of the page or the URL of other HTML file
+                                        * @property {string} [options.description="+ {0}"] Manages the message format
+                                        * @property {boolean} [options.selectable=false] Give possibility of select elements
+                                        * @property {boolean|string} [options.input=true] Set input or define input style
+                                        * @property {string} [options.placeholder=null] Input placeholder
+                                        * @property {string} [options.labelPosition=null] Position of label: "indent" | null
+                                        * @property {string} [options.selectedItems=null] List with indexes of selected items
+                                        * @property {string} [options.items=null] List of items
+                                        * @member ns.widget.mobile.TextEnveloper
+                                        */
+
+                                       self.options = {
+                                               groupOnBlur: true,
+                                               label: null,
+                                               link: "",
+                                               description: "+ {0}",
+                                               selectable: false,
+                                               input: true,
+                                               placeholder: null,
+                                               labelPosition: null,
+                                               selectedItems: null,
+                                               items: null
+                                       };
+                                       self._ui = {};
+                               },
+
+                               prototype = new BaseWidget();
+
+                       TextEnveloper.prototype = prototype;
+
+                       TextEnveloper.classes = classes;
+
+                       function bindEvents(self) {
+                               var inputElement = self._ui.inputElement;
+
+                               if (inputElement) {
+                                       events.on(inputElement, "keyup", self);
+                                       if (self.options.groupOnBlur) {
+                                               events.on(inputElement, "blur focus", self);
+                                       }
+                               }
+                               self.on("click", self);
+                       }
+
+                       function unbindEvents(self) {
+                               var inputElement = self._ui.inputElement;
+
+                               if (inputElement) {
+                                       events.off(inputElement, "keyup", self);
+                                       if (self.options.groupOnBlur) {
+                                               events.off(inputElement, "blur focus", self);
+                                       }
+                               }
+                               self.off("click", self);
+                       }
+
+                       /**
+                        * Build component structure
+                        * @method _build
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options;
+
+                               element.classList.add(classes.TEXT_ENVELOPER);
+
+                               self._setLabel(element, options.label);
+                               self._setLabelPosition(element, options.labelPosition);
+
+                               ui.container.classList.add(classes.CONTAINER);
+                               ui.buttons = [];
+
+                               self._setInput(element, options.input);
+                               self._setPlaceholder(element, options.placeholder);
+
+                               return element;
+                       };
+
+                       prototype._setLabelPosition = function (element, labelPosition) {
+                               var self = this,
+                                       ui = self._ui,
+                                       containerElement;
+
+                               if (labelPosition === "indent") {
+                                       containerElement = document.createElement("div");
+                                       element.appendChild(containerElement);
+                                       ui.container = containerElement;
+                                       element.classList.add(classes.WITH_CONTAINER);
+                               } else {
+                                       ui.container = element;
+                               }
+
+                               self.options.labelPosition = labelPosition;
+                       };
+
+                       prototype._setLabel = function (element, label) {
+                               var title = element.querySelector("." + classes.TEXT_ENVELOPER_START),
+                                       //if title is defined (usually its described as To, Cc, Bcc)
+                                       //then place it in the proper position
+                                       tempTitle = (title) ? title.cloneNode(true) : null;
+
+                               if (tempTitle) {
+                                       element.removeChild(title);
+                                       element.appendChild(tempTitle);
+                               }
+
+                               if (label) {
+                                       tempTitle = tempTitle || document.createElement("div");
+                                       tempTitle.innerText = label;
+                                       tempTitle.classList.add(classes.TEXT_ENVELOPER_START);
+                                       element.appendChild(tempTitle);
+                               }
+
+                               this.options.label = label;
+                       };
+
+                       /**
+                        * Init component
+                        * @method _init
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self._btnActive = false;
+                               self._isBlurred = false;
+
+                               return element;
+                       };
+
+                       /**
+                        * Bind event handler
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._bindEvents = function () {
+                               bindEvents(this);
+                       };
+
+                       /**
+                        * Bind event handler
+                        * @method handleEvent
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "click":
+                                               self._onClick(event);
+                                               break;
+                                       case "keyup":
+                                               self._onKeyup(event);
+                                               break;
+                                       case "blur":
+                                               self._onBlur(event);
+                                               break;
+                                       case "focus":
+                                               self._onFocus(event);
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * Focus event handler of input element
+                        * @method _onFocus
+                        * @protected
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._onFocus = function () {
+                               this.expandButtons();
+                       };
+
+                       /**
+                        * Method used to show Text Enveloper items
+                        * @method expandButtons
+                        * @since 3.0
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype.expandButtons = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       length,
+                                       i;
+
+                               if (self._isBlurred) {
+                                       self._isBlurred = false;
+                                       self.remove(self._btnToRemoveIndex);
+                                       ui.inputContainer.classList.remove(classes.INPUT_BLUR);
+                                       length = ui.buttons.length;
+
+                                       for (i = 0; i < length; i++) {
+                                               ui.buttons[i].classList.remove(classes.TEXT_ENVELOPER_BTN_BLUR);
+                                       }
+
+                                       self.trigger(eventName.RESIZE);
+                                       self.trigger(eventName.EXPAND);
+                               }
+                       };
+
+                       /**
+                        * Focus event handler of input element
+                        * @method _onFocus
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._onClick = function (event) {
+                               var self = this,
+                                       target = event.target,
+                                       targetClassList = target.classList,
+                                       previousElement = target.previousElementSibling,
+                                       nextElement = target.nextElementSibling,
+                                       nextButtonElement = nextElement && nextElement.nextElementSibling,
+                                       previousButtonElement = previousElement && previousElement.previousElementSibling,
+                                       previousElementClassList,
+                                       nextElementClassList,
+                                       eventNameForTrigger;
+
+                               if (!self._isBlurred) {
+                                       if (self.options.selectable && targetClassList.contains(classes.TEXT_ENVELOPER_BTN)) {
+                                               previousElementClassList = previousElement && previousElement.classList;
+                                               nextElementClassList = nextElement && nextElement.classList;
+                                               if (targetClassList.contains(classes.BTN_SELECTED)) {
+                                                       if (previousButtonElement &&
+                                                               !previousButtonElement.classList.contains(classes.BTN_SELECTED)) {
+                                                               previousElementClassList.remove(classes.SLASH_HIDDEN);
+                                                       }
+                                                       if (nextButtonElement &&
+                                                               !nextButtonElement.classList.contains(classes.BTN_SELECTED)) {
+                                                               nextElementClassList.remove(classes.SLASH_HIDDEN);
+                                                       }
+                                                       eventNameForTrigger = eventName.UNSELECT;
+                                               } else {
+                                                       if (previousElementClassList) {
+                                                               previousElementClassList.add(classes.SLASH_HIDDEN);
+                                                       }
+                                                       if (nextElementClassList) {
+                                                               nextElementClassList.add(classes.SLASH_HIDDEN);
+                                                       }
+                                                       eventNameForTrigger = eventName.SELECT;
+                                               }
+                                               targetClassList.toggle(classes.BTN_SELECTED);
+                                               self.trigger(eventNameForTrigger, {
+                                                       value: target.textContent,
+                                                       index: self._ui.buttons.indexOf(target)
+                                               }, false);
+                                               event.preventDefault();
+                                               event.stopPropagation();
+                                       }
+                               } else {
+                                       self.expandButtons();
+                                       event.preventDefault();
+                                       event.stopPropagation();
+                               }
+                       };
+
+                       prototype._getItems = function () {
+                               return this._ui.buttons.map(function (item) {
+                                       return item.textContent;
+                               });
+                       };
+
+                       prototype._setItems = function (element, value) {
+                               var self = this,
+                                       itemsArray = typeof value === "string" ? value.split(",") : value;
+
+                               if (itemsArray) {
+                                       this._ui.buttons.forEach(function () {
+                                               self.remove(0);
+                                       });
+                                       itemsArray.forEach(function (item) {
+                                               self.add(item);
+                                       });
+                               }
+                       };
+
+                       prototype._getSelectedItems = function () {
+                               var result = [];
+
+                               this._ui.buttons.forEach(function (item, index) {
+                                       if (item.classList.contains(classes.TEXT_ENVELOPER_BTN_SELECTED)) {
+                                               result.push({
+                                                       value: item.textContent,
+                                                       index: index
+                                               });
+                                       }
+                               });
+
+                               return result;
+                       };
+
+                       prototype._setSelectedItems = function (element, value) {
+                               var selectedArray = typeof value === "string" ? value.split(",") : value;
+
+                               if (selectedArray) {
+                                       this._ui.buttons.forEach(function (item, index) {
+                                               item.classList.toggle(classes.TEXT_ENVELOPER_BTN_SELECTED,
+                                                       selectedArray.indexOf(index) !== -1);
+                                       });
+                               }
+                       };
+
+                       /**
+                        * Blur event handler of input element
+                        * @method _onBlur
+                        * @protected
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._onBlur = function () {
+                               var self = this,
+                                       input = self._ui.inputElement;
+
+                               if (input && input.value) {
+                                       self.trigger(eventName.NEW_VALUE, {
+                                               value: input.value
+                                       }, false);
+
+                                       input.value = "";
+                               }
+                               self.foldButtons();
+                       };
+
+                       /**
+                        * Method used to hide Text Enveloper items
+                        * @method foldButtons
+                        * @since 3.0
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype.foldButtons = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       buttons = ui.buttons,
+                                       length = buttons.length,
+                                       firstButtonValue = buttons[0] ? buttons[0].textContent : "",
+                                       i,
+                                       button,
+                                       separatorNode,
+                                       lengthTextNode;
+
+                               if (!self._isBlurred) {
+                                       for (i = 0; i < length; i++) {
+                                               buttons[i].classList.add(classes.TEXT_ENVELOPER_BTN_BLUR);
+                                       }
+
+                                       ui.inputContainer.classList.add(classes.INPUT_BLUR);
+                                       button = self._createButton(firstButtonValue, false);
+                                       self._btnToRemoveIndex = buttons.indexOf(button);
+
+                                       if (length > 1) {
+                                               separatorNode = document.createElement("span");
+                                               separatorNode.classList.add(classes.TEXT_ENVELOPER_BTN_SLASH);
+
+                                               lengthTextNode = document.createTextNode("+" + (length - 1));
+
+                                               button.appendChild(separatorNode);
+                                               button.appendChild(lengthTextNode);
+                                       }
+
+                                       self._isBlurred = true;
+                                       self.trigger(eventName.RESIZE);
+                                       self.trigger(eventName.FOLD);
+                               }
+                       };
+
+                       /**
+                        * keyup event handler of input element
+                        * @method _onKeyup
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._onKeyup = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       input = ui.inputElement,
+                                       value = input.value,
+                                       keyValue = event.keyCode,
+                                       lastIndex = ui.buttons.length - 1;
+
+                               if (keyValue === keyCode.ENTER) {
+                                       self.trigger(eventName.NEW_VALUE, {
+                                               value: value
+                                       }, false);
+                                       input.value = "";
+                                       self.trigger(eventName.RESIZE);
+                               } else if (keyValue === keyCode.BACKSPACE) {
+                                       if (value === "") {
+                                               if (self._btnActive) {
+                                                       self.remove(lastIndex);
+                                                       self._btnActive = false;
+                                               } else {
+                                                       if (ui.buttons.length) {
+                                                               ui.buttons[lastIndex].classList.add(classes.TEXT_ENVELOPER_BTN_ACTIVE);
+                                                               self._btnActive = true;
+                                                       }
+                                               }
+                                       }
+                                       self.trigger(eventName.RESIZE);
+                               } else {
+                                       if (self._btnActive) {
+                                               ui.buttons[lastIndex].classList.remove(classes.TEXT_ENVELOPER_BTN_ACTIVE);
+                                               self._btnActive = false;
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Create button as used to word block
+                        * @method _onKeyup
+                        * @param {string} value
+                        * @param {boolean} [inline=true] set inline in button
+                        * @protected
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._createButton = function (value, inline) {
+                               var self = this,
+                                       ui = self._ui,
+                                       button = document.createElement("div"),
+                                       buttons = ui.buttons;
+
+                               if (inline === undefined) {
+                                       inline = true;
+                               }
+                               button.innerText = value;
+                               button.classList.add(classes.TEXT_ENVELOPER_BTN);
+                               engine.instanceWidget(button, "Button", {
+                                       inline: inline
+                               });
+                               ui.container.insertBefore(button, self._ui.inputContainer);
+                               buttons.push(button);
+                               self.trigger(eventName.ADDED, {
+                                       value: value,
+                                       index: buttons.length - 1
+                               }, false);
+                               return button;
+                       };
+
+                       /**
+                        * Create slash to appear after button
+                        * @method _createSlash
+                        * @protected
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._createSlash = function () {
+                               var ui = this._ui,
+                                       span = document.createElement("span");
+
+                               span.classList.add(classes.SLASH);
+                               ui.container.insertBefore(span, ui.inputContainer);
+                               return span;
+                       };
+
+                       /**
+                        * Method add block
+                        *
+                        * Method adds new token text component button with specified text
+                        * in place of the index. If index isn't set the token will
+                        * be inserted at the end.
+                        *
+                        *              @example
+                        *                      <div data-role="TextEnveloper" id="ns-tokentext"></div>
+                        *                      <script>
+                        *                              var tokenComponent = tau.component.TextEnveloper(
+                        *                                              document.getElementById("ns-tokentext")
+                        *                              );
+                        *                              tokenComponent.add("foobar");
+                        *
+                        *                              //or
+                        *
+                        *                              $( "#ns-tokentext" ).TextEnveloper("add", "foobar");
+                        *                      </script>
+                        *
+                        * @method add
+                        * @param {string} itemText
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype.add = function (itemText) {
+                               var self = this,
+                                       items = self._getItems(self.element);
+
+                               if (items.indexOf(itemText) === -1) {
+                                       self._createButton(itemText);
+                                       self._createSlash();
+                               }
+                       };
+
+                       /**
+                        * Method delete token; delete all tokens without parameter
+                        *
+                        * The remove method is used to remove a token text area component
+                        * button at the specified index position. If the parameter
+                        * is not defined, all the component buttons are removed.
+                        *
+                        *              @example
+                        *                      <div    data-role="TextEnveloper"
+                        *                                      data-label="Send to: "
+                        *                                      id="ns-tokentext">
+                        *                      </div>
+                        *                      <script>
+                        *                              var tokenComponent = tau.component.TextEnveloper(
+                        *                                              document.getElementById("ns-tokentext")
+                        *                              );
+                        *                              tokenComponent.remove(1);
+                        *
+                        *                              //or
+                        *
+                        *                              $( "#ns-tokentext" ).TextEnveloper("remove", "1" );
+                        *                      </script>
+                        *
+                        * @method remove
+                        * @param {number} index
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype.remove = function (index) {
+                               var self = this,
+                                       ui = self._ui,
+                                       buttons = ui.buttons,
+                                       length = buttons.length,
+                                       innerText = buttons[index].innerText,
+                                       container = ui.container,
+                                       validLength = self._isBlurred ? length - 2 : length - 1;
+
+                               if (index < 0 || index > validLength) {
+                                       ns.warn("You insert incorrect index, please check your index value");
+                               } else {
+                                       if (self._isBlurred) {
+                                               if (length > 2) {
+                                                       buttons[length - 1].textContent = buttons[0].textContent + " + " + (length - 2);
+                                               } else if (length === 2) {
+                                                       container.removeChild(buttons[length - 1]);
+                                                       buttons.pop();
+                                                       buttons[0].classList.remove(classes.TEXT_ENVELOPER_BTN_BLUR);
+                                               }
+                                       } else {
+                                               if (buttons[index].nextElementSibling.classList.contains(classes.SLASH)) {
+                                                       container.removeChild(buttons[index].nextElementSibling);
+                                               }
+                                               container.removeChild(buttons[index]);
+                                               buttons.splice(index, 1);
+                                       }
+                               }
+
+                               self.trigger(eventName.REMOVED, {
+                                       value: innerText,
+                                       index: index
+                               });
+                       };
+                       /**
+                        * Function return blocks count
+                        *
+                        * The length method is used to retrieve the number of buttons
+                        * in the token text area component:
+                        *
+                        *              @example
+                        *                      <div data-role="TextEnveloper" id="ns-tokentext"></div>
+                        *                      <script>
+                        *                              var tokenComponent = tau.component.TextEnveloper(
+                        *                                              document.getElementById("ns-tokentext")
+                        *                              );
+                        *                              tokenComponent.length();
+                        *
+                        *                              //if jQuery is loaded
+                        *
+                        *                              $( "#ns-tokentext" ).TextEnveloper( "length" );
+                        *                      </script>
+                        *
+                        * @method length
+                        * @return {number}
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype.length = function () {
+                               return this._ui.buttons.length;
+                       };
+
+                       prototype._setInput = function (element, addInput) {
+                               var self = this,
+                                       ui = self._ui,
+                                       input,
+                                       textLineElement,
+                                       inputContainer,
+                                       container = ui.container;
+
+                               if (addInput) {
+                                       inputContainer = document.createElement("div");
+                                       input = document.createElement("input");
+                                       input.classList.add(classes.TEXT_ENVELOPER_INPUT);
+
+                                       inputContainer.appendChild(input);
+                                       container.appendChild(inputContainer);
+
+                                       engine.instanceWidget(input, "TextInput", {
+                                               clearBtn: true
+                                       });
+                                       ui.inputElement = input;
+                                       ui.inputContainer = inputContainer;
+
+                                       if (typeof addInput === "string") {
+                                               inputContainer.classList.add(classes.INPUT_STYLE_PREFIX + addInput);
+                                       } else {
+                                               textLineElement = element.querySelector("." + classes.TEXT_ENVELOPER_TEXTLINE);
+                                               textLineElement.parentElement.removeChild(textLineElement);
+                                       }
+                               } else {
+                                       inputContainer = ui.inputContainer;
+                                       if (inputContainer) {
+                                               container.removeChild(inputContainer);
+
+                                               engine.destroyWidget(ui.inputElement, "TextInput");
+
+                                               ui.inputContainer = null;
+                                               ui.inputElement = null;
+                                       }
+                               }
+
+                               self.options.input = addInput;
+                       };
+
+                       prototype._setPlaceholder = function (element, placeholder) {
+                               var input = this._ui.inputElement;
+
+                               if (input) {
+                                       input.setAttribute("placeholder", placeholder || "");
+                               }
+
+                               this.options.placeholder = placeholder;
+                       };
+
+
+                       /**
+                        * Destroy component
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.mobile.TextEnveloper
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       ui = self._ui;
+
+                               ui.container.classList.remove(classes.CONTAINER);
+                               self._setInput(self.element, false);
+                               unbindEvents(self);
+                               self._ui = null;
+                       };
+
+                       prototype.getInput = function () {
+                               return this._ui.inputElement;
+                       };
+
+                       ns.widget.mobile.TextEnveloper = TextEnveloper;
+                       engine.defineWidget(
+                               "TextEnveloper",
+                               "[data-role='textenveloper'], .ui-text-enveloper",
+                               [
+                                       "add",
+                                       "remove",
+                                       "length"
+                               ],
+                               TextEnveloper,
+                               "mobile"
+                       );
+
+                       }(window.document, ns));
+
+/*global window, ns, define*/
+/*jslint bitwise: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @class ns.support
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function (window, document) {
+       "use strict";
+                               var isTizen = !(typeof window.tizen === "undefined");
+
+                       function isCircleShape() {
+                               var testDivElement = document.createElement("div"),
+                                       fakeBodyElement = document.createElement("body"),
+                                       htmlElement = document.getElementsByTagName("html")[0],
+                                       style = getComputedStyle(testDivElement),
+                                       isCircle;
+
+                               testDivElement.classList.add("is-circle-test");
+                               fakeBodyElement.appendChild(testDivElement);
+                               htmlElement.insertBefore(fakeBodyElement, htmlElement.firstChild);
+                               isCircle = style.width === "1px";
+                               htmlElement.removeChild(fakeBodyElement);
+
+                               // to support circle in  browser by additional parameter in url
+                               /* istanbul ignore if */
+                               if (window.location.search === "?circle") {
+                                       /* istanbul ignore next: we can't test this part because set location is not supported in
+                                        test environment */
+                                       isCircle = true;
+                               }
+
+                               return isCircle;
+                       }
+
+                       ns.support = {
+                               cssTransitions: true,
+                               mediaquery: true,
+                               cssPseudoElement: true,
+                               touchOverflow: true,
+                               cssTransform3d: true,
+                               boxShadow: true,
+                               scrollTop: 0,
+                               dynamicBaseTag: true,
+                               cssPointerEvents: false,
+                               boundingRect: true,
+                               browser: {
+                                       ie: false,
+                                       tizen: isTizen
+                               },
+                               shape: {
+                                       circle: isTizen ? window.matchMedia("(-tizen-geometric-shape: circle)").matches :
+                                               isCircleShape()
+                               },
+                               gradeA: function () {
+                                       return true;
+                               },
+                               isCircleShape: isCircleShape
+                       };
+                       }(window, window.document));
+
+/*global window, ns, define */
+(function (window, document, ns) {
+       "use strict";
+                               var PI = Math.PI,
+                               cos = Math.cos,
+                               sin = Math.sin,
+                               SVGNS = "http://www.w3.org/2000/svg",
+                               objectUtils = ns.util.object,
+                               classes = {
+                                       polar: "ui-polar",
+                                       animated: "ui-animated"
+                               },
+                               defaultsArc = {
+                                       x: 180,
+                                       y: 180,
+                                       r: 170,
+                                       arcStart: 0,
+                                       arcEnd: 90,
+                                       width: 5,
+                                       color: "black",
+                                       animation: false,
+                                       linecap: "butt",
+                                       referenceDegree: 0
+                               },
+                               defaultsRadius = {
+                                       x: 180,
+                                       y: 180,
+                                       r: 170,
+                                       degrees: 0,
+                                       length: 180,
+                                       direction: "in",
+                                       width: 5,
+                                       color: "black"
+                               },
+                               defaultsText = {
+                                       x: 180,
+                                       y: 180,
+                                       text: "Text",
+                                       position: "middle",
+                                       color: "white"
+                               },
+                               defaultsCircle = {
+                                       x: 180,
+                                       y: 180,
+                                       r: 170,
+                                       color: "white"
+                               },
+                               polar;
+
+                       /**
+                        * Calculate polar coords to cartesian
+                        * @param {number} centerX
+                        * @param {number} centerY
+                        * @param {number} radius
+                        * @param {number} angleInDegrees
+                        * @return {{x: number, y: number}}
+                        */
+                       function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
+                               var angleInRadians = angleInDegrees * PI / 180.0;
+
+                               return {
+                                       x: centerX + (radius * sin(angleInRadians)),
+                                       y: centerY - (radius * cos(angleInRadians))
+                               };
+                       }
+
+                       /**
+                        * Create description of path for arc
+                        * @param {number} x
+                        * @param {number} y
+                        * @param {number} radius
+                        * @param {number} startAngle Angle in degrees where arc starts
+                        * @param {number} endAngle Angle in degrees where arc ends
+                        * @return {string}
+                        */
+                       function describeArc(x, y, radius, startAngle, endAngle) {
+                               var start = polarToCartesian(x, y, radius, endAngle),
+                                       end = polarToCartesian(x, y, radius, startAngle),
+                                       arcSweep = endAngle - startAngle <= 180 ? "0" : "1",
+                                       clockWise = 0;
+
+                               return [
+                                       "M", start.x, start.y,
+                                       "A", radius, radius, 0, arcSweep, clockWise, end.x, end.y
+                               ].join(" ");
+                       }
+
+                       function addPath(svg, options) {
+                               var path = document.createElementNS(SVGNS, "path");
+
+                               path.setAttribute("class", options.classes);
+                               path.setAttribute("fill", "none");
+                               path.setAttribute("stroke", options.color);
+                               path.setAttribute("stroke-width", options.width);
+                               path.setAttribute("d", describeArc(options.x, options.y, options.r,
+                                       options.referenceDegree + options.arcStart, options.referenceDegree + options.arcEnd));
+                               path.setAttribute("data-initial-degree", options.referenceDegree);
+                               path.setAttribute("stroke-linecap", options.linecap);
+
+                               svg.appendChild(path);
+                       }
+
+                       function addAnimation(element, options) {
+                               var style = element.style,
+                                       value = options.x + "px " + options.y + "px",
+                                       degrees = (options.referenceDegree + options.arcStart) || options.degrees;
+
+                               // phantom not support classList on SVG
+                               if (element.classList) {
+                                       // add class for transition
+                                       element.classList.add(classes.animated);
+                               }
+
+                               // set transform
+                               style.webkitTransformOrigin = value;
+                               style.mozTransformOrigin = value;
+                               style.transformOrigin = value;
+
+                               value = "rotate(" + degrees + "deg)";
+                               style.webkitTransform = value;
+                               style.mozTransform = value;
+                               style.transform = value;
+                       }
+
+                       function addRadius(svg, options) {
+                               var line = document.createElementNS(SVGNS, "line"),
+                                       positionStart,
+                                       positionEnd;
+
+                               line.setAttribute("class", options.classes);
+                               line.setAttribute("stroke", options.color);
+                               line.setAttribute("stroke-width", options.width);
+                               if (options.direction === "out") {
+                                       positionStart = polarToCartesian(options.x, options.y, options.r, options.degrees);
+                                       positionEnd = polarToCartesian(options.x, options.y, options.r - options.length,
+                                               options.degrees);
+                               } else {
+                                       positionStart = polarToCartesian(options.x, options.y, options.r - options.length,
+                                               options.degrees);
+                                       positionEnd = polarToCartesian(options.x, options.y, options.r, options.degrees);
+                               }
+                               line.setAttribute("x1", positionStart.x);
+                               line.setAttribute("y1", positionStart.y);
+                               line.setAttribute("x2", positionEnd.x);
+                               line.setAttribute("y2", positionEnd.y);
+
+                               svg.appendChild(line);
+                               return line;
+                       }
+
+                       function addText(svg, options) {
+                               var text = document.createElementNS(SVGNS, "text");
+
+                               text.setAttribute("x", options.x);
+                               text.setAttribute("y", options.y);
+                               text.setAttribute("text-anchor", options.position);
+                               text.setAttribute("fill", options.color);
+                               text.setAttribute("transform", options.transform);
+                               text.textContent = options.text;
+
+                               svg.appendChild(text);
+                       }
+
+                       function addCircle(svg, options) {
+                               var circle = document.createElementNS(SVGNS, "circle");
+
+                               circle.setAttribute("stroke", options.color);
+                               circle.setAttribute("stroke-width", options.width);
+                               circle.setAttribute("cx", options.x);
+                               circle.setAttribute("cy", options.y);
+                               circle.setAttribute("r", options.r);
+                               circle.setAttribute("fill", options.fill);
+
+                               svg.appendChild(circle);
+                               return circle;
+                       }
+
+                       function updatePathPosition(path, options) {
+                               var reference;
+
+                               if (options.animation) {
+                                       addAnimation(path, options);
+                               } else {
+                                       if (path) {
+                                               reference = parseInt(path.getAttribute("data-initial-degree"), 10) || options.referenceDegree;
+                                               path.setAttribute("data-initial-degree", reference);
+                                               path.setAttribute("d", describeArc(options.x, options.y, options.r,
+                                                       reference + options.arcStart, reference + options.arcEnd));
+                                       }
+                               }
+                       }
+
+                       function updateLinePosition(line, options) {
+                               var positionStart,
+                                       positionEnd;
+
+                               if (options.animation) {
+                                       addAnimation(line, options);
+                               } else {
+                                       if (line) {
+                                               positionStart = polarToCartesian(options.x, options.y, options.r, options.degrees);
+                                               positionEnd = polarToCartesian(options.x, options.y, options.r - options.length, options.degrees);
+
+                                               line.setAttribute("x1", positionStart.x);
+                                               line.setAttribute("y1", positionStart.y);
+                                               line.setAttribute("x2", positionEnd.x);
+                                               line.setAttribute("y2", positionEnd.y);
+                                       }
+                               }
+                       }
+
+                       polar = {
+                               default: {
+                                       arc: defaultsArc,
+                                       radius: defaultsRadius,
+                                       text: defaultsText
+                               },
+                               classes: classes,
+
+                               polarToCartesian: polarToCartesian,
+
+                               /**
+                                * creates SVG element
+                                * @method createSVG
+                                * @member ns.util.polar
+                                * @param {HTMLElement} element
+                                * @return {SVGElement}
+                                * @static
+                                */
+                               createSVG: function (element) {
+                                       var svg = document.createElementNS(SVGNS, "svg");
+
+                                       // phantom not support classList on SVG
+                                       if (svg.classList) {
+                                               // add class to svg element
+                                               svg.classList.add(classes.polar);
+                                       }
+                                       // if element is set, add svg as child node
+                                       if (element) {
+                                               element.appendChild(svg);
+                                       }
+                                       return svg;
+                               },
+
+                               /**
+                                * draw arc on the svg element
+                                * @method addArc
+                                * @member ns.util.polar
+                                * @param {SVGElement} svg
+                                * @param {Object} options
+                                * @return {SVGElement}
+                                * @static
+                                */
+                               addArc: function (svg, options) {
+                                       // read or create new svg
+                                       svg = svg || this.createSVG();
+                                       // set options
+                                       options = objectUtils.merge({}, defaultsArc, options || {});
+                                       // add path with arc
+                                       addPath(svg, options);
+
+                                       return svg;
+                               },
+
+                               /**
+                                * draw radius on the svg element
+                                * @method addRadius
+                                * @member ns.util.polar
+                                * @param {SVGElement} svg
+                                * @param {Object} options
+                                * @return {SVGElement}
+                                * @static
+                                */
+                               addRadius: function (svg, options) {
+                                       // read or create new svg
+                                       svg = svg || this.createSVG();
+                                       // add path with radius
+                                       options = objectUtils.merge({}, defaultsRadius, options || {});
+                                       return addRadius(svg, options);
+                               },
+
+                               /**
+                                * draw text on the svg element
+                                * @method addText
+                                * @member ns.util.polar
+                                * @param {SVGElement} svg
+                                * @param {Object} options
+                                * @return {SVGElement}
+                                * @static
+                                */
+                               addText: function (svg, options) {
+                                       // read or create new svg
+                                       svg = svg || this.createSVG();
+                                       // add path with radius
+                                       options = objectUtils.merge({}, defaultsText, options || {});
+                                       addText(svg, options);
+
+                                       return svg;
+                               },
+
+                               /**
+                                * updatePosition for path or for line drawings in svg
+                                * @method updatePosition
+                                * @member ns.util.polar
+                                * @param {SVGElement} svg
+                                * @param {string} selector
+                                * @param {Object} options
+                                * @static
+                                */
+                               updatePosition: function (svg, selector, options) {
+                                       var path = svg && svg.querySelector("path" + selector),
+                                               line;
+
+                                       if (path) {
+                                               // set options
+                                               options = objectUtils.merge({}, defaultsArc, options || {});
+                                               updatePathPosition(path, options);
+                                       } else {
+                                               line = svg && svg.querySelector("line" + selector);
+                                               if (line) {
+                                                       updateLinePosition(line, options);
+                                               }
+                                       }
+                               },
+
+                               /**
+                                * draw circle on the svg element
+                                * @method addCircle
+                                * @member ns.util.polar
+                                * @param {SVGElement} svg
+                                * @param {Object} options
+                                * @return {SVGElement}
+                                * @static
+                                */
+                               addCircle: function (svg, options) {
+                                       var self = this;
+
+                                       // read or create svg
+                                       svg = svg || self.createSVG();
+
+                                       options = objectUtils.merge({}, defaultsCircle, options || {});
+                                       addCircle(svg, options);
+
+                                       return svg;
+                               }
+                       };
+
+                       ns.util.polar = polar;
+                       }(window, window.document, ns));
+
+/* global requestAnimationFrame, define, ns, Math */
+/**
+ * # JS base scrolling tool
+ *
+ * This enable fast scrolling on element
+ *
+ * @class ns.util.scrolling
+ */
+(function (document, window, ns) {
+       "use strict";
+                               var eventUtil = ns.event,
+                               polarUtil = ns.util.polar,
+                               selectorUtil = ns.util.selectors,
+                               classes = {
+                                       circular: "scrolling-circular",
+                                       direction: "scrolling-direction",
+                                       scrollbar: "scrolling-scrollbar",
+                                       path: "scrolling-path",
+                                       thumb: "scrolling-scrollthumb",
+                                       fadeIn: "fade-in",
+                                       container: "scrolling-container"
+                               },
+                               bounceBack = false,
+                               EVENTS = {
+                                       SCROLL_BEFORE_START: "beforeScrollStart",
+                                       SCROLL_START: "scrollStart",
+                                       SCROLL_END: "scrollEnd",
+                                       SCROLL_FLICK: "flick",
+                                       SCROLL: "scroll"
+                               },
+                               // 1px line space from screen edge
+                               RADIUS = 174,
+                               // position when was last touch start
+                               startPosition = 0,
+                               // current state of scroll position
+                               scrollPosition = 0,
+                               lastScrollPosition = 0,
+                               baseScrollPosition = 0,
+                               moveToPosition = 0,
+                               lastRenderedPosition = 0,
+                               lastTime = Date.now(),
+                               elementStyle = null,
+                               maxScrollPosition = 0,
+                               // scrolling element
+                               scrollingElement = null,
+                               childElement = null,
+                               // cache of previous overflow style to revert after disable
+                               previousOverflow = "",
+                               // cache abs function
+                               abs = Math.abs,
+                               // inform that is touched
+                               isTouch = false,
+                               isScrollableTarget = false,
+                               // direction of scrolling, 0 - mean Y, 1 - mean X
+                               direction = 0,
+                               // cache of round function
+                               round = Math.round,
+                               // cache max function
+                               max = Math.max,
+                               min = Math.min,
+
+                               // Circular scrollbar config
+                               CIRCULAR_SCROLL_BAR_SIZE = 60, // degrees
+                               CIRCULAR_SCROLL_MIN_THUMB_SIZE = 6,
+
+                               // Scrollbar is placed after scrolled element
+                               // that's why normal css values cannot be applied
+                               // margin needs to be subtracted from position
+                               SCROLL_MARGIN = 11,
+                               OVERSCROLL_SIZE = 0,
+
+                               // ScrollBar variables
+                               scrollBar = null,
+                               scrollThumb = null,
+                               scrollBarPosition = 0,
+                               maxScrollBarPosition = 0,
+                               circularScrollBar = ns.support.shape.circle,
+                               circularScrollThumbSize = CIRCULAR_SCROLL_MIN_THUMB_SIZE,
+                               svgScrollBar = null,
+                               scrollBarTimeout = null,
+                               fromAPI = false,
+                               virtualMode = false,
+                               snapSize = null,
+                               snapPoints = null,
+                               currentIndex = 0,
+                               previousIndex = 0,
+                               containerSize = 0,
+                               requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame;
+
+                       /**
+                        * Shows scrollbar using fadeIn class and sets timeout to hide it when not used
+                        */
+                       function fadeInScrollBar() {
+                               if (scrollBar) {
+                                       clearTimeout(scrollBarTimeout);
+                                       scrollBar.classList.add(classes.fadeIn);
+
+                                       scrollBarTimeout = setTimeout(function () {
+                                               if (scrollBar) {
+                                                       scrollBar.classList.remove(classes.fadeIn);
+                                               }
+                                       }, 2000);
+                               }
+                       }
+
+                       /**
+                        * Check that current target is inside scrolling element
+                        * @param {HTMLElement} target
+                        * @return {boolean}
+                        */
+                       function detectTarget(target) {
+                               while (target && target !== document) {
+                                       if (target === scrollingElement) {
+                                               return true;
+                                       }
+                                       target = target.parentElement;
+                               }
+                               return false;
+                       }
+
+                       /**
+                        * Handler for touchstart event
+                        * @param {Event} event
+                        */
+                       function touchStart(event) {
+                               var touches = event.touches,
+                                       touch = touches[0];
+
+                               isScrollableTarget = detectTarget(event.target);
+                               // is is only one touch
+                               if (isScrollableTarget && touches.length === 1) {
+                                       // save current touch point
+                                       startPosition = direction ? touch.clientX : touch.clientY;
+                                       // save current time for calculate acceleration on touchend
+                                       lastTime = Date.now();
+                                       eventUtil.trigger(scrollingElement, EVENTS.SCROLL_BEFORE_START, {
+                                               scrollLeft: direction ? -scrollPosition : 0,
+                                               scrollTop: direction ? 0 : -scrollPosition,
+                                               fromAPI: fromAPI
+                                       });
+                               }
+                       }
+
+                       function touchMoveMain(event) {
+                               var touches = event.touches,
+                                       touch = touches[0],
+                                       // get current position in correct direction
+                                       clientPosition = direction ? touch.clientX : touch.clientY,
+                                       scrollLeft = 0,
+                                       scrollTop = 0;
+
+                               fromAPI = false;
+                               // calculate difference between touch start and current position
+                               lastScrollPosition = clientPosition - startPosition;
+
+                               if (!bounceBack) {
+                                       // normalize value to be in bound [0, maxScroll]
+                                       if (scrollPosition + lastScrollPosition > 0) {
+                                               lastScrollPosition = -scrollPosition;
+                                       }
+                                       if (scrollPosition + lastScrollPosition < -maxScrollPosition) {
+                                               lastScrollPosition = -maxScrollPosition - scrollPosition;
+                                       }
+                               }
+
+                               if (direction) {
+                                       scrollLeft = -(scrollPosition + lastScrollPosition);
+                               } else {
+                                       scrollTop = -(scrollPosition + lastScrollPosition);
+                               }
+
+                               // trigger event scroll start if it is the first touch move
+                               if (!isTouch) {
+                                       eventUtil.trigger(scrollingElement, EVENTS.SCROLL_START, {
+                                               scrollLeft: scrollLeft,
+                                               scrollTop: scrollTop,
+                                               fromAPI: fromAPI
+                                       });
+                               }
+
+                               // trigger event scroll
+                               eventUtil.trigger(scrollingElement, EVENTS.SCROLL, {
+                                       scrollLeft: scrollLeft,
+                                       scrollTop: scrollTop,
+                                       inBounds: (scrollPosition + lastScrollPosition >= -maxScrollPosition) &&
+                                       (scrollPosition + lastScrollPosition <= 0),
+                                       fromAPI: fromAPI
+                               });
+                               fadeInScrollBar();
+                       }
+
+                       /**
+                        * Handler for touchmove event
+                        * @param {Event} event
+                        */
+                       function touchMove(event) {
+                               var touches = event.touches;
+
+                               // if touch start was on scrolled element
+                               if (isScrollableTarget) {
+                                       // if is only one touch
+                                       if (touches.length === 1) {
+                                               touchMoveMain(event);
+                                       }
+                                       // if this is first touch move
+                                       if (!isTouch) {
+                                               // we need start request loop
+                                               isTouch = true;
+                                       }
+                                       requestAnimationFrame(render);
+                               }
+                       }
+
+                       /**
+                        * Get position of scroll for indicated index
+                        * @method getScrollPositionByIndex
+                        * @param {number} index
+                        * @member ns.util.scrolling
+                        * @return {number}
+                        */
+                       function getScrollPositionByIndex(index) {
+                               if (snapPoints) {
+                                       index = max(min(snapPoints.length - 1, index), 0); // validate index value
+                                       return snapPoints[index].position - snapPoints[0].position;
+                               }
+                               return 0;
+                       }
+
+                       /**
+                        * Find index of snap point by given scroll position
+                        * @method getSnapPointIndexByScrollPosition
+                        * @param {number} position scroll position (usually negative value)
+                        * @member ns.util.scrolling
+                        * @return {number}
+                        */
+                       function getSnapPointIndexByScrollPosition(position) {
+                               var current = null,
+                                       next = null,
+                                       len,
+                                       i;
+
+                               if (snapPoints) {
+                                       position -= containerSize / 2; // half of screen
+                                       position = -position;
+                                       if (snapPoints[0].position > position) { // before first position
+                                               return 0;
+                                       }
+                                       for (i = 0, len = snapPoints.length; i < len; i++) {
+                                               current = snapPoints[i];
+                                               next = snapPoints[i + 1];
+                                               if (!next || // this is last snap point
+                                                       current.position < position && next.position > position) {
+                                                       return i;
+                                               }
+                                       }
+                               }
+                               return -1;
+                       }
+
+                       function touchEndCalculateSpeed(inBounds) {
+                               var diffTime = Date.now() - lastTime,
+                                       snapPoint = null;
+
+                               if (inBounds && abs(lastScrollPosition / diffTime) > 1) {
+                                       // if it was fast move, we start animation of scrolling after touch end
+                                       moveToPosition = max(min(round(scrollPosition + 1000 * lastScrollPosition / diffTime),
+                                               0), -maxScrollPosition);
+
+                                       if (snapPoints) {
+                                               currentIndex = getSnapPointIndexByScrollPosition(scrollPosition + 1000 * lastScrollPosition / diffTime);
+                                               snapPoint = snapPoints[currentIndex];
+                                               if (snapPoint) {
+                                                       moveToPosition = -getScrollPositionByIndex(currentIndex);
+                                               }
+                                       } else if (snapSize) {
+                                               moveToPosition = snapSize * round(moveToPosition / snapSize);
+                                       }
+                                       if (abs(lastScrollPosition / diffTime) > 1) {
+                                               eventUtil.trigger(scrollingElement, EVENTS.SCROLL_FLICK, {
+                                                       scrollLeft: direction ? -moveToPosition : 0,
+                                                       scrollTop: direction ? 0 : -moveToPosition,
+                                                       fromAPI: fromAPI
+                                               });
+                                       }
+                                       requestAnimationFrame(moveTo);
+                               } else {
+                                       // touch move was slow
+                                       if (snapPoints) {
+                                               currentIndex = getSnapPointIndexByScrollPosition(scrollPosition);
+                                               snapPoint = snapPoints[currentIndex];
+                                               if (snapPoint) {
+                                                       moveToPosition = -getScrollPositionByIndex(currentIndex);
+                                                       requestAnimationFrame(moveTo);
+                                               }
+                                       } else if (snapSize) {
+                                               moveToPosition = snapSize * round(scrollPosition / snapSize);
+                                               requestAnimationFrame(moveTo);
+                                       }
+                                       isTouch = false;
+                               }
+                       }
+
+                       function touchEndCalculatePosition(inBounds) {
+                               if (bounceBack) {
+                                       if (!inBounds) {
+                                               // if it was fast move, we start animation of scrolling after touch end
+                                               if (scrollPosition > 0) {
+                                                       moveToPosition = 0;
+                                               } else {
+                                                       moveToPosition = -maxScrollPosition;
+                                               }
+                                               requestAnimationFrame(moveTo);
+                                       }
+                               } else {
+                                       // normalize value to be in bound [0, maxScroll]
+                                       if (scrollPosition < -maxScrollPosition) {
+                                               scrollPosition = -maxScrollPosition;
+                                       }
+                                       if (scrollPosition > 0) {
+                                               scrollPosition = 0;
+                                       }
+                               }
+                       }
+
+                       function touchEndTriggerEvents(details) {
+                               eventUtil.trigger(scrollingElement, EVENTS.SCROLL, details);
+                               eventUtil.trigger(scrollingElement, EVENTS.SCROLL_END, details);
+                       }
+
+                       /**
+                        * Handler for touchend event
+                        */
+                       function touchEnd() {
+                               var inBounds,
+                                       scrollLeft = 0,
+                                       scrollTop = 0;
+                               // only if the event touchmove was noticed before
+
+                               if (isTouch) {
+                                       // update state of scrolling
+                                       scrollPosition += lastScrollPosition;
+                                       inBounds = (scrollPosition >= -maxScrollPosition) && (scrollPosition <= 0);
+
+                                       // calculate speed of touch move
+                                       touchEndCalculateSpeed(inBounds);
+                                       touchEndCalculatePosition(inBounds);
+
+                                       if (direction) {
+                                               scrollLeft = -(scrollPosition);
+                                       } else {
+                                               scrollTop = -(scrollPosition);
+                                       }
+
+                                       lastScrollPosition = 0;
+                                       // trigger event scroll
+                                       touchEndTriggerEvents({
+                                               scrollLeft: scrollLeft,
+                                               scrollTop: scrollTop,
+                                               inBounds: inBounds,
+                                               fromAPI: fromAPI
+                                       });
+                                       fadeInScrollBar();
+                                       // we stop scrolling
+                                       isScrollableTarget = false;
+                                       requestAnimationFrame(render);
+                               }
+                       }
+
+                       function getSnapSize(index) {
+                               if (snapPoints) {
+                                       return Math.abs(snapPoints[previousIndex].position - snapPoints[index].position);
+                               } else {
+                                       return snapSize;
+                               }
+                       }
+
+                       /**
+                        * Check visible state of the element
+                        * @param {Element} elm
+                        */
+                       function _isVisible(elm) {
+                               var rect = elm.getBoundingClientRect();
+
+                               return direction ? rect.width : rect.height;
+                       }
+
+                       /**
+                        * Handler for rotary event
+                        * @param {Event} event
+                        */
+                       function rotary(event) {
+                               var eventDirection = event.detail && event.detail.direction;
+
+                               if (scrollingElement && !_isVisible(scrollingElement)) {
+                                       return;
+                               }
+
+                               previousIndex = currentIndex;
+
+                               if (isTouch) {
+                                       lastScrollPosition = 0;
+                                       isTouch = false;
+                               }
+
+                               // update position by snapSize
+                               if (eventDirection === "CW") {
+                                       currentIndex++;
+                                       if (snapPoints && currentIndex >= snapPoints.length) {
+                                               currentIndex = snapPoints.length - 1;
+                                       }
+                                       snapSize = -1 * getSnapSize(currentIndex);
+
+                               } else {
+                                       currentIndex--;
+                                       if (snapPoints && currentIndex < 0) {
+                                               currentIndex = 0;
+                                       }
+                                       snapSize = getSnapSize(currentIndex);
+                               }
+
+                               moveToPosition += snapSize;
+
+                               if (!snapPoints && snapSize) {
+                                       moveToPosition = snapSize * round(moveToPosition / snapSize);
+                               }
+                               if (moveToPosition < -maxScrollPosition) {
+                                       moveToPosition = -maxScrollPosition;
+                               }
+                               if (moveToPosition > 0) {
+                                       moveToPosition = 0;
+                               }
+
+                               requestAnimationFrame(moveTo);
+                               requestAnimationFrame(render);
+                               eventUtil.trigger(scrollingElement, EVENTS.SCROLL_START, {
+                                       scrollLeft: direction ? -(moveToPosition) : 0,
+                                       scrollTop: direction ? 0 : -(moveToPosition),
+                                       fromAPI: false
+                               });
+                       }
+
+                       function moveToCalculatePosition() {
+                               var diffPosition = moveToPosition - scrollPosition,
+                                       // get absolute value
+                                       absDiffPosition = abs(diffPosition);
+
+                               if (absDiffPosition > 10) {
+                                       // we move 10% of difference
+                                       scrollPosition = round(scrollPosition + diffPosition / 10);
+                                       requestAnimationFrame(moveTo);
+                               } else if (absDiffPosition > 2) {
+                                       // else if is difference < 10 then we move 50%
+                                       scrollPosition = round(scrollPosition + diffPosition / 2);
+                                       requestAnimationFrame(moveTo);
+                               } else {
+                                       // if difference is <=2 then we move to end value and finish loop
+                                       scrollPosition = moveToPosition;
+                               }
+                               if (!bounceBack) {
+                                       // normalize scroll value
+                                       if (scrollPosition < -maxScrollPosition) {
+                                               scrollPosition = -maxScrollPosition;
+                                       }
+                                       if (scrollPosition > 0) {
+                                               scrollPosition = 0;
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Loop function to calculate state in animation after touchend
+                        */
+                       function moveTo() {
+                               // calculate difference between current position and expected scroll end
+                               var scrollLeft = 0,
+                                       scrollTop = 0;
+
+                               // if difference is big
+                               if (scrollingElement) {
+                                       moveToCalculatePosition();
+
+                                       if (direction) {
+                                               scrollLeft = -scrollPosition;
+                                       } else {
+                                               scrollTop = -scrollPosition;
+                                       }
+
+                                       // trigger event scroll
+                                       eventUtil.trigger(scrollingElement, EVENTS.SCROLL, {
+                                               scrollLeft: scrollLeft,
+                                               scrollTop: scrollTop,
+                                               inBounds: (scrollPosition >= -maxScrollPosition) && (scrollPosition <= 0),
+                                               fromAPI: fromAPI
+                                       });
+                                       if (!isTouch) {
+                                               eventUtil.trigger(scrollingElement, EVENTS.SCROLL_END, {
+                                                       scrollLeft: scrollLeft,
+                                                       scrollTop: scrollTop,
+                                                       fromAPI: fromAPI
+                                               });
+                                       }
+
+                                       fadeInScrollBar();
+                               }
+                       }
+
+                       function renderScrollbar() {
+                               if (circularScrollBar) {
+                                       polarUtil.updatePosition(svgScrollBar, "." + classes.thumb, {
+                                               arcStart: scrollBarPosition,
+                                               arcEnd: scrollBarPosition + circularScrollThumbSize,
+                                               r: RADIUS
+                                       });
+                               } else {
+                                       if (scrollThumb) {
+                                               if (direction) {
+                                                       scrollThumb.style.transform = "translate(" + scrollBarPosition + "px, 0)";
+                                               } else {
+                                                       scrollThumb.style.transform = "translate(0, " + scrollBarPosition + "px)";
+                                               }
+                                       }
+                               }
+                       }
+                       /**
+                        * Render loop on request animation frame
+                        */
+                       function render() {
+                               // calculate ne position of scrolling as sum of last scrolling state + move
+                               var newRenderedPosition = scrollPosition + lastScrollPosition + baseScrollPosition;
+                               // is position was changed
+
+                               if (newRenderedPosition !== lastRenderedPosition) {
+                                       // we update styles
+                                       lastRenderedPosition = newRenderedPosition;
+                                       if (-newRenderedPosition < maxScrollPosition) {
+                                               scrollBarPosition = -newRenderedPosition / maxScrollPosition * maxScrollBarPosition;
+                                       } else {
+                                               scrollBarPosition = maxScrollBarPosition;
+                                       }
+                                       if (scrollBarPosition < 0) {
+                                               scrollBarPosition = 0;
+                                       }
+
+                                       if (!virtualMode && elementStyle) {
+                                               elementStyle.transform = direction ?
+                                                       "translate(" + lastRenderedPosition + "px, 0)" :
+                                                       "translate(0, " + lastRenderedPosition + "px)";
+                                       }
+                                       renderScrollbar();
+
+                                       requestAnimationFrame(render);
+                               }
+                       }
+
+                       function initPosition() {
+                               // init internal variables
+                               startPosition = 0;
+                               scrollPosition = 0;
+                               scrollBarPosition = 0;
+                               lastScrollPosition = 0;
+                               moveToPosition = 0;
+                               lastRenderedPosition = 0;
+                               baseScrollPosition = 0;
+                               lastTime = Date.now();
+                       }
+
+                       /**
+                        * Enable JS scrolling on element
+                        * @method enable
+                        * @param {HTMLElement} element element for scrolling
+                        * @param {"x"|"y"} [setDirection="y"] direction of scrolling
+                        * @param {boolean} setVirtualMode if is set to true then send event without scroll element
+                        * @member ns.util.scrolling
+                        */
+                       function enable(element, setDirection, setVirtualMode) {
+                               var parentRectangle,
+                                       contentRectangle,
+                                       children,
+                                       existingContainerElement;
+
+                               virtualMode = setVirtualMode;
+                               bounceBack = false;
+                               snapSize = false;
+
+                               if (scrollingElement) {
+                                       ns.warn("Scrolling exist on another element, first call disable method");
+                               } else {
+                                       // detect direction
+                                       direction = (setDirection === "x") ? 1 : 0;
+
+                                       // reset current index for new list element
+                                       currentIndex = 0;
+
+                                       existingContainerElement = element.querySelector("div." + classes.container);
+                                       if (existingContainerElement) {
+                                               childElement = existingContainerElement;
+                                               childElement.style.transform = "";
+                                       } else {
+                                               // we are creating a container to position transform
+                                               childElement = document.createElement("div");
+                                               // ... and appending all children to it
+
+                                               children = Array.prototype.slice.call(element.childNodes)
+
+                                               children.forEach(function (node) {
+                                                       if (!ns.support.shape.circle || selectorUtil.matchesSelector(node, ".ui-header:not(.ui-fixed), :not(.ui-footer)")) {
+                                                               childElement.appendChild(node);
+                                                       }
+                                               });
+
+                                               element.insertBefore(childElement, element.firstElementChild);
+                                               childElement.classList.add(classes.container);
+                                       }
+                                       // setting scrolling element
+                                       scrollingElement = element;
+
+                                       // calculate maxScroll
+                                       parentRectangle = element.getBoundingClientRect();
+                                       contentRectangle = childElement.getBoundingClientRect();
+
+                                       // Max scroll position is determined by size of the content - clip window size
+                                       if (direction) {
+                                               maxScrollPosition = round(contentRectangle.width - parentRectangle.width);
+                                       } else {
+                                               maxScrollPosition = round(contentRectangle.height - parentRectangle.height);
+                                       }
+
+                                       // cache style element
+                                       elementStyle = childElement.style;
+
+                                       initPosition();
+                                       // cache current overflow value to restore in disable
+                                       previousOverflow = window.getComputedStyle(element).getPropertyValue("overflow");
+                                       // set overflow hidden
+                                       element.style.overflow = "hidden";
+                                       // add event listeners
+                                       document.addEventListener("touchstart", touchStart, false);
+                                       document.addEventListener("touchmove", touchMove, false);
+                                       document.addEventListener("touchend", touchEnd, false);
+                                       window.addEventListener("rotarydetent", rotary, true);
+                               }
+                       }
+
+                       /**
+                        * @method disable
+                        * @member ns.util.scrolling
+                        */
+                       function disable() {
+                               disableScrollBar();
+
+                               // clear event listeners
+                               document.removeEventListener("touchstart", touchStart, false);
+                               document.removeEventListener("touchmove", touchMove, false);
+                               document.removeEventListener("touchend", touchEnd, false);
+                               window.removeEventListener("rotarydetent", rotary, true);
+
+                               // after changed page and removed it this element can not exists
+                               if (scrollingElement) {
+                                       scrollingElement.style.overflow = previousOverflow;
+                               }
+
+                               elementStyle = null;
+                               scrollingElement = null;
+                               childElement = null;
+                               svgScrollBar = null;
+                       }
+
+                       function enableScrollBarCircular() {
+                               var arcStartPoint = direction ? 0 : 90;
+
+                               scrollBar.classList.add(classes.circular);
+                               svgScrollBar = polarUtil.createSVG();
+
+                               // create background
+                               polarUtil.addArc(svgScrollBar, {
+                                       arcStart: arcStartPoint - (CIRCULAR_SCROLL_BAR_SIZE / 2),
+                                       arcEnd: arcStartPoint + (CIRCULAR_SCROLL_BAR_SIZE / 2),
+                                       classes: classes.path,
+                                       width: 10,
+                                       r: RADIUS,
+                                       linecap: "round"
+                               });
+                               // create thumb
+                               polarUtil.addArc(svgScrollBar, {
+                                       referenceDegree: arcStartPoint - (CIRCULAR_SCROLL_BAR_SIZE / 2),
+                                       arcStart: 0,
+                                       arcEnd: circularScrollThumbSize,
+                                       classes: classes.thumb,
+                                       width: 10,
+                                       r: RADIUS,
+                                       linecap: "round"
+                               });
+
+                               scrollBar.appendChild(svgScrollBar);
+                               scrollingElement.parentElement.insertBefore(scrollBar, scrollingElement.nextSibling);
+                       }
+
+                       function enableScrollBarRectangular(scrollBarStyle) {
+                               var boundingRect,
+                                       childElementRect,
+                                       scrollThumbStyle,
+                                       scrollBarWidth = 0,
+                                       scrollBarHeight = 0;
+
+                               scrollBar.classList.add(classes.direction + "-" + (direction ? "x" : "y"));
+
+                               scrollThumb = document.createElement("div");
+                               scrollThumbStyle = scrollThumb.style;
+                               scrollThumb.classList.add(classes.thumb);
+
+                               boundingRect = scrollingElement.getBoundingClientRect();
+                               childElementRect = childElement.getBoundingClientRect();
+
+                               if (direction) {
+                                       scrollBarWidth = (boundingRect.width - (2 * SCROLL_MARGIN));
+
+                                       scrollBarStyle.width = scrollBarWidth + "px";
+                                       scrollBarStyle.left = (boundingRect.left + SCROLL_MARGIN) + "px";
+                                       scrollThumbStyle.transform = "translate3d(" + scrollBarPosition + "px,0,0)";
+                                       // Calculate size of the thumb (only useful when enabling after content has size > 0)
+                                       scrollThumbStyle.width = (scrollBarWidth / childElementRect.width * scrollBarWidth) +
+                                               "px";
+                               } else {
+                                       scrollBarHeight = (boundingRect.height - (2 * SCROLL_MARGIN));
+
+                                       scrollBarStyle.height = scrollBarHeight + "px";
+                                       scrollBarStyle.top = (boundingRect.top + SCROLL_MARGIN) + "px";
+                                       scrollThumbStyle.transform = "translate3d(0," + scrollBarPosition + "px,0)";
+                                       // Calculate size of the thumb (only useful when enabling after content has size > 0)
+                                       scrollThumbStyle.height = (scrollBarHeight / childElementRect.height * scrollBarHeight) +
+                                               "px";
+                               }
+
+                               scrollBar.appendChild(scrollThumb);
+                               scrollingElement.parentElement.insertBefore(scrollBar, scrollingElement.nextSibling);
+
+                               // Get max scrollbar position after appending
+                               if (direction) {
+                                       maxScrollBarPosition = scrollBarWidth - scrollThumb.getBoundingClientRect().width;
+                               } else {
+                                       maxScrollBarPosition = scrollBarHeight - scrollThumb.getBoundingClientRect().height;
+                               }
+                       }
+
+                       function enableScrollBar() {
+                               scrollBar = document.createElement("div");
+                               scrollBar.classList.add(classes.scrollbar);
+
+                               if (circularScrollBar) {
+                                       enableScrollBarCircular();
+                               } else {
+                                       enableScrollBarRectangular(scrollBar.style);
+                               }
+                       }
+
+                       function disableScrollBar() {
+                               if (scrollBar) {
+                                       scrollBar.parentElement.removeChild(scrollBar);
+                                       scrollBar = null;
+                                       scrollThumb = null;
+                               }
+                       }
+
+                       /**
+                        * Scroll to give position
+                        * @method scrollTo
+                        * @param {number} value
+                        * @member ns.util.scrolling
+                        */
+                       function scrollTo(value) {
+                               moveToPosition = value;
+                               fromAPI = true;
+                               eventUtil.trigger(scrollingElement, EVENTS.SCROLL_BEFORE_START, {
+                                       scrollLeft: direction ? -scrollPosition : 0,
+                                       scrollTop: direction ? 0 : -scrollPosition,
+                                       fromAPI: fromAPI
+                               });
+                               requestAnimationFrame(moveTo);
+                               render();
+                       }
+
+                       /**
+                        * Return scroll position
+                        * @method getScrollPosition
+                        * @member ns.util.scrolling
+                        */
+                       function getScrollPosition() {
+                               return -scrollPosition;
+                       }
+
+                       /**
+                        * Return max scroll position
+                        * @method getMaxScroll
+                        * @member ns.util.scrolling
+                        */
+                       function getMaxScroll() {
+                               return maxScrollPosition;
+                       }
+
+                       function scrollToIndex(index, from) {
+                               currentIndex = index;
+
+                               // Set the scroll position by index
+                               baseScrollPosition = from;
+                               scrollPosition = -getScrollPositionByIndex(index);
+                               moveToPosition = scrollPosition;
+
+                               // Enforce redraw to apply selected effect
+                               requestAnimationFrame(moveTo);
+                               render();
+                       }
+
+                       /**
+                        * Update max scrolling position
+                        * @method setMaxScroll
+                        * @param {number} maxValue
+                        * @member ns.util.scrolling
+                        */
+                       function setMaxScroll(maxValue) {
+                               var boundingRect = scrollingElement.getBoundingClientRect(),
+                                       directionDimension = direction ? "width" : "height",
+                                       directionSize = boundingRect[directionDimension],
+                                       tempMaxPosition = max(maxValue - directionSize, 0);
+
+                               // Change size of thumb only when necessary
+                               if (tempMaxPosition !== maxScrollPosition) {
+                                       maxScrollPosition = tempMaxPosition || Number.POSITIVE_INFINITY;
+                                       if (scrollBar) {
+                                               if (circularScrollBar) {
+                                                       // Calculate new thumb size based on max scrollbar size
+                                                       circularScrollThumbSize = max((directionSize / (maxScrollPosition + directionSize)) *
+                                                               CIRCULAR_SCROLL_BAR_SIZE, CIRCULAR_SCROLL_MIN_THUMB_SIZE);
+                                                       maxScrollBarPosition = CIRCULAR_SCROLL_BAR_SIZE - circularScrollThumbSize;
+                                                       polarUtil.updatePosition(svgScrollBar, "." + classes.thumb, {
+                                                               arcStart: scrollBarPosition,
+                                                               arcEnd: scrollBarPosition + circularScrollThumbSize,
+                                                               r: RADIUS
+                                                       });
+                                               } else {
+                                                       directionSize -= 2 * SCROLL_MARGIN;
+                                                       scrollThumb.style[directionDimension] =
+                                                               (directionSize / (maxScrollPosition + directionSize) * directionSize) + "px";
+                                                       // Cannot use direct value from style here because CSS may override the minimum
+                                                       // size of thumb here
+                                                       maxScrollBarPosition = directionSize -
+                                                               scrollThumb.getBoundingClientRect()[directionDimension];
+                                               }
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Method sets snap points for scroll
+                        * @param {Array} _snapPoints
+                        * @method setSnapSize
+                        * @member ns.util.scrolling
+                        */
+                       function setSnapPoints(_snapPoints) {
+                               var numberOfSnapPoints = _snapPoints.length;
+
+                               snapPoints = _snapPoints;
+                               snapSize = null;
+                               if (numberOfSnapPoints) {
+                                       maxScrollPosition = snapPoints[numberOfSnapPoints - 1].position - snapPoints[0].position +
+                                               OVERSCROLL_SIZE;
+                               }
+                       }
+
+                       /**
+                        * Method sets snap size for scroll or array of snap points
+                        * @param {number|Array} _snapSize
+                        * @method setSnapSize
+                        * @member ns.util.scrolling
+                        */
+                       function setSnapSize(_snapSize) {
+                               containerSize = (direction) ? scrollingElement.getBoundingClientRect().height :
+                                       scrollingElement.getBoundingClientRect().width;
+
+                               if (Array.isArray(_snapSize)) {
+                                       setSnapPoints(_snapSize);
+                               } else {
+                                       snapPoints = null;
+                                       snapSize = _snapSize;
+                                       if (snapSize) {
+                                               maxScrollPosition = snapSize * round(maxScrollPosition / snapSize);
+                                       }
+                               }
+                       }
+
+                       /**
+                        * Return true is given element is current scrolling element
+                        * @method isElement
+                        * @param {HTMLElement} element element to check
+                        * @return {boolean}
+                        * @member ns.util.scrolling
+                        */
+                       function isElement(element) {
+                               return scrollingElement === element;
+                       }
+
+                       ns.util.scrolling = {
+                               getScrollPosition: getScrollPosition,
+                               getScrollPositionByIndex: getScrollPositionByIndex,
+                               enable: enable,
+                               disable: disable,
+                               enableScrollBar: enableScrollBar,
+                               disableScrollBar: disableScrollBar,
+                               scrollTo: scrollTo,
+                               setMaxScroll: setMaxScroll,
+                               getMaxScroll: getMaxScroll,
+                               setSnapSize: setSnapSize,
+                               scrollToIndex: scrollToIndex,
+                               isElement: isElement,
+                               setBounceBack: function (setBounceBack) {
+                                       bounceBack = setBounceBack;
+                               }
+                       };
+
+                       }(document, window, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, white: true, plusplus: true*/
+/**
+ * #Virtual list
+ * Shows a list view for large amounts of data.
+ *
+ * @class ns.widget.core.VirtualListview
+ * @extends ns.core.BaseWidget
+ * @since 2.0
+ */
+(function (document, ns) {
+       "use strict";
+                               /**
+                        * @property {Object} Widget Alias for {@link ns.widget.BaseWidget}
+                        * @member ns.widget.core.VirtualListview
+                        * @private
+                        * @static
+                        */
+                       var BaseWidget = ns.widget.BaseWidget,
+                               // Constants definition
+                               /**
+                                * Defines index of scroll `{@link ns.widget.core.VirtualListview#_scroll}.direction`
+                                * @property {number} SCROLL_NONE
+                                * to retrieve if user is not scrolling
+                                * @private
+                                * @static
+                                * @member ns.widget.core.VirtualListview
+                                */
+                               SCROLL_NONE = -1,
+                               /**
+                                * Defines index of scroll `{@link ns.widget.core.VirtualListview#_scroll}.direction`
+                                * @property {number} SCROLL_UP
+                                * to retrieve if user is scrolling up
+                                * @private
+                                * @static
+                                * @member ns.widget.core.VirtualListview
+                                */
+                               SCROLL_UP = 0,
+                               /**
+                                * Defines index of scroll {@link ns.widget.core.VirtualListview#_scroll}
+                                * @property {number} SCROLL_DOWN
+                                * to retrieve if user is scrolling down
+                                * @private
+                                * @static
+                                * @member ns.widget.core.VirtualListview
+                                */
+                               SCROLL_DOWN = 1,
+                               /**
+                                * Defines index of scroll {@link ns.widget.core.VirtualListview#_scroll}
+                                * @property {number} SCROLL_LEFT
+                                * to retrieve if user is scrolling left
+                                * @private
+                                * @static
+                                * @member ns.widget.core.VirtualListview
+                                */
+                               SCROLL_LEFT = 2,
+                               /**
+                                * Defines index of scroll `{@link ns.widget.core.VirtualListview#_scroll}.direction`
+                                * @property {number} SCROLL_RIGHT
+                                * to retrieve if user is scrolling right
+                                * @private
+                                * @static
+                                * @member ns.widget.core.VirtualListview
+                                */
+                               SCROLL_RIGHT = 3,
+
+                               /**
+                                * Defines vertical scrolling orientation. It's default orientation.
+                                * @property {string} VERTICAL
+                                * @private
+                                * @static
+                                */
+                               VERTICAL = "y",
+                               /**
+                                * Defines horizontal scrolling orientation.
+                                * @property {string} HORIZONTAL
+                                * @private
+                                * @static
+                                */
+                               HORIZONTAL = "x",
+                               /**
+                                * Determines that scroll event should not be taken into account if scroll event occurs.
+                                * @property {boolean} blockEvent
+                                * @private
+                                * @static
+                                */
+                               blockEvent = false,
+                               /**
+                                * Handle window timeout ID.
+                                * @property {number} timeoutHandler
+                                * @private
+                                * @static
+                                */
+
+                               /**
+                                * Alias for ns.util
+                                * @property {Object} util
+                                * @private
+                                * @static
+                                */
+                               util = ns.util,
+
+                               /**
+                                * Alias for ns.util.requestAnimationFrame
+                                * @property {Function} requestFrame
+                                * @private
+                                * @static
+                                */
+                               requestFrame = util.requestAnimationFrame,
+
+                               selectors = util.selectors,
+
+                               utilEvent = ns.event,
+
+                               utilScrolling = ns.util.scrolling,
+
+                               filter = [].filter,
+
+                               /**
+                                * Local constructor function
+                                * @method VirtualListview
+                                * @private
+                                * @member ns.widget.core.VirtualListview
+                                */
+                               VirtualListview = function () {
+                                       var self = this;
+                                       /**
+                                        * VirtualListview widget's properties associated with
+                                        * @property {Object} ui
+                                        * User Interface
+                                        * @property {?HTMLElement} [ui.scrollview=null] Scroll element
+                                        * @property {?HTMLElement} [ui.spacer=null] HTML element which makes scrollbar proper
+                                        * size
+                                        * @property {number} [ui.itemSize=0] Size of list element in pixels. If scrolling is
+                                        * vertically it's item width in other case it"s height of item element
+                                        * @member ns.widget.core.VirtualListview
+                                        */
+
+                                       self._ui = {
+                                               scrollview: null,
+                                               spacer: null,
+                                               itemSize: 0
+                                       };
+
+                                       /**
+                                        * Holds information about scrolling state
+                                        * @property {Object} _scroll
+                                        * @property {Array} [_scroll.direction=[0,0,0,0]] Holds current direction of scrolling.
+                                        * Indexes suit to following order: [up, left, down, right]
+                                        * @property {number} [_scroll.lastPositionX=0] Last scroll position from top in pixels.
+                                        * @property {number} [_scroll.lastPositionY=0] Last scroll position from left in pixels.
+                                        * @property {number} [_scroll.lastJumpX=0] Difference between last and current
+                                        * position of horizontal scroll.
+                                        * @property {number} [_scroll.lastJumpY=0] Difference between last and current
+                                        * position of vertical scroll.
+                                        * @property {number} [_scroll.clipWidth=0] Width of clip - visible area for user.
+                                        * @property {number} [_scroll.clipHeight=0] Height of clip - visible area for user.
+                                        * @member ns.widget.core.VirtualListview
+                                        */
+                                       self._scroll = {
+                                               direction: [0, 0, 0, 0],
+                                               dir: SCROLL_NONE,
+                                               lastPositionX: 0,
+                                               lastPositionY: 0,
+                                               lastJumpX: 0,
+                                               lastJumpY: 0,
+                                               clipWidth: 0,
+                                               clipHeight: 0
+                                       };
+
+                                       /**
+                                        * Name of widget
+                                        * @property {string} name
+                                        * @member ns.widget.core.VirtualListview
+                                        * @static
+                                        */
+                                       self.name = "VirtualListview";
+
+                                       /**
+                                        * Current zero-based index of data set.
+                                        * @property {number} _currentIndex
+                                        * @member ns.widget.core.VirtualListview
+                                        * @protected
+                                        */
+                                       self._currentIndex = 0;
+
+                                       /**
+                                        * VirtualListview widget options.
+                                        * @property {Object} options
+                                        * @property {number} [options.bufferSize=100] Number of items of result set. The default
+                                        * value is 100.
+                                        * As the value gets higher, the loading time increases while the system performance
+                                        * improves. So you need to pick a value that provides the best performance
+                                        * without excessive loading time. It's recommended to set bufferSize at least 3 times
+                                        * bigger than number
+                                        * of visible elements.
+                                        * @property {number} [options.dataLength=0] Total number of items.
+                                        * @property {string} [options.orientation=VERTICAL] Scrolling orientation. Default
+                                        * VERTICAL scrolling enabled.
+                                        * @property {Object} options.listItemUpdater Holds reference to method which modifies
+                                        * list item, depended
+                                        * at specified index from database. **Method should be overridden by developer using
+                                        * {@link ns.widget.core.VirtualListview#setListItemUpdater} method.** or defined as a
+                                        * config
+                                        * object. Method takes two parameters:
+                                        *  -  element {HTMLElement} List item to be modified
+                                        *  -  index {number} Index of data set
+                                        * @member ns.widget.core.VirtualListview
+                                        */
+                                       self.options = {
+                                               bufferSize: 100,
+                                               dataLength: 0,
+                                               orientation: VERTICAL,
+                                               listItemUpdater: null,
+                                               scrollElement: null,
+                                               optimizedScrolling: false
+                                       };
+
+                                       /**
+                                        * Binding for scroll event listener.
+                                        * @method _scrollEventBound
+                                        * @member ns.widget.core.VirtualListview
+                                        * @protected
+                                        */
+                                       self._scrollEventBound = null;
+
+                                       /**
+                                        * Render function
+                                        * @method _render
+                                        * @protected
+                                        * @member ns.widget.core.VirtualListview
+                                        */
+                                       self._render = render.bind(null, this);
+
+                                       /**
+                                        * Render command list
+                                        * @property {Array.<*>} _renderList
+                                        * @member ns.widget.core.VirtualListview
+                                        * @protected
+                                        */
+                                       self._renderList = [];
+
+                                       /**
+                                        * Element size cache
+                                        * @property {Array.<number>} _sizeMap
+                                        * @member ns.widget.core.VirtualListview
+                                        * @protected
+                                        */
+                                       self._sizeMap = [];
+
+                                       /**
+                                        * DocumentFragment buffer for DOM offscreen manipulations
+                                        * @property {DocumentFragment} _domBuffer
+                                        * @member ns.widget.core.VirtualListview
+                                        * @protected
+                                        */
+                                       self._domBuffer = document.createDocumentFragment();
+
+                                       /**
+                                        * Time for last cleared cache data
+                                        * @property {number} _lastRenderClearTimestamp
+                                        * @member ns.widget.core.VirtualListview
+                                        * @protected
+                                        */
+                                       self._lastRenderClearTimestamp = 0;
+
+                                       /**
+                                        * Time to lease for clearing render caches
+                                        * @property {number} _lastRenderClearTTL
+                                        * @member ns.widget.core.VirtualListview
+                                        * @protected
+                                        */
+                                       self._lastRenderClearTTL = 10000;
+
+                                       /**
+                                        * Average list item size cache
+                                        * @property {number} _avgListItemSize
+                                        * @member ns.widget.core.VirtualListview
+                                        * @protected
+                                        */
+                                       self._avgListItemSize = -1;
+
+                                       return self;
+                               },
+
+                               // Cached prototype for better minification
+                               prototype = new BaseWidget();
+
+                       /**
+                        * Dictionary object containing commonly used widget classes
+                        * @property {Object} classes
+                        * @static
+                        * @readonly
+                        * @member ns.widget.core.VirtualListview
+                        */
+                       VirtualListview.classes = {
+                               /**
+                               * Container for virtual list widget
+                               * @style ui-virtual-list-container
+                               * @member ns.widget.core.VirtualListview
+                               */
+                               uiVirtualListContainer: "ui-virtual-list-container",
+                               /**
+                               * Prepare spacer - element which makes scrollBar proper size
+                               * @style ui-virtual-list-spacer
+                               * @member ns.widget.core.VirtualListview
+                               */
+                               spacer: "ui-virtual-list-spacer"
+                       };
+
+                       /**
+                        * Main render function
+                        * @method render
+                        * @member ns.widget.core.VirtualListview
+                        * @param {ns.widget.core.VirtualListview} vList Reference to VirtualListview object
+                        * @param {DOMHighResTimeStamp} timestamp The current time of the animation
+                        * @private
+                        * @static
+                        */
+                       function render(vList, timestamp) {
+                               var ops = vList._renderList,
+                                       i = 0,
+                                       l = ops.length;
+
+                               for (; i < l; i += 4) {
+                                       if (ops[i] === "propset") {
+                                               ops[i + 1][ops[i + 2]] = ops[i + 3];
+                                       }
+                               }
+
+                               if (l === 0 && timestamp - vList._lastRenderClearTimestamp > vList._lastRenderClearTTL) {
+                                       vList._lastRenderClearTimestamp = timestamp;
+                                       // clear
+                                       vList._sizeMap.length = 0;
+                                       vList._avgListItemSize = -1;
+                               }
+
+                               ops.length = 0;
+                       }
+
+                       /**
+                        * Updates scroll information about position, direction and jump size.
+                        * @method _updateScrollInfo
+                        * @param {ns.widget.core.VirtualListview} self VirtualListview widget reference
+                        * @param {Event} [event] scroll event object.
+                        * @member ns.widget.core.VirtualListview
+                        * @private
+                        * @static
+                        */
+                       function _updateScrollInfo(self, event) {
+                               var scrollInfo = self._scroll,
+                                       scrollDir = SCROLL_NONE,
+                                       scrollViewElement = self._ui.scrollview,
+                                       scrollLastPositionX = scrollInfo.lastPositionX,
+                                       scrollLastPositionY = scrollInfo.lastPositionY,
+                                       scrollviewPosX = scrollViewElement.scrollLeft,
+                                       scrollviewPosY = (event && event.detail && event.detail.scrollTop) ||
+                                               scrollViewElement.scrollTop;
+
+                               self._refreshScrollbar();
+
+                               //Scrolling UP
+                               if (scrollviewPosY < scrollLastPositionY) {
+                                       scrollDir = SCROLL_UP;
+                               }
+
+                               //Scrolling RIGHT
+                               if (scrollviewPosX < scrollLastPositionX) {
+                                       scrollDir = SCROLL_RIGHT;
+                               }
+
+                               //Scrolling DOWN
+                               if (scrollviewPosY > scrollLastPositionY) {
+                                       scrollDir = SCROLL_DOWN;
+                               }
+
+                               //Scrolling LEFT
+                               if (scrollviewPosX > scrollLastPositionX) {
+                                       scrollDir = SCROLL_LEFT;
+                               }
+
+                               scrollInfo.lastJumpY = Math.abs(scrollviewPosY - scrollLastPositionY);
+                               scrollInfo.lastJumpX = Math.abs(scrollviewPosX - scrollLastPositionX);
+                               scrollInfo.lastPositionX = scrollviewPosX;
+                               scrollInfo.lastPositionY = scrollviewPosY;
+                               scrollInfo.dir = scrollDir;
+                               scrollInfo.clipHeight = scrollViewElement.clientHeight;
+                               scrollInfo.clipWidth = scrollViewElement.clientWidth;
+                       }
+
+                       /**
+                        * Computes list element size according to scrolling orientation
+                        * @method _computeElementSize
+                        * @param {HTMLElement} element Element whose size should be computed
+                        * @param {string} orientation Scrolling orientation
+                        * @return {number} Size of element in pixels
+                        * @member ns.widget.core.VirtualListview
+                        * @private
+                        * @static
+                        */
+                       function _computeElementSize(element, orientation) {
+                               return parseInt((orientation === VERTICAL) ? element.clientHeight : element.clientWidth, 10);
+                       }
+
+                       /**
+                        * Scrolls and manipulates DOM element to destination index. Element at destination
+                        * index is the first visible element on the screen. Destination index can
+                        * be different from Virtual List's current index, because current index points
+                        * to first element in the buffer.
+                        * @member ns.widget.core.VirtualListview
+                        * @param {ns.widget.core.VirtualListview} self VirtualListview widget reference
+                        * @param {number} toIndex Destination index.
+                        * @method _orderElementsByIndex
+                        * @private
+                        * @static
+                        */
+                       function _orderElementsByIndex(self, toIndex) {
+                               var element = self.element,
+                                       options = self.options,
+                                       scrollInfo = self._scroll,
+                                       scrollClipSize,
+                                       dataLength = options.dataLength,
+                                       indexCorrection,
+                                       bufferedElements,
+                                       avgListItemSize = self._avgListItemSize,
+                                       bufferSize = options.bufferSize,
+                                       i,
+                                       offset,
+                                       index,
+                                       isLastBuffer = false,
+                                       children = filter.call(element.children, isListItem);
+
+                               //Get size of scroll clip depended on scroll direction
+                               scrollClipSize = options.orientation === VERTICAL ? scrollInfo.clipHeight :
+                                       scrollInfo.clipWidth;
+
+                               //Compute average list item size
+                               if (avgListItemSize === -1) {
+                                       self._avgListItemSize = avgListItemSize =
+                                               _computeElementSize(element, options.orientation) / bufferSize;
+                               }
+
+                               //Compute average number of elements in each buffer (before and after clip)
+                               bufferedElements = Math.floor((bufferSize -
+                                       Math.floor(scrollClipSize / avgListItemSize)) / 2);
+
+                               if (toIndex - bufferedElements <= 0) {
+                                       index = 0;
+                               } else {
+                                       index = toIndex - bufferedElements;
+                               }
+
+                               if (index + bufferSize >= dataLength) {
+                                       index = dataLength - bufferSize;
+                                       if (index < 0) {
+                                               index = 0;
+                                       }
+                                       isLastBuffer = true;
+                               }
+                               indexCorrection = toIndex - index;
+
+                               self._loadData(index);
+                               blockEvent = true;
+                               offset = index * avgListItemSize;
+                               if (options.orientation === VERTICAL) {
+                                       if (isLastBuffer) {
+                                               offset = self._ui.spacer.clientHeight;
+                                       }
+                                       self._addToRenderList("propset", element.style, "margin-top", offset + "px");
+                               } else {
+                                       if (isLastBuffer) {
+                                               offset = self._ui.spacer.clientWidth;
+                                       }
+                                       self._addToRenderList("propset", element.style, "margin-left", offset + "px");
+                               }
+
+                               for (i = 0; i < indexCorrection; i += 1) {
+                                       offset += _computeElementSize(children[i], options.orientation);
+                               }
+
+                               if (options.orientation === VERTICAL) {
+                                       //MOBILE: self._ui.scrollview.element.scrollTop = offset;
+                                       if (utilScrolling.isElement(self._ui.scrollview)) {
+                                               utilScrolling.scrollTo(offset);
+                                       } else {
+                                               self._ui.scrollview.scrollTop = offset;
+                                       }
+                               } else {
+                                       //MOBILE: self._ui.scrollview.element.scrollLeft = offset;
+                                       self._ui.scrollview.scrollLeft = offset;
+                               }
+                               blockEvent = false;
+                               self._currentIndex = index;
+                       }
+
+                       function getFirstElementChild(element) {
+                               var firstLiElement = element.firstElementChild;
+
+                               while (firstLiElement) {
+                                       if (firstLiElement.tagName === "LI") {
+                                               return firstLiElement;
+                                       }
+                                       firstLiElement = firstLiElement.nextElementSibling;
+                               }
+                               return null;
+                       }
+
+                       /**
+                        * Loads element range into internal list item buffer. Elements are taken off one end of the
+                        * children list,
+                        *  placed on the other end (i.e.: first is taken and appended ath the end when scrolling
+                        *  down)
+                        *  and their contents get reloaded. Content reload is delegated to an external function
+                        *  (_updateListItem).
+                        * Depending on the direction, elements are
+                        * @param {VirtualList} self
+                        * @param {HTMLElement} element parent widget (the list view) of the (re)loaded element range
+                        * @param {HTMLElement} domBuffer an off-document element for temporary storage of processed
+                        * elements
+                        * @param {Function} sizeGetter a function calculating element size
+                        * @param {number} loadIndex element index to start loading at
+                        * @param {number} indexDirection -1 when indices decrease with each loaded element, +1
+                        * otherwise
+                        * @param {number} elementsToLoad loaded element count
+                        * @return {number} number of pixels the positions of the widgets in the list moved.
+                        *  Repositioning the widget by this amount (along the scroll axis) is needed for the
+                        *  remaining children
+                        *  elements not to move, relative to the viewport.
+                        * @private
+                        */
+                       function _loadListElementRange(self, element, domBuffer, sizeGetter, loadIndex,
+                               indexDirection, elementsToLoad) {
+                               var temporaryElement,
+                                       children = filter.call(element.children, isListItem),
+                                       jump = 0,
+                                       i;
+
+                               if (indexDirection > 0) {
+                                       for (i = elementsToLoad; i > 0; i--) {
+                                               temporaryElement = children.shift();
+
+                                               // move to offscreen buffer
+                                               domBuffer.appendChild(temporaryElement);
+
+                                               //Updates list item using template
+                                               self._updateListItem(temporaryElement, loadIndex);
+
+                                               // move back to document
+                                               element.appendChild(temporaryElement);
+
+                                               jump += sizeGetter(temporaryElement, loadIndex++);
+                                       }
+                                       self._currentIndex += elementsToLoad;
+                               } else {
+                                       for (i = elementsToLoad; i > 0; i--) {
+                                               temporaryElement = children.shift();
+
+                                               // move to offscreen buffer
+                                               domBuffer.appendChild(temporaryElement);
+
+                                               //Updates list item using template
+                                               self._updateListItem(temporaryElement, loadIndex);
+
+                                               element.insertBefore(temporaryElement, getFirstElementChild(element));
+                                               jump -= sizeGetter(temporaryElement, loadIndex--);
+                                       }
+                                       self._currentIndex -= elementsToLoad;
+                               }
+                               return jump;
+                       }
+
+                       /**
+                        * For a given element style, positioning direction, set the top/left position to
+                        *  elementPosition* adjusted by |jump|. In case the resulting position is outside the bounds
+                        *  defined by valid index ranges (0..dataLength-1), clamp the position to tha boundary.
+                        * @param {VirtualList} self
+                        * @param {number} dataLength max valid index
+                        * @param {Object} elementStyle style of the element repositioned
+                        * @param {number} scrollDir one of the BaseWidget.SCROLL_*
+                        * @param {number} jump amount of pixels the repositioned element should be moved
+                        * @param {number} elementPositionTop current elementTop
+                        * @param {number} elementPositionLeft current elementLeft
+                        * @private
+                        */
+                       function _setElementStylePosition(self, dataLength, elementStyle, scrollDir, jump,
+                               elementPositionTop, elementPositionLeft) {
+                               var scrolledVertically = (scrollDir & 2) === 0,
+                                       scrolledHorizontally = (scrollDir & 2) === 1,
+                                       newPosition,
+                                       currentIndex = self._currentIndex;
+
+                               if (scrolledVertically) {
+                                       newPosition = elementPositionTop + jump;
+
+                                       if (currentIndex <= 0) {
+                                               self._currentIndex = currentIndex = 0;
+                                               newPosition = 0;
+                                       }
+
+                                       if (currentIndex >= (dataLength - 1)) {
+                                               newPosition = self._ui.spacer.clientHeight;
+                                       }
+
+                                       if (newPosition < 0) {
+                                               newPosition = 0;
+                                       }
+
+                                       self._addToRenderList("propset", elementStyle, "margin-top", newPosition + "px");
+                               }
+
+                               if (scrolledHorizontally) {
+                                       newPosition = elementPositionLeft + jump;
+
+                                       if (currentIndex <= 0) {
+                                               self._currentIndex = currentIndex = 0;
+                                               newPosition = 0;
+                                       }
+
+                                       if (currentIndex >= (dataLength - 1)) {
+                                               newPosition = self._ui.spacer.clientWidth;
+                                       }
+
+                                       if (newPosition < 0) {
+                                               newPosition = 0;
+                                       }
+
+                                       self._addToRenderList("propset", elementStyle, "margin-left", newPosition + "px");
+                               }
+                       }
+
+                       /**
+                        * Sums numeric properties of an array of objects
+                        * @method sumProperty
+                        * @member ns.widget.core.VirtualListview
+                        * @param {Array.<Object>} elements An array of objects
+                        * @param {string} property The property name
+                        * @return {number}
+                        * @private
+                        * @static
+                        */
+                       function sumProperty(elements, property) {
+                               var result = 0,
+                                       i = elements.length;
+
+                               while (--i >= 0) {
+                                       result += elements[i][property];
+                               }
+
+                               return result;
+                       }
+
+                       function isListItem(element) {
+                               return element.tagName === "LI";
+                       }
+
+                       /**
+                        *
+                        * @param {Array} sizeMap
+                        * @param {boolean} horizontal
+                        * @param {HTMLElement} element
+                        * @param {number} index
+                        * @return {*}
+                        * @private
+                        */
+                       function _getElementSize(sizeMap, horizontal, element, index) {
+                               if (sizeMap[index] === undefined) {
+                                       sizeMap[index] = horizontal ? element.clientWidth : element.clientHeight;
+                               }
+                               return sizeMap[index];
+                       }
+
+                       /**
+                        * Orders elements. Controls resultset visibility and does DOM manipulation. This
+                        * method is used during normal scrolling.
+                        * @method _orderElements
+                        * @param {ns.widget.core.VirtualListview} self VirtualListview widget reference
+                        * @member ns.widget.core.VirtualListview
+                        * @private
+                        * @static
+                        */
+                       function _orderElements(self) {
+                               var element = self.element,
+                                       scrollInfo = self._scroll,
+                                       options = self.options,
+                                       elementStyle = element.style,
+                                       //Current index of data, first element of resultset
+                                       currentIndex = self._currentIndex,
+                                       //Number of items in resultset
+                                       bufferSize = parseInt(options.bufferSize, 10),
+                                       //Total number of items
+                                       dataLength = options.dataLength,
+                                       //Array of scroll direction
+                                       scrollDir = scrollInfo.dir,
+                                       scrollLastPositionY = scrollInfo.lastPositionY,
+                                       scrollLastPositionX = scrollInfo.lastPositionX,
+                                       elementPositionTop = parseInt(elementStyle.marginTop, 10) || 0,
+                                       elementPositionLeft = parseInt(elementStyle.marginLeft, 10) || 0,
+                                       elementsToLoad,
+                                       bufferToLoad,
+                                       elementsLeftToLoad = 0,
+                                       domBuffer = self._domBuffer,
+                                       avgListItemSize = self._avgListItemSize,
+                                       resultsetSize = sumProperty(
+                                               filter.call(element.children, isListItem),
+                                               options.orientation === VERTICAL ? "clientHeight" : "clientWidth"
+                                       ),
+                                       sizeMap = self._sizeMap,
+                                       jump = 0,
+                                       hiddenPart = 0,
+                                       indexDirection,
+                                       loadIndex;
+
+                               if (avgListItemSize === -1) {
+                                       //Compute average list item size
+                                       self._avgListItemSize = avgListItemSize =
+                                               _computeElementSize(element, options.orientation) / bufferSize;
+                               }
+
+                               switch (scrollDir) {
+                                       case SCROLL_NONE:
+                                               break;
+                                       case SCROLL_DOWN:
+                                               hiddenPart = scrollLastPositionY - elementPositionTop;
+                                               elementsLeftToLoad = dataLength - currentIndex - bufferSize;
+                                               break;
+                                       case SCROLL_UP:
+                                               hiddenPart = (elementPositionTop + resultsetSize) -
+                                                       (scrollLastPositionY + scrollInfo.clipHeight);
+                                               elementsLeftToLoad = currentIndex;
+                                               break;
+                                       case SCROLL_RIGHT:
+                                               hiddenPart = scrollLastPositionX - elementPositionLeft;
+                                               elementsLeftToLoad = dataLength - currentIndex - bufferSize;
+                                               break;
+                                       case SCROLL_LEFT:
+                                               hiddenPart = (elementPositionLeft + resultsetSize) -
+                                                       (scrollLastPositionX - scrollInfo.clipWidth);
+                                               elementsLeftToLoad = currentIndex;
+                                               break;
+                               }
+
+                               //manipulate DOM only, when at least 1/2 of result set is hidden
+                               //NOTE: Result Set should be at least 2x bigger then clip size
+                               if (hiddenPart > 0 && (resultsetSize / hiddenPart) <= 2) {
+                                       //Left half of hidden elements still hidden/cached
+                                       elementsToLoad = ((hiddenPart / avgListItemSize) -
+                                               // |0 = floor the value
+                                               ((bufferSize - scrollInfo.clipHeight / avgListItemSize) / 5) | 0) | 0;
+                                       elementsToLoad = Math.min(elementsLeftToLoad, elementsToLoad);
+                                       bufferToLoad = (elementsToLoad / bufferSize) | 0;
+                                       elementsToLoad = elementsToLoad % bufferSize;
+
+                                       if (scrollDir === SCROLL_DOWN || scrollDir === SCROLL_RIGHT) {
+                                               indexDirection = 1;
+                                       } else {
+                                               indexDirection = -1;
+                                       }
+
+                                       // Scrolling more then buffer
+                                       if (bufferToLoad > 0) {
+                                               // Load data to buffer according to jumped index
+                                               self._loadData(currentIndex + indexDirection * bufferToLoad * bufferSize);
+
+                                               // Refresh current index after buffer jump
+                                               currentIndex = self._currentIndex;
+
+                                               jump += indexDirection * bufferToLoad * bufferSize * avgListItemSize;
+                                       }
+
+                                       loadIndex = currentIndex + (indexDirection > 0 ? bufferSize : -1);
+                                       // Note: currentIndex is not valid after this call.
+                                       jump += _loadListElementRange(self, element, domBuffer,
+                                               _getElementSize.bind(null, sizeMap, scrollDir & 2),
+                                               loadIndex, indexDirection, elementsToLoad);
+
+                                       _setElementStylePosition(self, dataLength, elementStyle, scrollDir, jump,
+                                               elementPositionTop, elementPositionLeft);
+                               }
+                       }
+
+                       /**
+                        * Check if scrolling position is changed and updates list if it needed.
+                        * @method _updateList
+                        * @param {ns.widget.core.VirtualListview} self VirtualListview widget reference
+                        * @param {Event} event scroll event triggering this update
+                        * @member ns.widget.core.VirtualListview
+                        * @private
+                        * @static
+                        */
+                       function _updateList(self, event) {
+                               var _scroll = self._scroll;
+
+                               _updateScrollInfo(self, event);
+                               if (_scroll.lastJumpY > 0 || _scroll.lastJumpX > 0 && !blockEvent) {
+                                       _orderElements(self);
+                                       utilEvent.trigger(self.element, "vlistupdate");
+                               }
+                       }
+
+                       /**
+                        * Updates list item using user defined listItemUpdater function.
+                        * @method _updateListItem
+                        * @param {HTMLElement} element List element to update
+                        * @param {number} index Data row index
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._updateListItem = function (element, index) {
+                               this.options.listItemUpdater(element, index);
+                       };
+
+                       prototype._setupScrollview = function (element, orientation) {
+                               var scrollview = selectors.getClosestByClass(element, "ui-scroller") || element.parentElement,
+                                       scrollviewStyle;
+                               //Get scrollview instance
+
+                               scrollviewStyle = scrollview.style;
+
+                               if (orientation === HORIZONTAL) {
+                                       scrollviewStyle.overflowX = "scroll";
+                                       scrollviewStyle.overflowY = "hidden";
+                               } else {
+                                       scrollviewStyle.overflowX = "hidden";
+                                       scrollviewStyle.overflowY = "scroll";
+                               }
+
+                               return scrollview;
+                       };
+
+                       prototype._getScrollView = function (options, element) {
+                               var scrollview = null;
+
+                               if (options.scrollElement) {
+                                       if (typeof options.scrollElement === "string") {
+                                               scrollview = selectors.getClosestBySelector(element, "." + options.scrollElement);
+                                       } else {
+                                               scrollview = options.scrollElement;
+                                       }
+                               }
+
+                               if (!scrollview) {
+                                       scrollview = this._setupScrollview(element, options.orientation);
+                               }
+
+                               return scrollview;
+                       };
+
+                       /**
+                        * Build widget structure
+                        * @method _build
+                        * @param {HTMLElement} element Widget's element
+                        * @return {HTMLElement} Element on which built is widget
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       classes = VirtualListview.classes,
+                                       options = self.options,
+                                       scrollview,
+                                       spacer = document.createElement("div"),
+                                       spacerStyle,
+                                       orientation;
+
+                               //Prepare element
+                               element.style.position = "relative";
+                               element.classList.add(classes.uiVirtualListContainer);
+
+                               //Set orientation, default vertical scrolling is allowed
+                               orientation = options.orientation.toLowerCase() === HORIZONTAL ? HORIZONTAL : VERTICAL;
+
+                               scrollview = self._getScrollView(options, element);
+
+                               // Prepare spacer (element which makes scrollBar proper size)
+                               spacer.classList.add(classes.spacer);
+
+                               spacerStyle = spacer.style;
+                               spacerStyle.display = "block";
+                               spacerStyle.position = "static";
+
+                               if (orientation === HORIZONTAL) {
+                                       spacerStyle.float = "left";
+                               }
+
+                               scrollview.appendChild(spacer);
+
+                               // Assign variables to members
+                               ui.spacer = spacer;
+                               ui.scrollview = scrollview;
+                               options.orientation = orientation;
+
+                               return element;
+                       };
+
+                       /**
+                        * Initialize widget on an element.
+                        * @method _init
+                        * @param {HTMLElement} element Widget's element
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       scrollview = ui.scrollview || self._getScrollView(options, element),
+                                       elementRect,
+                                       scrollviewRect;
+
+                               if (options.dataLength < options.bufferSize) {
+                                       options.bufferSize = options.dataLength;
+                               }
+
+                               if (options.bufferSize < 1) {
+                                       options.bufferSize = 1;
+                               }
+
+                               elementRect = element.getBoundingClientRect();
+                               scrollviewRect = scrollview.getBoundingClientRect();
+                               // Assign variables to members
+                               self._initTopPosition = elementRect.top - scrollviewRect.top;
+                               self._initLeftPosition = elementRect.left - scrollviewRect.left;
+
+                               scrollview.classList.add("ui-has-virtual-list");
+
+                               ui.spacer = ui.spacer || scrollview.querySelector("." + VirtualListview.classes.spacer);
+                               ui.scrollview = scrollview;
+
+                               options.orientation = options.orientation.toLowerCase() === HORIZONTAL ? HORIZONTAL : VERTICAL;
+
+                               if (options.optimizedScrolling) {
+                                       utilScrolling.enable(scrollview, options.orientation);
+                                       utilScrolling.enableScrollBar();
+                               }
+
+                               // disable tau rotaryScroller the widget has own support for rotary event
+                               ns.util.rotaryScrolling && ns.util.rotaryScrolling.lock();
+                       };
+
+                       /**
+                        * Builds Virtual List structure
+                        * @method _buildList
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._buildList = function () {
+                               var self = this,
+                                       listItem,
+                                       list = self.element,
+                                       options = self.options,
+                                       childElementType = (list.tagName === "UL" ||
+                                               list.tagName === "OL" ||
+                                               list.tagName === "TAU-VIRTUALLISTVIEW") ? "li" : "div",
+                                       numberOfItems = options.bufferSize,
+                                       documentFragment = self._domBuffer,
+                                       orientation = options.orientation,
+                                       i;
+
+                               for (i = 0; i < numberOfItems; ++i) {
+                                       listItem = document.createElement(childElementType);
+
+                                       if (orientation === HORIZONTAL) {
+                                               // NOTE: after rebuild this condition check possible duplication from _init method
+                                               listItem.style.float = "left";
+                                       }
+
+                                       self._updateListItem(listItem, i);
+                                       documentFragment.appendChild(listItem);
+                               }
+
+                               list.appendChild(documentFragment);
+                               this._refresh();
+                       };
+
+                       /**
+                        * Refresh list
+                        * @method _refresh
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._refresh = function () {
+                               //Set default value of variable create
+                               this._refreshScrollbar();
+                       };
+
+                       /**
+                        * Loads data from specified index to result set.
+                        * @method _loadData
+                        * @param {number} index Index of first row
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._loadData = function (index) {
+                               var self = this,
+                                       child = self.element.firstElementChild;
+
+                               if (self._currentIndex !== index) {
+                                       self._currentIndex = index;
+                                       do {
+                                               self._updateListItem(child, index);
+                                               ++index;
+                                               child = child.nextElementSibling;
+                                       } while (child);
+                               }
+                       };
+
+                       /**
+                        * Sets proper scrollbar size: height (vertical), width (horizontal)
+                        * @method _refreshScrollbar
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._refreshScrollbar = function () {
+                               var self = this,
+                                       currentIndex = self._currentIndex,
+                                       element = self.element,
+                                       options = self.options,
+                                       ui = self._ui,
+                                       spacerStyle = ui.spacer.style,
+                                       bufferSizePx,
+                                       listSize;
+
+                               if (options.orientation === VERTICAL) {
+                                       //Note: element.clientHeight is variable
+                                       bufferSizePx = parseFloat(element.clientHeight) || 0;
+                                       listSize = bufferSizePx / options.bufferSize * (options.dataLength - currentIndex);
+
+                                       if (options.optimizedScrolling) {
+                                               utilScrolling.setMaxScroll(listSize);
+                                       } else {
+                                               self._addToRenderList("propset", spacerStyle, "height", (listSize - bufferSizePx) +
+                                                       "px");
+                                       }
+                               } else {
+                                       //Note: element.clientWidth is variable
+                                       bufferSizePx = parseFloat(element.clientWidth) || 0;
+                                       listSize = bufferSizePx / options.bufferSize * options.dataLength;
+
+                                       if (options.optimizedScrolling) {
+                                               utilScrolling.setMaxScroll(listSize);
+                                       } else {
+                                               self._addToRenderList("propset", spacerStyle, "width", (bufferSizePx /
+                                                       options.bufferSize * (options.dataLength - 1) - 4 / 3 * bufferSizePx) + "px");
+                                       }
+
+                               }
+                       };
+
+                       /**
+                        * Binds VirtualListview events
+                        * @method _bindEvents
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._addToRenderList = function () {
+                               var self = this,
+                                       renderList = self._renderList;
+
+                               renderList.push.apply(renderList, arguments);
+                               requestFrame(self._render);
+
+                               //MOBILE: parent_bindEvents.call(self, self.element);
+                       };
+
+                       /**
+                        * Binds VirtualListview events
+                        * @method _bindEvents
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._bindEvents = function () {
+                               var scrollEventBound = _updateList.bind(null, this),
+                                       //MOBILE: scrollviewClip = self._ui.scrollview && self._ui.scrollview.element;
+                                       scrollviewClip = this._ui.scrollview;
+
+                               if (scrollviewClip) {
+                                       scrollviewClip.addEventListener("scroll", scrollEventBound, false);
+                                       this._scrollEventBound = scrollEventBound;
+                               }
+
+                               //MOBILE: parent_bindEvents.call(self, self.element);
+                       };
+
+                       /**
+                        * Cleans widget's resources
+                        * @method _destroy
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       scrollView = self._ui.scrollview,
+                                       uiSpacer = self._ui.spacer,
+                                       element = self.element,
+                                       elementStyle = element.style;
+
+                               // Restore start position
+                               elementStyle.position = "static";
+                               if (self.options.orientation === VERTICAL) {
+                                       elementStyle.top = "auto";
+                               } else {
+                                       elementStyle.left = "auto";
+                               }
+
+                               if (scrollView) {
+                                       utilScrolling.disable(scrollView);
+                                       scrollView.removeEventListener("scroll", self._scrollEventBound, false);
+                               }
+
+                               //Remove spacer element
+                               if (uiSpacer.parentNode) {
+                                       uiSpacer.parentNode.removeChild(uiSpacer);
+                               }
+
+                               //Remove li elements.
+                               while (element.firstElementChild) {
+                                       element.removeChild(element.firstElementChild);
+                               }
+                       };
+
+                       /**
+                        * This method scrolls list to defined position in pixels.
+                        * @method scrollTo
+                        * @param {number} position Scroll position expressed in pixels.
+                        * @member ns.widget.core.VirtualListview
+                        */
+                       prototype.scrollTo = function (position) {
+                               var self = this;
+
+                               if (utilScrolling.isElement(self._ui.scrollview)) {
+                                       utilScrolling.scrollTo(position);
+                               } else {
+                                       self._ui.scrollview.scrollTop = position;
+                               }
+                       };
+
+                       /**
+                        * This method scrolls list to defined index.
+                        * @method scrollToIndex
+                        * @param {number} index Scroll Destination index.
+                        * @member ns.widget.core.VirtualListview
+                        */
+                       prototype.scrollToIndex = function (index) {
+                               if (index < 0) {
+                                       index = 0;
+                               }
+                               if (index >= this.options.dataLength) {
+                                       index = this.options.dataLength - 1;
+                               }
+                               _updateScrollInfo(this);
+                               _orderElementsByIndex(this, index);
+                       };
+
+                       /**
+                        * This method builds widget and trigger event "draw".
+                        * @method draw
+                        * @member ns.widget.core.VirtualListview
+                        */
+                       prototype.draw = function () {
+                               this._buildList();
+                               this.trigger("draw");
+                       };
+
+                       /**
+                        * This method sets list item updater function.
+                        * To learn how to create list item updater function please
+                        * visit Virtual List User Guide.
+                        * @method setListItemUpdater
+                        * @param {Object} updateFunction Function reference.
+                        * @member ns.widget.core.VirtualListview
+                        */
+                       prototype.setListItemUpdater = function (updateFunction) {
+                               this.options.listItemUpdater = updateFunction;
+                       };
+
+                       // Assign prototype
+                       VirtualListview.prototype = prototype;
+                       ns.widget.core.VirtualListview = VirtualListview;
+
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+
+/**
+ * #Virtual List Widget
+ * Widget creates special list which can contain big number of items.
+ *
+ * In the Web environment, it is challenging to display a large amount of data in a list, such as
+ * displaying a contact list of over 1000 list items. It takes time to display the entire list in
+ * HTML and the DOM manipulation is complex.
+ *
+ * The virtual list widget is used to display a list of unlimited data elements on the screen
+ * for better performance. This widget provides easy access to databases to retrieve and display data.
+ * It based on **result set** which is fixed size defined by developer by data-row attribute. Result
+ * set should be **at least 3 times bigger** then size of clip (number of visible elements).
+ *
+ * For now Virtual Lists are based on the **jQuery.template plugin** as described in the jQuery documentation
+ * for jQuery.template plugin - but it will change some day...
+ *
+ * ##Default selectors
+ * In _ul_ elements with _data-role=virtuallistview_ or _data-role=virtuallist_.
+ *
+ * ##Make it work
+ * To active and configure virtual list widget with application follow these steps:
+ *
+ * ####1. Create template and place widget element
+ *
+ *    @example
+ *    <script id="tmp-3-2-7" type="text/x-jquery-tmpl">
+ *            <li class="ui-li-3-2-7">
+ *            <span class="ui-li-text-main">${NAME}</span>
+ *                <img src="00_winset_icon_favorite_on.png" class="ui-li-icon-sub"/>
+ *                <span class="ui-li-text-sub">${ACTIVE}</span>
+ *                <span class="ui-li-text-sub2">${FROM}</span>
+ *            </li>
+ *        </script>
+ *        <ul id="vList" data-role="virtuallistview" data-template="tmp-3-2-7" data-row="100"></ul>
+ *
+ * **NOTE:** Tizen Web UI's data-dbtable attribute and functionality is not supported.
+ *
+ * ####2. Create template and place widget element
+ * Run {@link ns.widget.mobile.VirtualListview#create .create} method to configure iteration function and
+ * declare total number of items.
+ *
+ *    @example
+ *    virtuallistview.create({
+ *             //Configure iteration function
+ *             itemData: function ( idx ) {
+ *                     return myDATA[idx];
+ *             },
+ *             //Declare total number of items
+ *             numItemData: myDATA.length
+ *     });
+ *
+ * ##Manual constructor
+ * To construct VirtualListview widget manually you can use constructor of the widget:
+ *
+ *    @example
+ *    var virtuallistview = ns.engine.instanceWidget(document.getElementById('virtuallistview'), 'VirtualListview');
+ *
+ * If jQuery library is loaded, its method can be used:
+ *
+ *    @example
+ *    var virtuallistview = $('#virtuallistview').virtuallistview();
+ *
+ * **NOTE:** after construct of widget should be create method called with proper parameters.
+ *
+ *
+ * @author Michał Szepielak <m.szepielak@samsung.com>
+ * @author Mateusz Ciepliński <m.cieplinski@samsung.com> [add jQuery template functionality]
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @class ns.widget.mobile.VirtualListview
+ * @extends ns.widget.mobile.Listview
+ */
+
+(function (window, document, ns) {
+       "use strict";
+                               var VirtualListview = ns.widget.core.VirtualListview,
+                               engine = ns.engine,
+                               utils = ns.util,
+                               utilsSelectors = utils.selectors,
+                               nsData = utils.DOM.nsData,
+                               prototype = new VirtualListview(),
+                               //
+                               // CORE METHODS
+                               //
+                               parentInit = prototype._init,
+                               parentRefresh = prototype._refresh,
+                               parentUpdateListItem = prototype._updateListItem;
+
+                       /**
+                        * Initialize widget on an element.
+                        * @method _init
+                        * @param {HTMLElement} element Widget's element
+                        * @member ns.widget.core.VirtualListview
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               engine.instanceWidget(element, "Listview");
+
+                               if (nsData(element, "row") !== null) {
+                                       ns.warn("Row option in VirtualListview is deprecated and not supported. Use bufferSize option instead.");
+                               }
+
+                               if (nsData(element, "template") !== null) {
+                                       ns.warn("Template option in VirtualListview is deprecated and not supported.");
+                               }
+
+                               if (nsData(element, "numItemData") !== null) {
+                                       ns.warn("NumItemData option in VirtualListview is deprecated and not supported. Use dataLength option instead.");
+                               }
+
+                               if (typeof self.options.listItemUpdater !== "function") {
+                                       ns.warn(["ListItemUpdater in VirtualListview is not set.",
+                                               "Probably you use selector for automatic creation of this widget.",
+                                               "Selectors for this widget are deprecated and will be removed in future.",
+                                               "Use setListItemUpdater to set list item updater."].join(" "));
+                               }
+
+                               self._ui.listview = engine.instanceWidget(element, "Listview");
+                               parentInit.call(self, element);
+                       };
+
+                       prototype._refresh = function () {
+                               this._ui.listview.refresh();
+                               parentRefresh.call(this);
+                       };
+
+                       prototype._setupScrollview = function (element) {
+                               var scrollview;
+
+                               // @TODO: get class value from static access to class
+                               scrollview = engine.getBinding(utilsSelectors.getClosestByClass(element, "ui-scrollview-clip"));
+                               return scrollview.element;
+                       };
+
+                       /**
+                        * @method _updateListItem
+                        * Updates list item using user defined listItemUpdater function.
+                        * @param {HTMLElement} element List element to update
+                        * @param {number} index Data row index
+                        * @protected
+                        */
+                       prototype._updateListItem = function (element, index) {
+                               var self = this;
+
+                               if (typeof self.options.listItemUpdater === "function") {
+                                       parentUpdateListItem.call(self, element, index);
+                               } else {
+                                       ns.warn("List item updater must be a function. Using jQuery Template in VirtualListview is deprecated and is not supported");
+                               }
+                       };
+
+                       /**
+                        * Sets iterator function and total number of data based on users arguments.
+                        * @method create
+                        * @protected
+                        * @member ns.widget.mobile.VirtualListview
+                        */
+                       prototype.create = function () {
+                               ns.warn("VirtualListview.create() method is deprecated and no more supported. Use draw() method instead.");
+                       };
+
+                       VirtualListview.prototype = prototype;
+
+                       ns.widget.mobile.VirtualListview = VirtualListview;
+                       ns.engine.defineWidget(
+                               "VirtualListview",
+                               "[data-role='virtuallistview'],[data-role='virtuallist'], .ui-virtuallistview",
+                               ["draw", "setListItemUpdater", "scrollTo", "scrollToIndex", "create"],
+                               VirtualListview,
+                               "tizen"
+                       );
+                       }(window, window.document, ns));
+
+
+/*global window, define, ns, screen */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, white: true, plusplus: true*/
+(function (document, ns) {
+       "use strict";
+                               /**
+                        * @property {Object} Widget Alias for {@link ns.widget.BaseWidget}
+                        * @member ns.widget.core.VirtualListview
+                        * @private
+                        * @static
+                        */
+                       var BaseWidget = ns.widget.BaseWidget,
+                               // Constants definition
+                               /**
+                                * Defines index of scroll `{@link ns.widget.core.VirtualListview#_scroll}.direction`
+                                * @property {number} SCROLL_NONE
+                                * to retrieve if user is not scrolling
+                                * @private
+                                * @static
+                                * @member ns.widget.core.VirtualListview
+                                */
+                               selectors = ns.util.selectors,
+                               // Scrolling util is responsible for support touches and calculate scrolling position after touch
+                               // In Virtual List we use scrolling in virtual model which is responsible for calculate touches, send event
+                               // but don't render scrolled element. For rendering is responsible only Virtual List
+                               utilScrolling = ns.util.scrolling,
+                               circularScreen = ns.support.shape.circle,
+
+                               SimpleVirtualList = function () {
+                                       var self = this;
+
+                                       self.options = {
+                                               dataLength: 0,
+                                               listItemUpdater: null,
+                                               scrollElement: null,
+                                               orientation: "vertical",
+                                               snap: false,
+                                               edgeEffect: circularScreen ? null : defaultEdgeEffect,
+                                               infinite: false
+                                       };
+                                       self._ui = {
+                                               edgeEffect: null,
+                                               scrollview: null
+                                       };
+                                       self._scrollBegin = 0;
+                                       self._elementsMap = [];
+                                       self._itemSize = 0;
+                                       self._numberOfItems = 5;
+                                       self._edgeEffectGradientSize = 0;
+                               },
+                               abs = Math.abs,
+                               min = Math.min,
+                               floor = Math.floor,
+                               filter = Array.prototype.filter,
+                               prototype = new BaseWidget(),
+                               // Current color from changeable style
+                               // @TODO change to dynamic color
+                               EDGE_EFFECT_COLOR = "rgba(61, 185, 204, {1})",
+                               classes = {
+                                       uiVirtualListContainer: "ui-virtual-list-container",
+                                       edgeEffect: "ui-virtual-list-edge-effect"
+                               };
+
+                       SimpleVirtualList.classes = classes;
+
+                       /**
+                        * Effect for edge scrolling on rectangular screens
+                        * @param {number} positionDiff difference from edge to current scroll
+                        * @param {string} orientation `vertical` or `horizontal`
+                        * @param {string} edge `start` or `end` depending on orientation
+                        * @param {number} rawPosition current scroll position
+                        * @param {number} widgetInstance current widget instance
+                        * @return {number}
+                        */
+                       function defaultEdgeEffect(positionDiff, orientation, edge, rawPosition, widgetInstance) {
+                               var ui = widgetInstance._ui,
+                                       edgeEffectElement = ui.edgeEffect || ui.scrollview.querySelector("." + classes.edgeEffect),
+                                       edgeEffectStyle = edgeEffectElement.style,
+                                       gradientSize = min(abs(positionDiff / 8) - 1, 10);
+
+                               if (orientation === "vertical") {
+                                       edgeEffectStyle.top = (edge === "start") ? "0" : "auto";
+                                       edgeEffectStyle.bottom = (edge === "start") ? "auto" : "0";
+                               } else {
+                                       edgeEffectStyle.left = (edge === "start") ? "0" : "auto";
+                                       edgeEffectStyle.right = (edge === "start") ? "auto" : "0";
+                               }
+
+                               // Saved reference to later avoid unnecessary style manipulations
+                               widgetInstance._edgeEffectGradientSize = gradientSize;
+
+                               edgeEffectStyle.boxShadow = "0 0 0 " + gradientSize + "px " + EDGE_EFFECT_COLOR.replace("{1}", 0.5) + "," +
+                                       "0 0 0 " + (gradientSize * 2) + "px " + EDGE_EFFECT_COLOR.replace("{1}", 0.4) + "," +
+                                       "0 0 0 " + (gradientSize * 3) + "px " + EDGE_EFFECT_COLOR.replace("{1}", 0.3) + "," +
+                                       "0 0 0 " + (gradientSize * 4) + "px " + EDGE_EFFECT_COLOR.replace("{1}", 0.2) + "," +
+                                       "0 0 0 " + (gradientSize * 5) + "px " + EDGE_EFFECT_COLOR.replace("{1}", 0.1) + "";
+
+                               return 0;
+                       }
+
+                       function setupScrollview(element) {
+                               return selectors.getClosestByClass(element, "ui-scroller") || element.parentElement;
+                       }
+
+                       function getScrollView(options, element) {
+                               var scrollview = null;
+
+                               if (options.scrollElement) {
+                                       if (typeof options.scrollElement === "string") {
+                                               scrollview = selectors.getClosestBySelector(element, "." + options.scrollElement);
+                                       } else {
+                                               scrollview = options.scrollElement;
+                                       }
+                               }
+
+                               if (!scrollview) {
+                                       scrollview = setupScrollview(element);
+                               }
+
+                               return scrollview;
+                       }
+
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       classes = SimpleVirtualList.classes,
+                                       options = self.options,
+                                       scrollview,
+                                       orientation;
+
+                               //Prepare element
+                               element.classList.add(classes.uiVirtualListContainer);
+
+                               //Set orientation, default vertical scrolling is allowed
+                               orientation = options.orientation.toLowerCase() === "horizontal" ? "horizontal" : "vertical";
+
+                               scrollview = getScrollView(options, element);
+
+                               ui.scrollview = scrollview;
+                               options.orientation = orientation;
+
+                               return element;
+                       };
+
+                       prototype._buildList = function () {
+                               var self = this,
+                                       listItem,
+                                       ui = self._ui,
+                                       scrollviewWidget,
+                                       options = self.options,
+                                       scrollview = self._ui.scrollview,
+                                       sizeProperty = options.orientation === "vertical" ? "height" : "width",
+                                       list = self.element,
+                                       childElementType = (list.tagName === "UL" || list.tagName === "OL") ? "li" : "div",
+                                       numberOfItems = self._numberOfItems,
+                                       content = selectors.getClosestBySelector(list, ".ui-content").getBoundingClientRect(),
+                                       elementRect = null,
+                                       i,
+                                       scrollInitSize = [].reduce.call(scrollview.children, function (previousValue, currentNode) {
+                                               return previousValue + currentNode.getBoundingClientRect()[sizeProperty];
+                                       }, 0),
+                                       circle = ns.support.shape.circle;
+
+                               scrollviewWidget = ns.engine.getBinding(selectors.getClosestBySelector(list,
+                                       ".ui-page"), "Scrollview");
+                               if (scrollviewWidget) {
+                                       scrollviewWidget.option("bouncingEffect", false);
+                                       self._scrollviewWidget = scrollviewWidget;
+                                       options.edgeEffect = function (positionDiff, orientation, edge) {
+                                               scrollviewWidget.showBouncingEffect(edge);
+                                       };
+                               }
+
+                               if (options.dataLength < numberOfItems) {
+                                       numberOfItems = options.dataLength;
+                               }
+
+                               for (i = 0; i < numberOfItems; ++i) {
+                                       listItem = document.createElement(childElementType);
+                                       self._updateListItem(listItem, i);
+                                       list.appendChild(listItem);
+                                       elementRect = self.element.getBoundingClientRect();
+                                       if (elementRect[sizeProperty] < content[sizeProperty]) {
+                                               numberOfItems++;
+                                       }
+                               }
+
+                               if (options.snap && circle) {
+                                       self._snapListviewWidget = ns.engine.instanceWidget(list, "SnapListview", options.snap);
+                               }
+
+                               elementRect = self.element.getBoundingClientRect();
+                               self._itemSize = numberOfItems > 0 ? Math.round(elementRect[sizeProperty] / numberOfItems) : 0;
+                               self._numberOfItems = numberOfItems;
+                               self._containerSize = content[sizeProperty];
+                               self._numberOfVisibleElements = Math.ceil(content[sizeProperty] / self._itemSize);
+
+                               utilScrolling.enable(scrollview, options.orientation === "horizontal" ? "x" : "y", true);
+                               if (options.infinite) {
+                                       utilScrolling.setMaxScroll(null);
+                               } else {
+                                       utilScrolling.enableScrollBar();
+                                       if (scrollview.classList.contains("ui-scroller")) {
+                                               utilScrolling.setMaxScroll((options.dataLength + 1) * self._itemSize + scrollInitSize);
+                                       } else {
+                                               utilScrolling.setMaxScroll(options.dataLength * self._itemSize);
+                                       }
+                               }
+                               if (options.snap && circle) {
+                                       utilScrolling.setSnapSize(self._itemSize);
+                               }
+
+                               // Add default edge effect
+                               // @TODO consider changing to :after and :before
+                               if (options.edgeEffect === defaultEdgeEffect) {
+                                       ui.edgeEffect = document.createElement("div");
+                                       ui.edgeEffect.classList.add(classes.edgeEffect, "orientation-" + options.orientation);
+
+                                       ui.scrollview.appendChild(ui.edgeEffect);
+                               }
+
+                               utilScrolling.setBounceBack(true);
+                       };
+
+                       prototype._updateListItem = function (element, index) {
+                               element.setAttribute("data-index", index);
+                               this.options.listItemUpdater(element, index);
+                       };
+
+                       prototype._refresh = function () {
+                               var self = this;
+
+                               self._buildList();
+                               if (self._snapListviewWidget) {
+                                       self._snapListviewWidget.refresh();
+                               }
+                               self.trigger("draw");
+                       };
+
+                       prototype.draw = function () {
+                               this.refresh();
+                       };
+
+                       prototype.scrollTo = function (position) {
+                               utilScrolling.scrollTo(-position);
+                       };
+
+                       prototype.scrollToIndex = function (index) {
+                               this.scrollTo(Math.floor(this._itemSize * index));
+                       };
+
+                       function filterElement(index, element) {
+                               return element.getAttribute("data-index") === "" + index;
+                       }
+
+                       function filterNextElement(nextIndex, element, index) {
+                               return index > nextIndex;
+                       }
+
+                       function filterFreeElements(map, element) {
+                               return map.indexOf(element) === -1;
+                       }
+
+                       function _updateList(self, event) {
+                               var list = self.element,
+                                       itemSize = self._itemSize,
+                                       options = self.options,
+                                       beginProperty = options.orientation === "vertical" ? "scrollTop" : "scrollLeft",
+                                       scrollBegin = event.detail && event.detail[beginProperty],
+                                       ui = self._ui,
+                                       scrollChildStyle = ui.scrollview.firstElementChild.style,
+                                       fromIndex = 0,
+                                       dataLength = options.dataLength,
+                                       map = [],
+                                       freeElements,
+                                       numberOfItems = self._numberOfItems,
+                                       i = 0,
+                                       infinite = options.infinite,
+                                       currentIndex = 0,
+                                       listItem,
+                                       correction = 0,
+                                       scroll = {
+                                               scrollTop: 0,
+                                               scrollLeft: 0
+                                       },
+                                       inBoundsDiff = 0,
+                                       nextElement,
+                                       j = 0;
+
+                               if (options.edgeEffect) {
+                                       if (event.detail && !event.detail.inBounds) {
+                                               inBoundsDiff = scrollBegin < 0 ? scrollBegin : (scrollBegin + self._containerSize) - (options.dataLength * self._itemSize);
+
+                                               scrollBegin = scrollBegin - inBoundsDiff + options.edgeEffect(inBoundsDiff, // position diff
+                                                       options.orientation, // orientation
+                                                       (scrollBegin < 0) ? "start" : "end", // edge
+                                                       scrollBegin, // raw position
+                                                       self);
+
+                                       } else if (self._edgeEffectGradientSize > 0) {
+                                               // In some rare cases gradient in default edge effect may stay greater than 0
+                                               // eg. fast flicking down and up without touchend
+                                               (ui.edgeEffect || ui.scrollview.querySelector("." + classes.edgeEffect)).style.boxShadow = "none";
+                                               self._edgeEffectGradientSize = 0;
+                                       } else {
+                                               if (self._scrollviewWidget) {
+                                                       self._scrollviewWidget.hideBouncingEffect();
+                                               }
+                                       }
+                               }
+
+                               if (scrollBegin !== undefined) {
+                                       self._scrollBegin = scrollBegin;
+                                       currentIndex = floor(scrollBegin / self._itemSize);
+                                       if (currentIndex !== floor(self._scrollBeginPrev / self._itemSize) && currentIndex >= 0) {
+                                               if (scrollBegin < self._itemSize) {
+                                                       fromIndex = 0;
+                                                       correction = 0;
+                                               } else if (currentIndex > (dataLength - numberOfItems) && !infinite) {
+                                                       fromIndex = dataLength - numberOfItems;
+                                                       correction = itemSize * (currentIndex - fromIndex);
+                                               } else {
+                                                       fromIndex = currentIndex - 1;
+                                                       correction = itemSize;
+                                               }
+
+                                               // Get elements which are currently presented
+                                               for (i = fromIndex; i < fromIndex + numberOfItems; ++i) {
+                                                       map[i - fromIndex] = filter.call(list.children, filterElement.bind(null, i % dataLength))[0];
+                                               }
+
+                                               // Get elements that should be changed
+                                               freeElements = filter.call(list.children, filterFreeElements.bind(null, map));
+
+                                               for (i = fromIndex + numberOfItems - 1; i >= fromIndex; --i) {
+                                                       j = i % dataLength;
+                                                       if ((i >= 0 && i < dataLength) || infinite) {
+
+                                                               // if checked element is not presented
+                                                               if (!map[i - fromIndex]) {
+                                                                       // get first free element
+                                                                       listItem = freeElements.shift();
+                                                                       map[i - fromIndex] = listItem;
+
+                                                                       if (listItem) {
+                                                                               self._updateListItem(listItem, j);
+
+                                                                               // Get the desired position for the element
+                                                                               if (i - fromIndex === numberOfItems - 1 || (j < fromIndex && (scrollBegin > self._scrollBeginPrev))) {
+                                                                                       list.appendChild(listItem);
+                                                                               } else {
+                                                                                       nextElement = map.filter(filterNextElement.bind(null, i - fromIndex))[0];
+                                                                                       if (!nextElement) {
+                                                                                               list.insertBefore(listItem, list.firstElementChild);
+                                                                                       } else {
+                                                                                               list.insertBefore(listItem, nextElement);
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                               scroll[beginProperty] = correction + scrollBegin % self._itemSize;
+                                       } else {
+                                               // If we are somewhere in the middle of the list
+                                               if (scrollBegin >= 0) {
+                                                       if (scrollBegin < self._itemSize) {
+                                                               scroll[beginProperty] = scrollBegin % itemSize;
+                                                       } else if (currentIndex > (dataLength - numberOfItems) && (!infinite)) {
+                                                               fromIndex = dataLength - numberOfItems;
+                                                               correction = itemSize * (currentIndex - fromIndex);
+                                                               scroll[beginProperty] = correction + scrollBegin % itemSize;
+                                                       } else {
+                                                               scroll[beginProperty] = itemSize + scrollBegin % itemSize;
+                                                       }
+                                               } else {
+                                                       // In case we scroll to content before the list
+                                                       scroll[beginProperty] = scrollBegin;
+                                               }
+                                       }
+                                       scrollChildStyle.webkitTransform = "translate(" + (-scroll.scrollLeft) + "px, " + (-scroll.scrollTop) + "px)";
+
+                                       self._scrollBeginPrev = scrollBegin;
+                                       if (self._snapListviewWidget) {
+                                               self._snapListviewWidget.refresh();
+                                       }
+                               }
+                       }
+
+                       prototype._bindEvents = function () {
+                               var scrollEventBound = _updateList.bind(null, this),
+                                       scrollview = this._ui.scrollview;
+
+                               if (scrollview) {
+                                       scrollview.addEventListener("scroll", scrollEventBound, false);
+                                       this._scrollEventBound = scrollEventBound;
+                               }
+
+                       };
+
+                       prototype._destroy = function () {
+                               utilScrolling.disable();
+                       };
+
+                       prototype.setListItemUpdater = function (updateFunction) {
+                               this.options.listItemUpdater = updateFunction;
+                               this.refresh();
+                       };
+
+                       SimpleVirtualList.prototype = prototype;
+
+                       ns.engine.defineWidget(
+                               "VirtualListviewSimple",
+                               // empty selector because widget require manual build
+                               "",
+                               ["draw", "setListItemUpdater", "scrollTo", "scrollToIndex"],
+                               SimpleVirtualList,
+                               "",
+                               true
+                       );
+                       ns.widget.core.VirtualListviewSimple = SimpleVirtualList;
+                       }(window.document, ns));
+
+/*global $, ns, define*/
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true, white: true, browser: true */
+/**
+ * #Virtual Grid Widget
+ * Widget creates special grid which can contain big number of items.
+ *
+ * @class ns.widget.mobile.VirtualGrid
+ * @extends ns.widget.mobile.VirtualListview
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var VirtualList = ns.widget.mobile.VirtualListview,
+                               parentPrototype = VirtualList.prototype,
+                               engine = ns.engine,
+                               domUtils = ns.util.DOM,
+                               /**
+                                * @property {Function} utilsObjectMerge
+                                * @private
+                                * @member ns.widget.mobile.VirtualGrid
+                                * @static
+                                */
+                               utilsObjectMerge = ns.util.object.merge,
+                               // @TODO HORIZONTAL is currently not used, it will be used when horizontal scrolling is ready
+                               /**
+                                * @property {string} HORIZONTAL="x" constant for horizontal virtual grid
+                                * @private
+                                * @member ns.widget.mobile.VirtualGrid
+                                * @static
+                                */
+                               HORIZONTAL = "x",
+                               /**
+                                * @property {string} VERTICAL="y" constant for vertical virtual grid
+                                * @private
+                                * @member ns.widget.mobile.VirtualGrid
+                                * @static
+                                */
+                               VERTICAL = "y",
+                               classes = {
+                                       WRAP_BLOCK_Y: "ui-virtualgrid-wrapblock-y",
+                                       WRAP_BLOCK_X: "ui-virtualgrid-wrapblock-x",
+                                       ITEM: "virtualgrid-item"
+                               },
+                               VirtualGrid = function () {
+                                       return this;
+                               },
+                               prototype = new VirtualList();
+
+                       prototype._configure = function () {
+                               var self = this;
+
+                               // Call parent _configure
+                               if (typeof parentPrototype._configure === "function") {
+                                       parentPrototype._configure.apply(self, arguments);
+                               }
+
+                               /**
+                                * @property {Object} options
+                                * @property {number} options.numItemData number of lines in the grid
+                                * @property {number} [options.rawNumItemData] number of items inside data source
+                                * @property {string} options.direction='y' direction for scrolling elements
+                                * @property {number} options.row number of lines displayed at once
+                                * @property {number} options.itemsPerLine number of elements per one line
+                                * @property {Function} [options.listItemUpdater=null] Method which modifies list item, depended at specified index from database.
+                                * @property {boolean} [options.standalone=false] If true scrollview instance will be created inside of the widget
+                                * **Method may be overridden by developer using {@link ns.widget.mobile.VirtualListview#create .create} method with proper arguments.**
+                                */
+                               self.options = utilsObjectMerge({}, self.options, {
+                                       numItemData: 0,
+                                       direction: VERTICAL,
+                                       row: 50,
+                                       itemsPerLine: 1,
+                                       listItemUpdater: null,
+                                       standalone: false
+                               });
+
+                               /**
+                                * @property {Object} ui Holds UI elements of the widget
+                                * @member ns.widget.mobile.VirtualGrid
+                                */
+                               self._ui = utilsObjectMerge({}, self._ui);
+
+                               /**
+                                * @property {number} _currentIndex Current zero-based index of data set.
+                                * @member ns.widget.mobile.VirtualGrid
+                                */
+                               self._currentIndex = 0;
+
+                               // @TODO Developer currently needs to define direction="x" for VirtualGrid and scroll="x" for container with scrollview,
+                               // @TODO ...it would be better to set scroll="x" for scroll view when it's not forced (defined as HTML attribute)
+                       };
+
+                       prototype._build = function (element) {
+                               if (typeof parentPrototype._build === "function") {
+                                       parentPrototype._build.apply(this, arguments);
+                               }
+
+                               if (this.options.direction === HORIZONTAL) {
+                                       element.style.height = "100%";
+                               }
+
+                               return element;
+                       };
+
+                       /**
+                        * Determines grid sizes, row and column count.
+                        * Temporary adds one element into list to fetch it's sizes.
+                        * @method _setLineSize
+                        * @protected
+                        */
+                       prototype._setLineSize = function () {
+                               var self = this,
+                                       options = self.options,
+                                       tempElement = document.createElement("div"),
+                                       tempFirstChild,
+                                       tempElementFromTemplate,
+                                       list = self.element,
+                                       size,
+                                       containerSize;
+
+                               // Add temporary element for fetching sizes
+                               list.appendChild(tempElement);
+                               self._updateListItem(tempElement, 0);
+                               tempFirstChild = tempElement.firstElementChild;
+                               tempElementFromTemplate = tempFirstChild.firstElementChild;
+
+                               // [NOTE] grid cells are floated to left for vertical scrolling
+                               // First row child element is the grid cell, it gets styles from CSS stylesheet.
+                               // We are clearing float to make list row expand to whole list width.
+                               // To fetch the raw width of template element we are going deeper (tempElementFromTemplate)
+                               // This ensures we fetch the authored value of width for grid cell element.
+
+                               // @TODO consider getting the height/width (.lineSize) each time a new line is parsed, currently all lines are based on the size of first element
+                               if (options.direction === VERTICAL) {
+                                       // Reset width of first child set by updateListElement
+                                       tempFirstChild.style.width = "";
+                                       tempFirstChild.style.float = "none";
+                                       // Fetch original width with everything (including margins)
+                                       size = domUtils.getElementWidth(tempElementFromTemplate, "outer", true, true);
+                                       // .lineSize is required to set the real height or width of a line
+                                       options.lineSize = tempFirstChild.offsetHeight;
+                                       containerSize = list.offsetWidth;
+                               } else {
+                                       // @TODO create proper styles for horizontal scrolling
+                                       size = tempElement.offsetHeight;
+                                       if (options.standalone) {
+                                               containerSize = self._ui.scrollview.element.offsetHeight;
+                                       } else {
+                                               containerSize = list.offsetHeight;
+                                       }
+                                       // .lineSize is required to set the real height or width of a line
+                                       options.lineSize = tempFirstChild.offsetWidth;
+                               }
+
+                               // Remove element after fetching sizes
+                               list.removeChild(tempElement);
+
+                               // Calculate item count per line
+                               options.itemsPerLine = Math.max(Math.floor(containerSize / size), 1);
+                               // Save original element count
+                               options.rawNumItemData = options.numItemData;
+                               // Calculate limited element count
+                               options.numItemData = Math.ceil(options.numItemData / options.itemsPerLine);
+                       };
+
+                       /**
+                        * Configures list. Sets data source and iterator behavior.
+                        * @method _configureList
+                        * @protected
+                        * @param {Object} argumentsArray
+                        */
+                       prototype._configureList = function (argumentsArray) {
+                               var self = this,
+                                       options = self.options,
+                                       args = argumentsArray[0] || {};
+
+                               // @TODO this is easy to use, but the code is confusing
+                               // and doesn't allow easy merging
+                               if (typeof args.itemData === "function" && (typeof args.numItemData === "function" || typeof args.numItemData === "number")) {
+                                       if (typeof args.numItemData === "function") {
+                                               options.numItemData = args.numItemData();
+                                       } else {
+                                               options.numItemData = args.numItemData <= 0 ? 0 : args.numItemData;
+                                       }
+                                       self.itemData = args.itemData;
+                               }
+
+                               // @TODO all options should be merged at once without the need of separate defining variables
+                               options.direction = args.direction || options.direction;
+
+                               // @TODO set minimum set size depending on current screen size
+                               options.row = Math.max(20, options.row);
+
+                               self._setLineSize();
+
+                               self._buildList();
+
+                               //Update scroll info: scroll position etc...
+                               if (options.standalone) {
+                                       self._updateScrollInfo();
+                               }
+                       };
+
+                       /**
+                        * @method _updateListItem
+                        * Prepares list items.
+                        * This method is used once while creating widget and later for every list update (on scroll for example)
+                        * @param {HTMLElement} element Grid line element (usually a div with proper class)
+                        * @param {number} index Index of the item to process
+                        * @protected
+                        */
+                       prototype._updateListItem = function (element, index) {
+                               var self = this,
+                                       options = self.options,
+                                       updateFunction = options.listItemUpdater,
+                                       direction = options.direction,
+                                       itemData = self.itemData,
+                                       $jqTmpl = self._ui.$jqTmpl,
+                                       itemsPerLine = options.itemsPerLine,
+                                       rawNumItemData = options.rawNumItemData,
+                                       elementPercentSize = (100 / itemsPerLine) + "%",
+                                       // Offset for fetching elements from next line
+                                       itemsOffset = itemsPerLine * index,
+                                       templateElement,
+                                       fragment,
+                                       nextItemIndex,
+                                       i = 0;
+
+                               // Clean insides before creating new content
+                               element.innerHTML = "";
+
+                               fragment = document.createDocumentFragment();
+                               nextItemIndex = itemsOffset + i;
+                               // Add items until line end or data source end
+                               // rawNumItemData may be undefined for first time size checking
+                               while (i < itemsPerLine && (rawNumItemData === undefined || nextItemIndex < rawNumItemData)) {
+                                       //@TODO THIS IS A JQUERY INCLUSION IN A TAU WIDGET!!!
+                                       //@TODO FIX THIS!!!
+                                       templateElement = document.createElement("div");
+                                       // Set item-in-line size
+                                       templateElement.style[direction === VERTICAL ? "width" : "height"] = elementPercentSize;
+
+                                       templateElement.classList.add(classes.ITEM);
+
+                                       if (typeof updateFunction === "function") {
+                                               updateFunction(templateElement, nextItemIndex);
+                                       } else {
+                                               templateElement.appendChild($.tmpl($jqTmpl, itemData(nextItemIndex))[0]);
+                                       }
+
+                                       fragment.appendChild(templateElement);
+
+                                       i++;
+                                       nextItemIndex = itemsOffset + i;
+                               }
+
+                               element.appendChild(fragment);
+                               engine.createWidgets(element);
+
+
+                               if (options.lineSize) {
+                                       element.style[direction === VERTICAL ? "height" : "width"] = options.lineSize + "px";
+                               }
+                               element.classList.add(direction === VERTICAL ? classes.WRAP_BLOCK_Y : classes.WRAP_BLOCK_X);
+                       };
+
+                       /**
+                        * List of classes used inside VirtualGrid
+                        * @property {Object} classes
+                        * @property {string} classes.WRAP_BLOCK_Y="ui-virtualgrid-wrapblock-y"
+                        * @property {string} classes.WRAP_BLOCK_X="ui-virtualgrid-wrapblock-x"
+                        * @property {string} classes.ITEM="virtualgrid-item"
+                        * @static
+                        */
+                       VirtualGrid.classes = classes;
+
+                       VirtualGrid.prototype = prototype;
+
+                       ns.widget.mobile.VirtualGrid = VirtualGrid;
+
+                       engine.defineWidget(
+                               "VirtualGrid",
+                               "[data-role=virtualgrid], .ui-virtualgrid",
+                               ["create"],
+                               VirtualGrid,
+                               "mobile"
+                       );
+
+                       }(window, window.document, ns));
+
+/*global window, ns, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Loader Widget
+ * Widget displaying loader popup on page changes.
+ *
+ * ##HTML Examples
+ * ###Create simple loader pending from div using data-role:
+ *
+ *             @example
+ *                     <div data-role="loader" id="ns-loader"></div>
+ *
+ * ###Create simple loader pending from div using class:
+ *
+ *             @example
+ *                     <div class="ui-loader" id="ns-loader"></div>
+ *
+ * ##Manual constructor
+ * For manual creation of loader widget you can use constructor of widget:
+ *
+ *             @example
+ *                     <div id="ns-loader"></div>
+ *                     <script>
+ *                             var elementLoader = document.getElementById("ns-loader"),
+ *                             loader = tau.widget.Loader(elementLoader);
+ *                     </script>
+ * If jQuery library is loaded, its method can be used:
+ *
+ *             @example
+ *                     <div id="ns-loader"></div>
+ *                     <script>
+ *                             $("#ns-loader").loader();
+ *                     </script>
+ *
+ * ##Options for Loader Widget
+ *
+ * Options for widget can be defined as _data-..._ attributes or given as
+ * parameter in constructor.
+ *
+ * You can change option for widget using method **option**.
+ *
+ * ###Custom html
+ * Adds custom html for the inner content of the loading messages
+ *
+ *             @example
+ *                     <div data-role="loader" id="ns-loader"
+ *                     data-html="<span>loading...</span>"></div>
+ *
+ * ###Custom text
+ * Text to be displayed when the loader is shown
+ *
+ *             @example
+ *                     <div data-role="loader" id="ns-loader" data-text="loading...">
+ *                     </div>
+
+ * ###Visibility of text
+ * When the loader is shown and text is added, checks whether the text in the
+ * loading message is shown;
+ *
+ *             @example
+ *                     <div data-role="loader" id="ns-loader" data-text="loading..."
+ *                     data-text-visible="true"></div>
+
+ * ###Set theme
+ * Sets the theme for the loading messages
+ *
+ *             @example
+ *                     <div data-role="loader" id="ns-loader" data-theme="a"></div>
+ *
+ *
+ * ##Options for Loader Widget
+ *
+ * Options for widget can be get/set .
+ *
+ * ###You can change option for widget using method **option**.
+ * Initialize the loader
+ *
+ *             @example
+ *                     <script>
+ *                             var elementLoader = document.getElementById("ns-loader"),
+ *                             loader = tau.widget.Loader(elementLoader);
+ *                     </script>
+ *
+ * ###Custom html
+ * Get or set the html option, after initialization
+ *
+ *             @example
+ *                     <script>
+ *                             //getter
+ *                             loader.option( "html" );
+ *
+ *                             //setter
+ *                             loader.option( "html", "<span>Loader</span>", );
+ *                     </script>
+ *
+ * ###Custom text
+ * Get or set the text option, after initialization
+ *
+ *             @example
+ *                     <script>
+ *                             //getter
+ *                             loader.option( "text" );
+ *
+ *                             //setter
+ *                             loader.option( "text", "Loader" );
+ *                     </script>
+ *
+ * ###Visibility of text
+ * Get or set the textVisible option, after initialization
+ *
+ *             @example
+ *                     <script>
+ *                             //getter
+ *                             loader.option( "textVisible" );
+ *
+ *                             //setter
+ *                             loader.option( "textVisible", "true" );
+ *                     </script>
+ *
+ * ###Set theme
+ * Get or set the theme option, after initialization
+ *
+ *             @example
+ *                     <script>
+ *                             //getter
+ *                             loader.option( "theme" );
+ *
+ *                             //setter
+ *                             loader.option( "theme", "b" );
+ *                     </script>
+ *
+ *
+ * @deprecated
+ * @extends ns.widget.mobile.BaseWidgetMobile
+ * @class ns.widget.mobile.Loader
+ * @author Maciej Moczulski <m.moczulski@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Piotr Kusztal <p.kusztal@samsung.com>
+ */
+(function (window, ns, $) {
+       "use strict";
+
+       
+                       /**
+                        * {Object} Widget Alias for {@link ns.widget.mobile.BaseWidgetMobile}
+                        * @member ns.widget.mobile.Loader
+                        * @private
+                        */
+                       var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               /**
+                                * @property {Object} engine Alias for class ns.engine
+                                * @member ns.widget.mobile.Loader
+                                * @private
+                                */
+                               engine = ns.engine,
+                               object = ns.util.object,
+
+                               Loader = function () {
+                                       var self = this;
+
+                                       self.action = "";
+                                       self.label = null;
+                                       self.defaultHtml = "";
+                                       self.options = object.copy(Loader.prototype.options);
+                               },
+                               classes = {
+                                       uiLoader: "ui-loader",
+                                       uiLoaderPrefix: "ui-loader-",
+                                       uiCorner: "ui-corner-all",
+                                       uiIcon: "ui-icon",
+                                       uiLoaderIcon: "ui-icon-loading",
+                                       uiLoading: "ui-loading",
+                                       uiTextOnly: "ui-loader-textonly"
+                               },
+                               properties = {
+                                       pageLoadErrorMessageTheme: "e",
+                                       pageLoadErrorMessage: "Error Loading Page"
+                               },
+                               prototype = new BaseWidget();
+
+                       /**
+                        * Dictionary for loader related css
+                        * @property {Object} classes
+                        * @member ns.widget.mobile.Loader
+                        * @static
+                        */
+                       Loader.classes = classes;
+
+                       /**
+                        * Dictionary for loader related properties such as messages and
+                        * themes
+                        * @property {Object} properties
+                        * @member ns.widget.mobile.Loader
+                        * @static
+                        */
+                       Loader.properties = properties;
+
+                       /**
+                        * Object with default options
+                        * @property {Object} options
+                        * @property {boolean} [options.textVisible=false] whether the text
+                        * in the loading message is shown
+                        * @property {?string} [options.html=""] custom html for the inner
+                        * content of the loading messages
+                        * @property {string} [options.text="loading"] the text to be
+                        * displayed when the loading is shown
+                        * @member ns.widget.mobile.Loader
+                        */
+                       prototype.options = {
+                               textVisible: false,
+                               html: "",
+                               text: "loading"
+                       };
+
+                       /**
+                        * Build structure of loader widget
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.mobile.Loader
+                        */
+                       prototype._build = function (element) {
+                               var options = this.options,
+                                       loaderElementSpan = document.createElement("span"),
+                                       loaderElementTile = document.createElement("h1"),
+                                       elementClassList = element.classList,
+                                       spanClassList = loaderElementSpan.classList;
+
+                               loaderElementTile.textContent = options.text;
+                               spanClassList.add(classes.uiIcon);
+                               spanClassList.add(classes.uiLoaderIcon);
+
+                               element.appendChild(loaderElementSpan);
+                               element.appendChild(loaderElementTile);
+                               elementClassList.add(classes.uiLoader);
+                               elementClassList.add(classes.uiCorner);
+                               elementClassList.add(classes.uiLoaderPrefix + "default");
+
+                               this.defaultHtml = element.innerHTML;
+
+                               return element;
+                       };
+
+                       /**
+                        * Init structure of loader widget
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.mobile.Loader
+                        */
+                       prototype._init = function (element) {
+                               this.defaultHtml = element.innerHTML;
+                               return element;
+                       };
+
+                       /**
+                        * Reset HTML
+                        *
+                        * Method resets contained html of loader
+                        *
+                        *              @example
+                        *                      <script>
+                        *                              var loaderWidget = tau.widget.Loader(
+                        *                                              document.getElementById("ns-loader")
+                        *                              );
+                        *                              loaderWidget.resetHtml();
+                        *
+                        *                              //or
+                        *
+                        *                              $( "#ns-loader" ).loader( "resetHtml" );
+                        *                      </script>
+                        *
+                        * @method resetHtml
+                        * @param {HTMLElement} element
+                        * @member ns.widget.mobile.Loader
+                        */
+                       prototype.resetHtml = function (element) {
+                               element = element || this.element;
+                               element.innerHTML = this.defaultHtml;
+                       };
+
+                       /**
+                        * Show loader
+                        *
+                        * Method shows loader on the page
+                        *
+                        *              @example
+                        *                      <script>
+                        *                              var loaderWidget = tau.widget.Loader(
+                        *                                              document.getElementById("ns-loader")
+                        *                                      );
+                        *                              loaderWidget.show();
+                        *
+                        *                              // or
+                        *
+                        *                              $( "#ns-loader" ).loader( "show" );
+                        *
+                        *                              //or with parameters
+                        *
+                        *                              $( "#ns-loader" ).loader( "show", {
+                        *                                      text: "foo",
+                        *                                      textVisible: true,
+                        *                                      theme: "z",
+                        *                                      html: ""
+                        *                              });
+                        *                      </script>
+                        *
+                        * @method show
+                        * @param {string} theme
+                        * @param {string} msgText
+                        * @param {boolean} textonly
+                        * @member ns.widget.mobile.Loader
+                        */
+                       prototype.show = function (theme, msgText, textonly) {
+                               var classes = Loader.classes,
+                                       self = this,
+                                       element = self.element,
+                                       elementClassList = element.classList,
+                                       copySettings = {},
+                                       loadSettings = {},
+                                       textVisible,
+                                       message;
+
+                               self.resetHtml(element);
+
+                               if (theme !== undefined && theme.constructor === Object) {
+                                       copySettings = object.copy(self.options);
+                                       loadSettings = object.merge(copySettings, theme);
+                                       // @todo remove $.mobile.loadingMessageTheme
+                                       theme = loadSettings.theme || $.mobile.loadingMessageTheme;
+                               } else {
+                                       loadSettings = self.options;
+                                       // @todo remove $.mobile.loadingMessageTheme
+                                       theme = theme || $.mobile.loadingMessageTheme ||
+                                               loadSettings.theme;
+                               }
+
+                               // @todo remove $.mobile.loadingMessage
+                               message = msgText || $.mobile.loadingMessage ||
+                                       loadSettings.text;
+                               document.documentElement.classList.add(classes.uiLoading);
+
+                               // @todo remove $.mobile.loadingMessage
+                               if ($.mobile.loadingMessage === false && !loadSettings.html) {
+                                       element.getElementsByTagName("h1")[0].innerHTML = "";
+                               } else {
+                                       // @todo remove $.mobile.loadingMessageTextVisible
+                                       if ($.mobile.loadingMessageTextVisible !== undefined) {
+                                               textVisible = $.mobile.loadingMessageTextVisible;
+                                       } else {
+                                               textVisible = loadSettings.textVisible;
+                                       }
+
+                                       element.className = "";
+                                       elementClassList.add(classes.uiLoader);
+                                       elementClassList.add(classes.uiCorner);
+                                       elementClassList.add(classes.uiBodyPrefix + theme);
+                                       elementClassList.add(classes.uiLoaderPrefix +
+                                               (textVisible || msgText ||
+                                                       theme.text ? "verbose" : "default"));
+
+                                       if ((loadSettings.textonly !== undefined &&
+                                               loadSettings.textonly) || textonly) {
+                                               elementClassList.add(classes.uiTextOnly);
+                                       }
+
+                                       if (loadSettings.html) {
+                                               element.innerHTML = loadSettings.html;
+                                       } else {
+                                               element.getElementsByTagName("h1")[0].textContent =
+                                                       message;
+                                       }
+                               }
+
+                       };
+
+                       /**
+                        * Hide loader
+                        *
+                        * Method hides loader on the page
+                        *
+                        *              @example
+                        *                      <script>
+                        *                              var loaderWidget = tau.widget.Loader(
+                        *                                              document.getElementById("ns-loader")
+                        *                                      );
+                        *                              loaderWidget.hide();
+                        *
+                        *                              // or
+                        *
+                        *                              $( "#ns-loader" ).loader( "hide" );
+                        *                      </script>
+                        *
+                        * @method hide
+                        * @member ns.widget.mobile.Loader
+                        */
+                       prototype.hide = function () {
+                               var classes = Loader.classes;
+
+                               document.documentElement.classList.remove(classes.uiLoading);
+                       };
+
+                       /**
+                        * The function "value" is not supported in this widget.
+                        *
+                        * @method value
+                        * @chainable
+                        * @member ns.widget.mobile.Loader
+                        */
+
+                       /**
+                        * Disable the Loader
+                        *
+                        * Method adds disabled attribute on loader and changes look of
+                        * loader to disabled state.
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      var elementLoader = tau.widget.Loader(
+                        *                                      document.getElementById("ns-loader")
+                        *                              );
+                        *                      elementLoader.disable();
+                        *              </script>
+                        *
+                        * If jQuery is loaded:
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      $("#ns-loader").loader("disable");
+                        *              </script>
+                        *
+                        * @method disable
+                        * @chainable
+                        * @member ns.widget.mobile.Loader
+                        */
+
+                       /**
+                        * Enable the loader
+                        *
+                        * Method removes disabled attribute on loader and changes look of
+                        * loader to enabled state.
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      var elementLoader = tau.widget.Loader(
+                        *                                      document.getElementById("ns-loader")
+                        *                              );
+                        *                      elementLoader.enable();
+                        *              </script>
+                        *
+                        * If jQuery is loaded:
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      $("#ns-loader").loader("enable");
+                        *              </script>
+                        *
+                        * @method enable
+                        * @chainable
+                        * @member ns.widget.mobile.Loader
+                        */
+
+                       /**
+                        * Trigger an event on widget's element.
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      var elementLoader = tau.widget.Loader(
+                        *                                      document.getElementById("ns-loader")
+                        *                              );
+                        *                      elementLoader.trigger("eventName");
+                        *              </script>
+                        *
+                        * If jQuery is loaded:
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      $("#ns-loader").loader("trigger", "eventName");
+                        *              </script>
+                        *
+                        * @method trigger
+                        * @param {string} eventName the name of event to trigger
+                        * @param {?*} [data] additional object to be carried with the event
+                        * @param {boolean} [bubbles=true] indicating whether the event
+                        * bubbles up through the DOM or not
+                        * @param {boolean} [cancelable=true] indicating whether the event
+                        * is cancelable
+                        * @return {boolean} false, if any callback invoked preventDefault
+                        * on event object
+                        * @member ns.widget.mobile.Loader
+                        */
+
+                       /**
+                        * Add event listener to widget's element.
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      var elementLoader = tau.widget.Loader(
+                        *                                      document.getElementById("ns-loader")
+                        *                              );
+                        *                      elementLoader.on("eventName", function () {
+                        *                              console.log("Event fires");
+                        *                      });
+                        *              </script>
+                        *
+                        * If jQuery is loaded:S
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      $("#ns-loader").loader("on", "eventName", function () {
+                        *                              console.log("Event fires");
+                        *                      });
+                        *              </script>
+                        *
+                        * @method on
+                        * @param {string} eventName the name of event
+                        * @param {Function} listener function call after event will be
+                        * trigger
+                        * @param {boolean} [useCapture=false] useCapture param tu
+                        * addEventListener
+                        * @member ns.widget.mobile.Loader
+                        */
+
+                       /**
+                        * Remove event listener to widget's element.
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      var elementLoader = tau.widget.Loader(
+                        *                                      document.getElementById("ns-loader")
+                        *                              ),
+                        *                              callback = function () {
+                        *                                      console.log("Event fires");
+                        *                              };
+                        *                      // add callback on event "eventName"
+                        *                      elementLoader.on("eventName", callback);
+                        *                      // ...
+                        *                      // remove callback on event "eventName"
+                        *                      elementLoader.off("eventName", callback);
+                        *              </script>
+                        *
+                        * If jQuery is loaded:
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      var callback = function () {
+                        *                                      console.log("Event fires");
+                        *                              };
+                        *                      // add callback on event "eventName"
+                        *                      $("#ns-loader").loader("on", "eventName", callback);
+                        *                      // ...
+                        *                      // remove callback on event "eventName"
+                        *                      $("#ns-loader").loader("off", "eventName", callback);
+                        *              </script>
+                        * @method off
+                        * @param {string} eventName the name of event
+                        * @param {Function} listener function call after event will be
+                        * trigger
+                        * @param {boolean} [useCapture=false] useCapture param to
+                        * addEventListener
+                        * @member ns.widget.mobile.Loader
+                        */
+
+                       /**
+                        * Get/Set options of the widget.
+                        *
+                        * This method can work in many context.
+                        *
+                        * If first argument is type of object them, method set values for
+                        * options given in object. Keys of object are names of options and
+                        * values from object are values to set.
+                        *
+                        * If you give only one string argument then method return value
+                        * for given option.
+                        *
+                        * If you give two arguments and first argument will be a string
+                        * then second argument will be intemperate as value to set.
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *                      <script>
+                        *                              //getter
+                        *                              loader.option("text");
+                        *
+                        *                              //setter
+                        *                              loader.option("text","Loader");
+                        *                      </script>
+                        *
+                        * If jQuery is loaded:
+                        *
+                        *              @example
+                        *              <div data-role="loader" id="ns-loader"></div>
+                        *
+                        *              <script>
+                        *                      var value;
+                        *
+                        *                      // get value
+                        *                      value = $("#ns-loader").loader("option", "text");
+                        *
+                        *                      // set value
+                        *                      $("#ns-loader").loader(
+                        *                              "option", "text", "Loader fires"
+                        *                      );
+                        *              </script>
+                        *
+                        * @method option
+                        * @param {string|Object} [name] name of option
+                        * @param {*} value value to set
+                        * @member ns.widget.mobile.Loader
+                        * @return {*} return value of option or undefined if method is
+                        * called in setter context
+                        */
+                       // definition
+                       Loader.prototype = prototype;
+                       ns.widget.mobile.Loader = Loader;
+                       engine.defineWidget(
+                               "Loader",
+                               "[data-role='loader'], .ui-loader",
+                               [
+                                       "show",
+                                       "hide",
+                                       "resetHtml"
+                               ],
+                               Loader,
+                               "mobile"
+                       );
+
+                       }(window.document, ns, window.$));
+
+/*global ns, define, ns */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Drawer Widget
+ * Core Drawer widget is a base for creating Drawer widgets for profiles. It
+ * provides drawer functionality - container with ability to open and close with
+ * an animation.
+ *
+ * ### Positioning Drawer left / right (option)
+ * To change position of a Drawer please set data-position attribute of Drawer
+ * element to:
+ *
+ * - left (left position, default)
+ * - right (right position)
+ * @since 1.2
+ * - down (bottom position)
+ * - up (top position)
+ *
+ * ##Opening / Closing Drawer
+ * To open / close Drawer one can use open() and close() methods.
+ *
+ * ##Checking if Drawer is opened.
+ * To check if Drawer is opened use widget`s isOpen() method.
+ *
+ * ##Creating widget
+ * Core drawer is a base class - examples of creating widgets are described in
+ * documentation of profiles
+ *
+ * @class ns.widget.core.Drawer
+ * @component-selector .ui-drawer, [data-role]="drawer"
+ * @extends ns.widget.BaseWidget
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               /**
+                        * @property {Object} Widget Alias for {@link ns.widget.BaseWidget}
+                        * @member ns.widget.core.Drawer
+                        * @private
+                        * @static
+                        */
+                       var BaseWidget = ns.widget.BaseWidget,
+                               /**
+                                * @property {Object} selectors Alias for class ns.util.selectors
+                                * @member ns.widget.core.Drawer
+                                * @private
+                                * @static
+                                * @readonly
+                                */
+                               selectors = ns.util.selectors,
+                               utilDOM = ns.util.DOM,
+                               events = ns.event,
+                               history = ns.history,
+                               Gesture = ns.event.gesture,
+                               Page = ns.widget.core.Page,
+                               STATE = {
+                                       CLOSED: "closed",
+                                       OPENED: "opened",
+                                       SLIDING: "sliding",
+                                       SETTLING: "settling"
+                               },
+                               /**
+                                * Events
+                                * @event draweropen Event triggered then the drawer is opened.
+                                * @event drawerclose Event triggered then the drawer is closed.
+                                * @member ns.widget.core.Drawer
+                                */
+                               CUSTOM_EVENTS = {
+                                       OPEN: "draweropen",
+                                       CLOSE: "drawerclose"
+                               },
+                               /**
+                                * Default values
+                                */
+                               DEFAULT = {
+                                       WIDTH: 240,
+                                       HEIGHT: 360,
+                                       DURATION: 300,
+                                       POSITION: "left"
+                               },
+                               /**
+                                * Drawer constructor
+                                * @method Drawer
+                                */
+                               Drawer = function () {
+                                       var self = this;
+                                       /**
+                                        * Drawer field containing options
+                                        * @property {string} options.position Position of Drawer ("left", "right" or "bottom")
+                                        * @property {number} options.width Width of Drawer
+                                        * @property {number} options.duration Duration of Drawer entrance animation
+                                        * @property {boolean} options.closeOnClick If true Drawer will be closed on overlay
+                                        * @property {boolean} options.overlay Sets whether to show an overlay when Drawer is open.
+                                        * @property {string} options.drawerTarget Set drawer target element as the css selector
+                                        * @property {boolean} options.enable Enable drawer component
+                                        * @property {number} options.dragEdge Set the area that can open the drawer as drag gesture in drawer target element
+                                        * @member ns.widget.core.Drawer
+                                        */
+
+                                       self.options = {
+                                               position: DEFAULT.POSITION,
+                                               width: DEFAULT.WIDTH,
+                                               height: DEFAULT.HEIGHT,
+                                               duration: DEFAULT.DURATION,
+                                               closeOnClick: true,
+                                               overlay: true,
+                                               drawerTarget: "." + Page.classes.uiPage,
+                                               enable: true,
+                                               dragEdge: 1
+                                       };
+
+                                       self._pageSelector = null;
+
+                                       self._isDrag = false;
+                                       self._state = STATE.CLOSED;
+                                       self._settlingType = STATE.CLOSED;
+                                       self._translatedX = 0;
+                                       self._translatedY = 0;
+
+                                       self._ui = {};
+
+                                       self._eventBoundElement = null;
+                                       self._drawerOverlay = null;
+                               },
+                               /**
+                                * Dictionary object containing commonly used widget classes
+                                * @property {Object} classes
+                                * @member ns.widget.core.Drawer
+                                * @private
+                                * @static
+                                * @readonly
+                                */
+                               classes = {
+                                       page: Page.classes.uiPage,
+                                       /**
+                                        * Standard drawer
+                                        * @style ui-drawer
+                                        * @member ns.widget.core.Drawer
+                                        */
+                                       drawer: "ui-drawer",
+                                       /**
+                                        * Drawer appears from the left side.
+                                        * @style ui-drawer-left
+                                        * @member ns.widget.core.Drawer
+                                        */
+                                       left: "ui-drawer-left",
+                                       /**
+                                        * Drawer appears from the right side.
+                                        * @style ui-drawer-right
+                                        * @member ns.widget.core.Drawer
+                                        */
+                                       right: "ui-drawer-right",
+                                       /**
+                                        * Drawer appears from the top side.
+                                        * @style ui-drawer-up
+                                        * @member ns.widget.core.Drawer
+                                        */
+                                       up: "ui-drawer-up",
+                                       /**
+                                        * Drawer appears from the bottom side.
+                                        * @style ui-drawer-down
+                                        * @member ns.widget.core.Drawer
+                                        */
+                                       down: "ui-drawer-down",
+                                       /**
+                                        * Set the drawer overlay when the drawer is opened.
+                                        * @style ui-drawer-overlay
+                                        * @member ns.widget.core.Drawer
+                                        */
+                                       overlay: "ui-drawer-overlay",
+                                       /**
+                                        * Opens the drawer.
+                                        * @style ui-drawer-open
+                                        * @member ns.widget.core.Drawer
+                                        */
+                                       open: "ui-drawer-open",
+                                       /**
+                                        * Closes the drawer.
+                                        * @style ui-drawer-close
+                                        * @member ns.widget.core.Drawer
+                                        */
+                                       close: "ui-drawer-close"
+                               },
+                               /**
+                                * {Object} Drawer widget prototype
+                                * @member ns.widget.core.Drawer
+                                * @private
+                                * @static
+                                */
+                               prototype = new BaseWidget();
+
+                       Drawer.prototype = prototype;
+                       Drawer.classes = classes;
+
+                       /**
+                        * Unbind drag events
+                        * @method unbindDragEvents
+                        * @param {Object} self
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._unbindDragEvents = function (self, element) {
+                               var overlayElement = self._ui.drawerOverlay;
+
+                               events.disableGesture(element);
+                               events.off(element, "drag dragstart dragend dragcancel swipe swipeleft swiperight swipe vmouseup", self, false);
+                               events.prefixedFastOff(self.element, "transitionEnd", self, false);
+                               events.off(window, "resize", self, false);
+                               if (overlayElement) {
+                                       events.off(overlayElement, "vclick", self, false);
+                               }
+                       }
+
+                       /**
+                        * Bind drag events
+                        * @method bindDragEvents
+                        * @param {Object} self
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._bindDragEvents = function (self, element) {
+                               var overlayElement = self._ui.drawerOverlay;
+
+                               self._eventBoundElement = element;
+
+                               events.enableGesture(
+                                       element,
+
+                                       new Gesture.Drag(),
+                                       new Gesture.Swipe({
+                                               orientation: (self.options.position === "left" || self.options.position === "right") ?
+                                                       Gesture.Orientation.HORIZONTAL : Gesture.Orientation.VERTICAL
+                                       })
+                               );
+
+                               events.on(element,
+                                       "drag dragstart dragend dragcancel swipe swipeleft swiperight swipeup swipedown vmouseup",
+                                       self, false);
+                               events.prefixedFastOn(self.element, "transitionEnd", self, false);
+                               events.on(window, "resize", self, false);
+                               if (overlayElement) {
+                                       events.on(overlayElement, "vclick", self, false);
+                               }
+                       }
+
+                       /**
+                        * Handle events
+                        * @method handleEvent
+                        * @param {Event} event
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "drag":
+                                               self._onDrag(event);
+                                               break;
+                                       case "dragstart":
+                                               self._onDragStart(event);
+                                               break;
+                                       case "dragend":
+                                               self._onDragEnd(event);
+                                               break;
+                                       case "dragcancel":
+                                               self._onDragCancel(event);
+                                               break;
+                                       case "vmouseup":
+                                               self._onMouseup(event);
+                                               break;
+                                       case "swipe":
+                                       case "swipeleft":
+                                       case "swiperight":
+                                       case "swipeup":
+                                       case "swipedown":
+                                               self._onSwipe(event);
+                                               break;
+                                       case "vclick":
+                                               self._onClick(event);
+                                               break;
+                                       case "transitionend":
+                                       case "webkitTransitionEnd":
+                                       case "mozTransitionEnd":
+                                       case "oTransitionEnd":
+                                       case "msTransitionEnd":
+                                               self._onTransitionEnd(event);
+                                               break;
+                                       case "resize":
+                                               self._onResize(event);
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * MouseUp event handler
+                        * @method _onMouseup
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._onMouseup = function () {
+                               var self = this;
+
+                               if (self._state === STATE.SLIDING) {
+                                       self.close();
+                               }
+                       };
+                       /**
+                        * Click event handler
+                        * @method _onClick
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._onClick = function () {
+                               var self = this;
+
+                               if (self._state === STATE.OPENED) {
+                                       self.close();
+                               }
+                       };
+
+                       /**
+                        * Resize event handler
+                        * @method _onResize
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._onResize = function () {
+                               var self = this;
+                               // resize event handler
+
+                               self._refresh();
+                       };
+
+                       /**
+                        * webkitTransitionEnd event handler
+                        * @method _onTransitionEnd
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._onTransitionEnd = function () {
+                               var self = this,
+                                       position = self.options.position,
+                                       drawerOverlay = self._drawerOverlay;
+
+                               if (self._state === STATE.SETTLING) {
+                                       if (self._settlingType === STATE.OPENED) {
+                                               self.trigger(CUSTOM_EVENTS.OPEN, {
+                                                       position: position
+                                               });
+                                               self._setActive(true);
+                                               self._state = STATE.OPENED;
+                                       } else {
+                                               self.close();
+                                               self.trigger(CUSTOM_EVENTS.CLOSE, {
+                                                       position: position
+                                               });
+                                               self._setActive(false);
+                                               self._state = STATE.CLOSED;
+                                               if (drawerOverlay) {
+                                                       drawerOverlay.style.visibility = "hidden";
+                                               }
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Swipe event handler
+                        * @method _onSwipe
+                        * @protected
+                        * @param {Event} event
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype._onSwipe = function (event) {
+                               var self = this,
+                                       direction,
+                                       options = self.options;
+
+                               // Now mobile has two swipe event
+                               if (event.detail) {
+                                       switch (event.detail.direction) {
+                                               case "left" : direction = "right";
+                                                       break;
+                                               case "right" : direction = "left";
+                                                       break;
+                                               case "up" : direction = "down";
+                                                       break;
+                                               case "down" : direction = "up";
+                                                       break;
+                                       }
+                               } else if (event.type === "swiperight") {
+                                       direction = "left";
+                               } else if (event.type === "swipeleft") {
+                                       direction = "right";
+                               } else if (event.type === "swipeup") {
+                                       direction = "down";
+                               } else if (event.type === "swipedown") {
+                                       direction = "up";
+                               }
+
+                               if (options.enable && self._isDrag && options.position === direction) {
+                                       self.open();
+                                       self._isDrag = false;
+                               }
+                       };
+                       /**
+                        * Dragstart event handler
+                        * @method _onDragStart
+                        * @protected
+                        * @param {Event} event
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype._onDragStart = function (event) {
+                               var self = this;
+
+                               if (self._state === STATE.OPENED) {
+                                       return;
+                               }
+                               if (self.options.enable && !self._isDrag && self._state !== STATE.SETTLING && self._checkSideEdge(event)) {
+                                       self._isDrag = true;
+                               } else {
+                                       self.close();
+                               }
+                       };
+                       /**
+                        * Drag event handler
+                        * @method _onDrag
+                        * @protected
+                        * @param {Event} event
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype._onDrag = function (event) {
+                               var self = this,
+                                       deltaX = event.detail.deltaX,
+                                       deltaY = event.detail.deltaY,
+                                       options = self.options,
+                                       translatedX = self._translatedX,
+                                       translatedY = self._translatedY,
+                                       movedX,
+                                       movedY;
+
+                               if (options.enable && self._isDrag && self._state !== STATE.SETTLING) {
+                                       switch (options.position) {
+                                               case "left":
+                                                       movedX = -options.width + deltaX + translatedX;
+                                                       if (movedX < 0) {
+                                                               self._translate(movedX, 0, 0);
+                                                       }
+                                                       break;
+                                               case "right":
+                                                       movedX = window.innerWidth + deltaX - translatedX;
+                                                       if (movedX > 0 && movedX > window.innerWidth - options.width) {
+                                                               self._translate(movedX, 0, 0);
+                                                       }
+                                                       break;
+                                               case "up":
+                                                       movedY = -options.height + deltaY + translatedY;
+                                                       if (movedY < 0) {
+                                                               self._translate(0, movedY, 0);
+                                                       }
+                                                       break;
+                                               case "down":
+                                                       movedY = window.innerHeight + deltaY - translatedY;
+                                                       if (movedY > 0 && movedY > window.innerHeight - options.height) {
+                                                               self._translate(0, movedY, 0);
+                                                       }
+                                                       break;
+                                       }
+                               }
+                       };
+                       /**
+                        * DragEnd event handler
+                        * @method _onDragEnd
+                        * @protected
+                        * @param {Event} event
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype._onDragEnd = function (event) {
+                               var self = this,
+                                       options = self.options,
+                                       detail = event.detail;
+
+                               if (options.enable && self._isDrag) {
+                                       if (options.position === "left" || options.position === "right") {
+                                               if (Math.abs(detail.deltaX) > options.width / 2) {
+                                                       self.open();
+                                               } else if (self._state !== STATE.SETTLING) {
+                                                       self.close();
+                                               }
+                                       }
+                                       if (options.position === "up" || options.position === "down") {
+                                               if (Math.abs(detail.deltaY) > options.height / 2) {
+                                                       self.open();
+                                               } else if (self._state !== STATE.SETTLING) {
+                                                       self.close();
+                                               }
+                                       }
+                               }
+                               self._isDrag = false;
+                       };
+
+                       /**
+                        * DragCancel event handler
+                        * @method _onDragCancel
+                        * @protected
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype._onDragCancel = function () {
+                               var self = this;
+
+                               if (self.options.enable && self._isDrag) {
+                                       self.close();
+                               }
+                               self._isDrag = false;
+                       };
+
+                       /**
+                        * Drawer translate function
+                        * @method _translate
+                        * @param {number} x
+                        * @param {number} y
+                        * @param {number} duration
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._translate = function (x, y, duration) {
+                               var self = this,
+                                       element = self.element;
+
+                               if (self._state !== STATE.SETTLING) {
+                                       self._state = STATE.SLIDING;
+                               }
+
+                               if (duration) {
+                                       utilDOM.setPrefixedStyle(element, "transition", utilDOM.getPrefixedValue("transform " + duration / 1000 + "s ease-out"));
+                               }
+
+                               // there should be a helper for this :(
+                               utilDOM.setPrefixedStyle(element, "transform", "translate3d(" + x + "px, " + y + "px, 0px)");
+                               if (self.options.overlay) {
+                                       self._setOverlay(x, y);
+                               }
+                               if (!duration) {
+                                       self._onTransitionEnd();
+                               }
+
+                       };
+
+                       /**
+                        * Set overlay opacity
+                        * @method _setOverlayOpacity
+                        * @param {number} ratio
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._setOverlayOpacity = function (ratio) {
+                               this._ui.drawerOverlay.style.opacity = 1 - ratio;
+                       };
+
+                       /**
+                        * Set overlay visibility
+                        * @method _setOverlayVisibility
+                        * @param {number} ratio
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._setOverlayVisibility = function (ratio) {
+                               var overlayStyle = this._ui.drawerOverlay.style;
+
+                               if (ratio < 1) {
+                                       overlayStyle.visibility = "visible";
+                               } else {
+                                       overlayStyle.visibility = "hidden";
+                               }
+                       };
+
+                       /**
+                        * Calculation of overlay position and opacity
+                        * depending to touch move
+                        * @method _calcOverlay
+                        * @param {number} x
+                        * @param {number} y
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._calcOverlay = function (x, y) {
+                               var ratio,
+                                       options = this.options,
+                                       absX = Math.abs(x),
+                                       absY = Math.abs(y);
+
+                               if (options.position === "right") {
+                                       ratio = absX / window.innerWidth;
+                               } else if (options.position === "left") {
+                                       ratio = absX / options.width;
+                               } else if (options.position === "down") {
+                                       ratio = absY / window.innerHeight;
+                               } else if (options.position === "up") {
+                                       ratio = absY / options.height;
+                               }
+                               return ratio;
+                       };
+
+                       /**
+                        * Set overlay visibility
+                        * @method _setOverlay
+                        * @param {number} x
+                        * @param {number} y
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._setOverlay = function (x, y) {
+                               var self = this,
+                                       ratio = self._calcOverlay(x, y);
+
+                               self._setOverlayVisibility(ratio);
+                               self._setOverlayOpacity(ratio);
+                       };
+
+                       /**
+                        * Set active status in drawer router
+                        * @method _setActive
+                        * @param {boolean} active
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._setActive = function (active) {
+                               var self = this,
+                                       route = ns.router.Router.getInstance().getRoute("drawer");
+
+                               if (active) {
+                                       route.setActive(self);
+                               } else {
+                                       route.setActive(null);
+                               }
+                       };
+
+                       /**
+                        * Build structure of Drawer widget
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement} Returns built element
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       targetElement;
+
+                               element.classList.add(classes.drawer);
+                               element.style.top = 0;
+                               targetElement = selectors.getClosestBySelector(element, options.drawerTarget);
+
+                               if (targetElement) {
+                                       targetElement.appendChild(element);
+                                       targetElement.style.overflowX = "hidden";
+                               }
+
+                               if (self.options.overlay) {
+                                       ui.drawerOverlay = self._createOverlay(element);
+                                       ui.drawerOverlay.style.visibility = "hidden";
+                               }
+
+                               if (!ui.placeholder) {
+                                       ui.placeholder = document.createComment(element.id + "-placeholder");
+                                       element.parentNode.insertBefore(ui.placeholder, element);
+                               }
+                               ui.targetElement = targetElement;
+                               return element;
+                       };
+
+                       /**
+                        * Initialization of Drawer widget
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui;
+
+                               ui.drawerPage = selectors.getClosestByClass(element, classes.page);
+                               ui.drawerPage.style.overflowX = "hidden";
+                               self._initLayout();
+                               return element;
+                       };
+
+                       /**
+                        * init Drawer widget layout
+                        * @method _initLayout
+                        * @protected
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype._initLayout = function () {
+                               var self = this,
+                                       options = self.options,
+                                       element = self.element,
+                                       elementStyle = element.style,
+                                       ui = self._ui,
+                                       overlayStyle = ui.drawerOverlay ? ui.drawerOverlay.style : null;
+
+                               options.width = options.width || ui.targetElement.offsetWidth;
+                               options.height = options.height || ui.targetElement.offsetHeight;
+
+                               elementStyle.width = (options.width !== 0) ? options.width + "px" : "100%";
+                               elementStyle.height = (options.height !== 0) ? options.height + "px" : "100%";
+                               elementStyle.top = "0";
+
+                               if (overlayStyle) {
+                                       overlayStyle.width = window.innerWidth + "px";
+                                       overlayStyle.height = window.innerHeight + "px";
+                                       overlayStyle.top = 0;
+                               }
+                               if (options.position === "right") {
+                                       element.classList.add(classes.right);
+                                       self._translate(window.innerWidth, 0, 0);
+                               } else if (options.position === "left") {
+                                       element.classList.add(classes.left);
+                                       self._translate(-options.width, 0, 0);
+                               } else if (options.position === "up") {
+                                       element.classList.add(classes.up);
+                                       self._translate(0, -window.innerHeight, 0);
+                               } else if (options.position === "down") {
+                                       element.classList.add(classes.down);
+                                       self._translate(0, options.height, 0);
+                               }
+
+                               self._state = STATE.CLOSED;
+                       };
+
+                       /**
+                        * Provides translation if position is set to right
+                        * @method _translateRight
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._translateRight = function () {
+                               var self = this,
+                                       options = self.options;
+
+                               if (options.position === "right") {
+                                       // If drawer position is right, drawer should be moved right side
+                                       if (self._state === STATE.OPENED) {
+                                               // drawer opened
+                                               self._translate(window.innerWidth - options.width, 0, 0);
+                                       } else {
+                                               // drawer closed
+                                               self._translate(window.innerWidth, 0, 0);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Check dragstart event whether triggered on side edge area or not
+                        * @method _checkSideEdge
+                        * @protected
+                        * @param {Event} event
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype._checkSideEdge = function (event) {
+                               var self = this,
+                                       detail = event.detail,
+                                       eventClientX = detail.pointer.clientX - detail.estimatedDeltaX,
+                                       eventClientY = detail.pointer.clientY - detail.estimatedDeltaY,
+                                       options = self.options,
+                                       position = options.position,
+                                       boundElement = self._eventBoundElement,
+                                       boundElementOffsetWidth = boundElement.offsetWidth,
+                                       boundElementOffsetHeight = boundElement.offsetHeight,
+                                       boundElementRightEdge = boundElement.offsetLeft + boundElementOffsetWidth,
+                                       boundElementDownEdge = boundElement.offsetTop + boundElementOffsetHeight,
+                                       dragStartAreaWidth = boundElementOffsetWidth * options.dragEdge,
+                                       dragStartAreaHeight = boundElementOffsetHeight * options.dragEdge;
+
+                               return (
+                                       (position === "left" && eventClientX > 0 && eventClientX < dragStartAreaWidth) ||
+                                       (position === "right" && eventClientX > boundElementRightEdge - dragStartAreaWidth &&
+                                               eventClientX < boundElementRightEdge) ||
+                                       (position === "up" && eventClientY > 0 && eventClientY < dragStartAreaHeight) ||
+                                       (position === "down" && eventClientY > boundElementDownEdge - dragStartAreaHeight &&
+                                               eventClientY < boundElementDownEdge)
+                               );
+                       };
+                       /**
+                        * Refreshes Drawer widget
+                        * @method _refresh
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._refresh = function () {
+                               // Drawer layout has been set by parent element layout
+                               var self = this;
+
+                               self._translateRight();
+                               self._initLayout();
+                       };
+                       /**
+                        * Creates Drawer overlay element
+                        * @method _createOverlay
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._createOverlay = function (element) {
+                               var overlayElement = document.createElement("div");
+
+                               overlayElement.classList.add(classes.overlay);
+                               element.parentNode.insertBefore(overlayElement, element);
+
+                               return overlayElement;
+                       };
+
+                       /**
+                        * Binds events to a Drawer widget
+                        * @method _bindEvents
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       targetElement = self._ui.targetElement;
+
+                               self._bindDragEvents(self, targetElement);
+                       };
+
+                       /**
+                        * Unbinds events to a Drawer widget
+                        * @method _unbindEvents
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._unbindEvents = function () {
+                               var self = this,
+                                       targetElement = self._ui.targetElement;
+
+                               self._unbindDragEvents(self, targetElement);
+                       };
+
+                       /**
+                        * Enable Drawer widget
+                        * @method _enable
+                        * @protected
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype._enable = function () {
+                               this._oneOption("enable", true);
+                       };
+
+                       /**
+                        * Disable Drawer widget
+                        * @method _disable
+                        * @protected
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype._disable = function () {
+                               this._oneOption("enable", false);
+                       };
+
+                       /**
+                        * Checks Drawer status
+                        * @method isOpen
+                        * @member ns.widget.core.Drawer
+                        * @return {boolean} Returns true if Drawer is open
+                        */
+                       prototype.isOpen = function () {
+                               return (this._state === STATE.OPENED);
+                       };
+
+                       /**
+                        * Opens Drawer widget
+                        * @method open
+                        * @param {number} [duration] Duration for opening, if is not set then method take value from options
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype.open = function (duration) {
+                               var self = this,
+                                       options = self.options,
+                                       drawerClassList = self.element.classList,
+                                       drawerOverlay = self._ui.drawerOverlay;
+
+                               if (self._state !== STATE.OPENED) {
+                                       self._state = STATE.SETTLING;
+                                       self._settlingType = STATE.OPENED;
+                                       duration = duration !== undefined ? duration : options.duration;
+                                       if (drawerOverlay) {
+                                               drawerOverlay.style.visibility = "visible";
+                                       }
+                                       drawerClassList.remove(classes.close);
+                                       drawerClassList.add(classes.open);
+                                       if (options.position === "left") {
+                                               self._translate(0, 0, duration);
+                                       } else if (options.position === "right") {
+                                               self._translate(window.innerWidth - options.width, 0, duration);
+                                       } else if (options.position === "up") {
+                                               self._translate(0, 0, duration);
+                                       } else if (options.position === "down") {
+                                               self._translate(0, window.innerHeight - options.height, duration);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Closes Drawer widget
+                        * @requires mobile wearable
+                        *
+                        *
+                        * @method close
+                        * @param {Object} options This value is router options whether reverse or not.
+                        * @param {number} [duration] Duration for closing, if is not set then method take value from options
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype.close = function (options, duration) {
+                               var self = this,
+                                       reverse = options ? options.reverse : false,
+                                       selfOptions = self.options,
+                                       drawerClassList = self.element.classList;
+
+                               if (self._state !== STATE.CLOSED) {
+                                       if (!reverse && self._state === STATE.OPENED && !ns.getConfig("disableRouter")) {
+                                               // This method was fired by JS code or this widget.
+                                               history.back();
+                                               return;
+                                       }
+                                       self._state = STATE.SETTLING;
+                                       self._settlingType = STATE.CLOSED;
+                                       duration = duration !== undefined ? duration : selfOptions.duration;
+                                       drawerClassList.remove(classes.open);
+                                       drawerClassList.add(classes.close);
+
+                                       if (selfOptions.position === "left") {
+                                               self._translate(-selfOptions.width, 0, duration);
+                                       } else if (selfOptions.position === "right") {
+                                               self._translate(window.innerWidth, 0, duration);
+                                       } else if (selfOptions.position === "up") {
+                                               self._translate(0, -selfOptions.height, duration);
+                                       } else if (selfOptions.position === "down") {
+                                               self._translate(0, window.innerHeight, duration);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Set Drawer drag handler.
+                        * If developer use handler, drag event is bound at handler only.
+                        * @method setDragHandler
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype.setDragHandler = function (element) {
+                               var self = this;
+
+                               self.options.dragEdge = 1;
+                               self._unbindDragEvents(self, self._eventBoundElement);
+                               self._bindDragEvents(self, element);
+                       };
+
+                       /**
+                        * Transition Drawer widget.
+                        * This method use only positive integer number.
+                        * @method transition
+                        * @param {number} position
+                        * @member ns.widget.core.Drawer
+                        */
+                       prototype.transition = function (position) {
+                               var self = this,
+                                       options = self.options;
+
+                               if (options.position === "left") {
+                                       self._translate(-options.width + position, 0, options.duration);
+                                       self._translatedX = position;
+                               } else if (options.position === "right") {
+                                       self._translate(options.width - position, 0, options.duration);
+                                       self._translatedX = position;
+                               }
+                               if (options.position === "up") {
+                                       self._translate(0, -options.height + position, options.duration);
+                                       self._translatedY = position;
+                               } else if (options.position === "down") {
+                                       self._translate(0, options.height - position, options.duration);
+                                       self._translatedY = position;
+                               }
+                       };
+
+                       /**
+                        * Get state of Drawer widget.
+                        */
+                       prototype.getState = function () {
+                               return this._state;
+                       };
+                       /**
+                        * Destroys Drawer widget
+                        * @method _destroy
+                        * @member ns.widget.core.Drawer
+                        * @protected
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       drawerOverlay = ui.drawerOverlay,
+                                       placeholder = ui.placeholder,
+                                       placeholderParent = placeholder.parentNode,
+                                       element = self.element;
+
+                               placeholderParent.insertBefore(element, placeholder);
+                               placeholderParent.removeChild(placeholder);
+
+                               if (drawerOverlay) {
+                                       drawerOverlay.removeEventListener("vclick", self._onClickBound, false);
+                               }
+                               self._unbindEvents();
+                       };
+
+                       Drawer.STATE = STATE;
+
+                       ns.widget.core.Drawer = Drawer;
+
+                       }(window.document, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Drawer Widget
+ * Drawer widget provide creating drawer widget and managing drawer operation.
+ *
+ * @since 2.3
+ * @class ns.widget.mobile.Drawer
+ * @component-selector .ui-drawer, [data-role]="drawer"
+ * @extends ns.widget.core.Drawer
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var CoreDrawer = ns.widget.core.Drawer,
+                               engine = ns.engine,
+                               Drawer = function () {
+                                       CoreDrawer.call(this);
+                               },
+                               prototype = new CoreDrawer();
+
+                       Drawer.prototype = prototype;
+
+                       /**
+                        * Configure Drawer widget
+                        * @method _configure
+                        * @protected
+                        * @member ns.widget.mobile.Drawer
+                        */
+                       prototype._configure = function () {
+                               var self = this;
+                               /**
+                                * Widget options
+                                * @property {string} [options.drawerTarget="ui-page"] Drawer appended target. Value type is CSS selector type.
+                                * @property {string} [options.position="left"] Drawer position. "left" or "right"
+                                * @property {boolean} [options.enable=true] Enable drawer component.
+                                * @property {Number} [options.dragEdge=0.05] Start dragging gesture possible area ratio of target or handler between 0 and 1.
+                                * @member ns.widget.mobile.Drawer
+                                */
+
+                               self.options.dragEdge = 0.05;
+                               self.options.width = (window.screen.width >= 960) ? 360 : // for TV HD+
+                                       0.75 * window.screen.width; // mobile
+                               self.options.height = window.screen.height;
+                       };
+
+                       ns.widget.mobile.Drawer = Drawer;
+                       engine.defineWidget(
+                               "Drawer",
+                               "[data-role='drawer'], .ui-drawer",
+                               [
+                                       "transition",
+                                       "setDragHandler",
+                                       "open",
+                                       "close",
+                                       "isOpen",
+                                       "getState"
+                               ],
+                               Drawer,
+                               "mobile"
+                       );
+
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * # Toggle Switch
+ * Toggle switch component is a common UI element used for binary on/off or true/false data input.
+ *
+ * The toggle switch widget shows a 2-state switch on the screen.
+ * If defined with select type with options it creates toggles
+ * On the toggle its possible to tap one side of the switch.
+ *
+ * We still support toggles defined with select tag for backward compatibility
+ *
+ * ## Default selectors
+ * INPUT tags with _data-role=toggleswitch_ or SELECT tags
+ * with _data-role=toggleswitch_
+ * changed to toggle switch
+ * To add a toggle switch widget to the application, use the following code:
+ *
+ *        @example
+ *        <input type="checkbox" data-role="toggleswitch">
+ *
+ *        @example
+ *        <select name="flip-11" id="flip-11" data-role="toggleswitch">
+ *            <option value="off"></option>
+ *            <option value="on"></option>
+ *        </select>
+ *
+ *        @example
+ *        <select name="flip-11" id="flip-11" data-role="toggleswitch">
+ *            <option value="off">off option</option>
+ *            <option value="on">on option</option>
+ *        </select>
+ *
+ * ## Manual constructor
+ * For manual creation of toggle switch widget you can use constructor of
+ * widget from **tau** namespace:
+ *
+ *        @example
+ *        <select id="toggle" name="flip-11" id="flip-11" data-role="toggleswitch"
+ *        data-mini="true">
+ *            <option value="off"></option>
+ *            <option value="on"></option>
+ *        </select>
+ *        <script>
+ *            var toggleElement = document.getElementById("toggle"),
+ *                toggle = tau.widget.ToggleSwitch(toggleElement);
+ *        </script>
+ *
+ * ## JavaScript API
+ *
+ * ToggleSwitch widget hasn't JavaScript API.
+ *
+ * @since 2.0
+ * @deprecated 1.2
+ * @class ns.widget.mobile.ToggleSwitch
+ * @component-selector .ui-toggleswitch, [data-role]="toggleswitch"
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var engine = ns.engine,
+                               OnOffSwitch = ns.widget.core.OnOffSwitch,
+                               ToggleSwitch = function () {
+                                       // constructor;
+                                       OnOffSwitch.call(this, arguments);
+                               },
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               widgetSelector = "input[data-role='toggleswitch']," +
+                                       "select[data-role='toggleswitch']," +
+                                       "select.ui-toggleswitch," +
+                                       "input.ui-toggleswitch";
+
+                       ToggleSwitch.prototype = new OnOffSwitch();
+                       ns.widget.mobile.ToggleSwitch = ToggleSwitch;
+                       engine.defineWidget(
+                               "ToggleSwitch",
+                               widgetSelector,
+                               [],
+                               ToggleSwitch,
+                               "mobile"
+                       );
+
+                       BaseKeyboardSupport.registerActiveSelector(widgetSelector);
+
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * # Navigation
+ * Navigation component is used inside the header to navigate back and forth according to the navigational history array,
+ * which is created by the application. By clicking a horizontally-listed element on the navigation bar,
+ * the user can move to the target page.
+ *
+ * By clicking horizontally listed element on the Navigation Bar,
+ *  a page is possible to navigate to the target page.
+ *
+ * ##Default selector
+ * You can make the navigation widget as data-role="navigation".
+ * To use *NAV* tag is recommended for semantic understanding.
+ *
+ * ####  Create Navigation Bar using data-role
+ *
+ *             @example
+ *             <div data-role="page" id="pageId">
+ *                     <div data-role="header" data-position="fixed">
+ *                             <h1>title</h1>
+ *                             <nav data-role="navigation" id="navigation"></nav>
+ *                     </div>
+ *                     <div data-role="content"></div>
+ *             </div>
+ *
+ * ##HTML Examples
+ *
+ * ####How to use Navigation Bar in your code
+ *
+ * This component is made to support navigational
+ * indication on panel change mainly. So Navigation Bar is
+ * not only hard to be used alone, but also not efficient with solo usage.
+ *
+ * The essential function of navigation bar is to add navigational item
+ * according to the given element's id. And this component also
+ * provides navigational changes on the click of each item.
+ *
+ *
+ * To create a navigation bar, navigation bar needs to be defined in
+ * your HTMl with 'data-role="navigation"' or 'class="ui-navigation"'.
+ *
+ *             @example
+ *             <div data-role="page" id="navigation-bar">
+ *                     <!-- declare navigation in header -->
+ *                     <div data-role="header" data-position="fixed">
+ *                             <h1>Navigation Bar</h1>
+ *                             <nav data-role="navigation" id="navigation"></nav>
+ *                     </div>
+ *
+ *                     <!-- you can put several panels to move -->
+ *                     <div data-role="content">
+ *                     </div>
+ *             </div>
+ *
+ * @since 2.3
+ * @class ns.widget.mobile.Navigation
+ * @component-selector .ui-navigation, [data-role]="navigation"
+ * @extends ns.widget.BaseWidget
+ * @author Junhyeon Lee <juneh.lee@samsung.com>
+ * @author Maciej Moczulski <m.moczulsku@samsung.com>
+ * @author Hyunkook Cho <hk0713.cho@samsung.com>
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ * @author Heeju Joo <heeju.joo@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Koeun Choi <koeun.choi@samsung.com>
+ * @author Piort Karny <p.karny@samsung.com>
+ * @author Krzysztof Antonszek <k.antonszek@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               engine = ns.engine,
+                               events = ns.event,
+                               selectors = ns.util.selectors,
+                               Navigation = function () {
+                                       var self = this;
+
+                                       BaseKeyboardSupport.call(this);
+                                       self._clickBound = null;
+                                       self._ui = {};
+                                       self._navigationStack = [];
+                               },
+
+                               attributes = {
+                                       POSITION: "data-position"
+                               },
+                               /**
+                                * Dictionary object containing commonly used widget classes
+                                * @property {Object} classes
+                                * @static
+                                * @member ns.widget.mobile.Navigation
+                                */
+                               classes = {
+                                       /**
+                                        * Standard navigation widget
+                                        * @style ui-navigation
+                                        * @member ns.widget.mobile.Navigation
+                                        */
+                                       NAVIGATION: "ui-navigation",
+                                       /**
+                                        * Set a container with navigation widget
+                                        * @style ui-navigation-container
+                                        * @member ns.widget.mobile.Navigation
+                                        */
+                                       NAVIGATION_CONTAINER: "ui-navigation-container",
+                                       /**
+                                        * Set an item of navigation widget
+                                        * @style ui-navigation-item
+                                        * @member ns.widget.mobile.Navigation
+                                        */
+                                       NAVIGATION_ITEM: "ui-navigation-item",
+                                       /**
+                                        * Set navigation widget as active
+                                        * @style ui-navigation-active
+                                        * @member ns.widget.mobile.Navigation
+                                        */
+                                       NAVIGATION_ACTIVE: "ui-navigation-active",
+                                       /**
+                                        * Hide navigation widget
+                                        * @style ui-navigation-hide
+                                        * @member ns.widget.mobile.Navigation
+                                        */
+                                       NAVIGATION_HIDE: "ui-navigator-hide",
+                                       /**
+                                        * Set item to back in navigation widget
+                                        * @style ui-navigation-hide
+                                        * @member ns.widget.mobile.Navigation
+                                        */
+                                       NAVIGATION_BACK: "ui-navigator-back",
+                                       /**
+                                        * Hide item back in navigation widget
+                                        * @style ui-navigation-hide
+                                        * @member ns.widget.mobile.Navigation
+                                        */
+                                       NAVIGATION_BACK_HIDE: "ui-navigator-back-hide",
+                                       /**
+                                        * Set active animation in navigation widget
+                                        * @style ui-navigation-hide
+                                        * @member ns.widget.mobile.Navigation
+                                        */
+                                       NAVIGATION_ACTIVE_ANIMATION: "ui-navigator-active-animation"
+                               },
+                               prototype = new BaseWidget();
+
+                       Navigation.prototype = prototype;
+                       Navigation.classes = classes;
+                       Navigation.attributes = attributes;
+
+                       /**
+                        * Navigation navigateTrigger function
+                        * @method navigateTrigger
+                        * @private
+                        * @static
+                        * @param {event} event
+                        * @member ns.widget.mobile.Navigation
+                        */
+                       function onClick(event) {
+                               var self = this,
+                                       target = selectors.getClosestByClass(event.target, classes.NAVIGATION_ITEM),
+                                       position = target && parseInt(target.getAttribute(attributes.POSITION), 10),
+                                       stack = self._navigationStack,
+                                       id = stack[position],
+                                       toRemoveLength = stack.length - 1 - position;
+
+                               if (target) {
+                                       setTimeout(function () {
+                                               if (!target.classList.contains(classes.NAVIGATION_ACTIVE) && stack[stack.length - 1] !== id) {
+                                                       self.pop(toRemoveLength);
+                                                       self.trigger("navigate", {
+                                                               id: id,
+                                                               //element Id to move
+                                                               position: position
+                                                       });
+                                               }
+                                       }, 0);
+                               }
+                       }
+
+                       /**
+                        * Build structure of Navigation widget
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.mobile.Navigation
+                        */
+                       prototype._build = function (element) {
+                               var container;
+
+                               element.classList.add(classes.NAVIGATION);
+                               container = document.createElement("ul");
+                               container.classList.add(classes.NAVIGATION_CONTAINER);
+
+                               this._ui.container = container;
+
+                               element.appendChild(container);
+                               return element;
+                       };
+
+                       /**
+                        * Bind events of Navigation widget
+                        * @method _bindEvents
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.mobile.Navigation
+                        */
+                       prototype._bindEvents = function (element) {
+                               var self = this;
+
+                               self._clickBound = onClick.bind(self);
+                               element.addEventListener("vclick", self._clickBound, false);
+                       };
+
+
+                       /**
+                        * Initiate creating navigation bar in old version way
+                        * @method create
+                        * @public
+                        * @deprecated
+                        * @member ns.widget.mobile.Navigation
+                        */
+                       prototype.create = function () {
+                               ns.warn("Create method is deprecated because with 'create' method," +
+                               "it is hard to meet the newly changed Navigation function. " +
+                               "To handle Navigation Bar, please utilize 'push' method with " +
+                               "and 'panelChanger' component, instead.");
+                       };
+
+                       /**
+                        * Remove navigation bar item or items
+                        * @param {number} count
+                        * @method pop
+                        * @member ns.widget.mobile.Navigation
+                        */
+                       prototype.pop = function (count) {
+                               var self = this,
+                                       container = self._ui.container,
+                                       stack = self._navigationStack,
+                                       lastChild = container.lastChild,
+                                       lastChildClassList = lastChild && lastChild.classList,
+                                       previousLastChildClassList = lastChild && lastChild.previousElementSibling && lastChild.previousElementSibling.classList;
+
+                               if (count === undefined) {
+                                       count = 1;
+                               }
+
+                               if (lastChildClassList) {
+                                       lastChildClassList.add(classes.NAVIGATION_HIDE);
+                                       if (previousLastChildClassList) {
+                                               previousLastChildClassList.add(classes.NAVIGATION_BACK);
+                                               previousLastChildClassList.add(classes.NAVIGATION_ACTIVE);
+                                               events.one(lastChild, "animationend, webkitAnimationEnd", function () {
+                                                       container.removeChild(container.lastChild);
+                                                       lastChildClassList.remove(classes.NAVIGATION_BACK);
+                                                       if (count > 1) {
+                                                               self.pop(count - 1);
+                                                       }
+                                               });
+                                       }
+                                       stack.pop();
+                               }
+                       };
+
+                       /**
+                        * Add navigation bar item only one at a time
+                        * @method push
+                        * @param {string} id
+                        * @member ns.widget.mobile.Navigation
+                        */
+                       prototype.push = function (id) {
+                               var self = this,
+                                       element = self.element,
+                                       stack = self._navigationStack,
+                                       container = self._ui.container,
+                                       itemLength = container.childElementCount,
+                                       lastChild = container.lastElementChild,
+                                       lastChildClassList = lastChild && lastChild.classList,
+                                       listClassList = null,
+                                       list,
+                                       arrow,
+                                       text;
+
+                               stack.push(id);
+                               if (itemLength > 0) {
+                                       lastChildClassList.add(classes.NAVIGATION_BACK_HIDE);
+                                       events.one(lastChild, "animationend webkitAnimationEnd", function () {
+                                               //both animation end events should trigger right after push but often only one triggered
+                                               //and second triggered after using pop method and thus removed unintentionally useful classes
+                                               if (lastChild !== self._ui.container.lastElementChild) {
+                                                       lastChildClassList.remove(classes.NAVIGATION_BACK_HIDE);
+                                                       lastChildClassList.remove(classes.NAVIGATION_ACTIVE);
+                                               }
+                                       });
+                               }
+
+                               list = document.createElement("li");
+                               list.setAttribute(attributes.POSITION, itemLength);
+                               listClassList = list.classList;
+                               listClassList.add(classes.NAVIGATION_ITEM);
+
+                               if (itemLength > 0) {
+                                       arrow = document.createElement("span");
+                                       arrow.classList.add("ui-arrow");
+                                       list.appendChild(arrow);
+                               }
+
+                               text = document.createElement("a");
+                               text.classList.add("ui-text");
+                               text.setAttribute("href", "#" + id);
+                               text.innerHTML = id;
+                               list.appendChild(text);
+
+                               listClassList.add(classes.NAVIGATION_ACTIVE);
+                               listClassList.add(classes.NAVIGATION_ACTIVE_ANIMATION);
+                               events.one(list, "animationend webkitAnimationEnd", function () {
+                                       listClassList.remove(classes.NAVIGATION_ACTIVE_ANIMATION);
+                               });
+
+                               container.appendChild(list);
+                               if (container.offsetWidth > element.offsetWidth) {
+                                       element.scrollLeft = container.offsetWidth - element.offsetWidth;
+                               }
+                       };
+
+                       /**
+                        * Destroy Navigation widget
+                        * @method _destroy
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.mobile.Navigation
+                        */
+                       prototype._destroy = function (element) {
+                               var self = this;
+
+                               element.removeEventListener("vclick", self._clickBound, false);
+                               element.removeChild(self._ui.container);
+                               self._clickBound = null;
+                               self._ui = null;
+                               self._navigationStack = null;
+                       };
+
+                       BaseKeyboardSupport.registerActiveSelector(".ui-navigation .ui-text");
+
+                       ns.widget.mobile.Navigation = Navigation;
+                       engine.defineWidget(
+                               "Navigation",
+                               "[data-role='navigation'], .ui-navigation",
+                               [
+                                       "push",
+                                       "pop",
+                                       "create"
+                               ],
+                               Navigation,
+                               "mobile"
+                       );
+
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function (ns) {
+       "use strict";
+                               /** @namespace ns.widget.wearable */
+                       ns.widget.core.indexscrollbar = ns.widget.core.indexscrollbar || {};
+                       }(ns));
+
+/*global define, ns, document, window */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #IndexBar widget
+ * Widget creates bar with index.
+ *
+ * @internal
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @class ns.widget.wearable.indexscrollbar.IndexBar
+ */
+(function (document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               utilsDOM = ns.util.DOM,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport;
+
+                       function IndexBar(element, options) {
+                               this.element = element;
+                               this.options = utilsObject.merge(options, this._options, false);
+                               this.container = this.options.container;
+
+                               BaseKeyboardSupport.call(self);
+
+                               this.indices = {
+                                       original: this.options.index,
+                                       merged: []
+                               };
+
+                               this._init();
+
+                               return this;
+                       }
+
+                       IndexBar.prototype = {
+                               _options: {
+                                       container: null,
+                                       offsetLeft: 0,
+                                       index: [],
+                                       verticalCenter: false,
+                                       moreChar: "*",
+                                       moreCharLineHeight: 9,
+                                       indexHeight: 41,
+                                       selectedClass: "ui-state-selected",
+                                       ulClass: null,
+                                       maxIndexLen: 0
+                               },
+                               _init: function () {
+                                       this.indices.original = this.options.index;
+                                       this.indexLookupTable = [];
+                                       this.indexElements = null;
+                                       this.selectedIndex = -1;
+                                       this.visiblity = "hidden";
+
+                                       this._setMaxIndexLen();
+                                       this._makeMergedIndices();
+                                       this._drawDOM();
+                                       this._appendToContainer();
+                                       if (this.options.verticalCenter) {
+                                               this._adjustVerticalCenter();
+                                       }
+                                       this._setIndexCellInfo();
+                               },
+
+                               _clear: function () {
+                                       while (this.element.firstChild) {
+                                               this.element.removeChild(this.element.firstChild);
+                                       }
+
+                                       this.indices.merged.length = 0;
+                                       this.indexLookupTable.length = 0;
+                                       this.indexElements = null;
+                                       this.selectedIndex = -1;
+                                       this.visiblity = null;
+                               },
+
+                               /**
+                                * Refreshes widget.
+                                * @method refresh
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               refresh: function () {
+                                       this._clear();
+                                       this._init();
+                               },
+
+                               /**
+                                * Destroys widget.
+                                * @method destroy
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               destroy: function () {
+                                       this._clear();
+                               },
+
+                               /**
+                                * Shows widget.
+                                * @method show
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               show: function () {
+                                       this.visibility = "visible";
+                                       this.element.style.visibility = this.visibility;
+                               },
+
+                               /**
+                                * Hides widget.
+                                * @method hide
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               hide: function () {
+                                       this.visibility = "hidden";
+                                       this.element.style.visibility = this.visibility;
+                               },
+
+                               /**
+                                * Get if the visibility status is shown or not
+                                * @method isShown
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               isShown: function () {
+                                       return "visible" === this.visibility;
+                               },
+
+                               _setMaxIndexLen: function () {
+                                       var maxIndexLen,
+                                               self = this,
+                                               options = self.options,
+                                               container = self.container,
+                                               indexHeight = options.indexHeight,
+                                               containerHeight = container.offsetHeight;
+
+                                       maxIndexLen = Math.floor(containerHeight / indexHeight);
+                                       if (maxIndexLen > 0 && maxIndexLen % 2 === 0) {
+                                               maxIndexLen -= 1;       // Ensure odd number
+                                       }
+                                       options.maxIndexLen = options.maxIndexLen > 0 ? Math.min(maxIndexLen, options.maxIndexLen) : maxIndexLen;
+
+                               },
+
+                               _makeMergedIndices: function () {
+                                       var origIndices = this.indices.original,
+                                               origIndexLen = origIndices.length,
+                                               visibleIndexLen = Math.min(this.options.maxIndexLen, origIndexLen),
+                                               totalLeft = origIndexLen - visibleIndexLen,
+                                               nIndexPerItem = parseInt(totalLeft / parseInt(visibleIndexLen / 2, 10), 10),
+                                               leftItems = totalLeft % parseInt(visibleIndexLen / 2, 10),
+                                               indexItemSize = [],
+                                               mergedIndices = [],
+                                               i,
+                                               len,
+                                               position = 0;
+
+                                       for (i = 0, len = visibleIndexLen; i < len; i++) {
+                                               indexItemSize[i] = 1;
+                                               if (i % 2) {    // omit even numbers
+                                                       indexItemSize[i] += nIndexPerItem + (leftItems-- > 0 ? 1 : 0);
+                                               }
+                                               position += indexItemSize[i];
+                                               mergedIndices.push({
+                                                       start: position - 1,
+                                                       length: indexItemSize[i]
+                                               });
+                                       }
+                                       this.indices.merged = mergedIndices;
+                               },
+
+                               _drawDOM: function () {
+                                       var origIndices = this.indices.original,
+                                               indices = this.indices.merged,
+                                               indexLen = indices.length,
+                                               indexHeight = this.options.indexHeight,
+                                               moreChar = this.options.moreChar,
+                                               // Height of the last index is total height - all other indexes
+                                               lastElementHeight = this.container.clientHeight - ((indexLen - 1) * indexHeight),
+                                               addMoreCharLineHeight = this.options.moreCharLineHeight,
+                                               text,
+                                               frag,
+                                               li,
+                                               a,
+                                               i,
+                                               m;
+
+                                       frag = document.createDocumentFragment();
+                                       for (i = 0; i < indexLen; i++) {
+                                               m = indices[i];
+                                               text = m.length === 1 ? origIndices[m.start] : moreChar;
+                                               a = document.createElement("a");
+                                               li = document.createElement("li");
+
+                                               a.innerText = text.toUpperCase();
+                                               a.setAttribute("href", "#" + text.toUpperCase());
+                                               li.appendChild(a);
+
+                                               li.style.height = ((i === indexLen - 1) ? lastElementHeight : indexHeight) + "px";
+                                               li.style.lineHeight = text === moreChar ? indexHeight + addMoreCharLineHeight + "px" : indexHeight + "px";
+
+                                               frag.appendChild(li);
+                                       }
+                                       this.element.appendChild(frag);
+
+                                       if (this.options.ulClass) {
+                                               this.element.classList.add(this.options.ulClass);
+                                       }
+                               },
+
+                               _adjustVerticalCenter: function () {
+                                       var nItem = this.indices.merged.length,
+                                               totalIndexLen = nItem * this.options.indexHeight,
+                                               vPadding = parseInt((this.container.offsetHeight - totalIndexLen) / 2, 10);
+
+                                       this.element.style.paddingTop = vPadding + "px";
+                               },
+
+                               _appendToContainer: function () {
+                                       var self = this,
+                                               options = self.options,
+                                               element = self.element,
+                                               container = self.container,
+                                               elementStyle = element.style,
+                                               divWithMargin = document.createElement("div"),
+                                               distanceFromBottom = options.paddingBottom + "px";
+
+                                       container.appendChild(element);
+                                       elementStyle.left = options.offsetLeft + "px";
+
+                                       if (options.paddingBottom) {
+                                               elementStyle.paddingBottom = distanceFromBottom;
+                                               divWithMargin.classList.add("ui-indexscrollbar-margin");
+                                               divWithMargin.style.height = distanceFromBottom;
+                                               container.appendChild(divWithMargin);
+                                       }
+                               },
+
+                               /**
+                                * Sets padding top for element.
+                                * @method setPaddingTop
+                                * @param {number} paddingTop
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               setPaddingTop: function (paddingTop) {
+                                       var height = this.element.clientHeight,
+                                               oldPaddingTop = this.element.style.paddingTop,
+                                               containerHeight = this.container.clientHeight;
+
+                                       if (oldPaddingTop === "") {
+                                               oldPaddingTop = 0;
+                                       } else {
+                                               oldPaddingTop = parseInt(oldPaddingTop, 10);
+                                       }
+
+                                       height = height - oldPaddingTop;
+
+                                       if (height > containerHeight) {
+                                               paddingTop -= (paddingTop + height - containerHeight);
+                                       }
+                                       this.element.style.paddingTop = paddingTop + "px";
+
+                                       this._setIndexCellInfo();       // update index cell info
+                               },
+
+                               /**
+                                * Returns element's offsetTop of given index.
+                                * @method getOffsetTopByIndex
+                                * @param {number} index
+                                * @return {number}
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               getOffsetTopByIndex: function (index) {
+                                       var cellIndex = this.indexLookupTable[index].cellIndex,
+                                               el = this.indexElements[cellIndex],
+                                               offsetTop = el.offsetTop;
+
+                                       return offsetTop;
+                               },
+
+                               _setIndexCellInfo: function () {
+                                       var element = this.element,
+                                               mergedIndices = this.indices.merged,
+                                               containerOffsetTop = utilsDOM.getElementOffset(this.container).top,
+                                               listItems = this.element.querySelectorAll("LI"),
+                                               lookupTable = [];
+
+                                       [].forEach.call(listItems, function (node, idx) {
+                                               var m = mergedIndices[idx],
+                                                       i = m.start,
+                                                       len = i + m.length,
+                                                       top = containerOffsetTop + node.offsetTop,
+                                                       height = node.offsetHeight / m.length;
+
+                                               for (; i < len; i++) {
+                                                       lookupTable.push({
+                                                               cellIndex: idx,
+                                                               top: top,
+                                                               range: height
+                                                       });
+                                                       top += height;
+                                               }
+                                       });
+                                       this.indexLookupTable = lookupTable;
+                                       this.indexElements = element.children;
+                               },
+
+                               /**
+                                * Returns index for given position.
+                                * @method getIndexByPosition
+                                * @param {number} posY
+                                * @return {number}
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               getIndexByPosition: function (posY) {
+                                       var table = this.indexLookupTable,
+                                               info,
+                                               i,
+                                               len,
+                                               range;
+
+                                       // boundary check
+                                       if (table[0]) {
+                                               info = table[0];
+                                               if (posY < info.top) {
+                                                       return 0;
+                                               }
+                                       }
+                                       if (table[table.length - 1]) {
+                                               info = table[table.length - 1];
+                                               if (posY >= info.top + info.range) {
+                                                       return table.length - 1;
+                                               }
+                                       }
+                                       for (i = 0, len = table.length; i < len; i++) {
+                                               info = table[i];
+                                               range = posY - info.top;
+                                               if (range >= 0 && range < info.range) {
+                                                       return i;
+                                               }
+                                       }
+                                       return 0;
+                               },
+
+                               /**
+                                * Returns value for given index.
+                                * @method getValueByIndex
+                                * @param {number} idx
+                                * @return {number}
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               getValueByIndex: function (idx) {
+                                       if (idx < 0) {
+                                               idx = 0;
+                                       }
+                                       return this.indices.original[idx];
+                               },
+
+                               /**
+                                * Select given index
+                                * @method select
+                                * @param {number} idx
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               select: function (idx) {
+                                       var cellIndex,
+                                               eCell;
+
+                                       this.clearSelected();
+
+                                       if (this.selectedIndex === idx) {
+                                               return;
+                                       }
+                                       this.selectedIndex = idx;
+
+                                       cellIndex = this.indexLookupTable[idx].cellIndex;
+                                       eCell = this.indexElements[cellIndex];
+                                       eCell.classList.add(this.options.selectedClass);
+                               },
+
+                               /**
+                                * Clears selected class.
+                                * @method clearSelected
+                                * @member ns.widget.wearable.indexscrollbar.IndexBar
+                                */
+                               clearSelected: function () {
+                                       var el = this.element,
+                                               selectedClass = this.options.selectedClass,
+                                               selectedElement = el.querySelectorAll("." + selectedClass);
+
+                                       [].forEach.call(selectedElement, function (node) {
+                                               node.classList.remove(selectedClass);
+                                       });
+                                       this.selectedIndex = -1;
+                               }
+                       };
+
+                       ns.widget.core.indexscrollbar.IndexBar = IndexBar;
+
+                       }(window.document, ns));
+
+/*global define, ns, document, window */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #IndexIndicator widget
+ * Class creates index indicator.
+ *
+ * @internal
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @class ns.widget.wearable.indexscrollbar.IndexIndicator
+ */
+(function (document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               events = ns.event;
+
+                       /**
+                        * block 'unexpected bouncing effect' on indexscroller indicator.
+                        * @param {Event} event
+                        */
+                       function blockEvent(event) {
+                               event.preventDefault();
+                               event.stopPropagation();
+                       }
+
+                       function IndexIndicator(element, options) {
+                               this.element = element;
+                               this.options = utilsObject.merge(options, this._options, false);
+                               this.value = null;
+
+                               this._init();
+
+                               return this;
+                       }
+
+                       IndexIndicator.prototype = {
+                               _options: {
+                                       className: "ui-indexscrollbar-indicator",
+                                       selectedClass: "ui-selected",
+                                       alignTo: "container",
+                                       container: null
+                               },
+                               _init: function () {
+                                       var self = this,
+                                               options = self.options,
+                                               element = self.element;
+
+                                       element.className = options.className;
+                                       element.innerHTML = "<span></span>";
+                                       events.on(element, ["touchstart", "touchmove"], blockEvent, false);
+
+
+                                       // Add to DOM tree
+                                       options.referenceElement.parentNode.insertBefore(element, options.referenceElement);
+                                       self.fitToContainer();
+                               },
+
+                               /**
+                                * Fits size to container.
+                                * @method fitToContainer
+                                * @param {HTMLElement} alignTo align indicator position relative to particular element
+                                * @member ns.widget.wearable.indexscrollbar.IndexIndicator
+                                */
+                               fitToContainer: function (alignTo) {
+                                       var self = this,
+                                               element = self.element,
+                                               style = element.style,
+                                               options = self.options,
+                                               container = options.container,
+                                               containerRect = container.getBoundingClientRect();
+
+                                       alignTo = alignTo || options.alignTo;
+
+                                       style.width = containerRect.width + "px";
+                                       if (alignTo === "container") {
+                                               style.height = containerRect.height + "px";
+                                       } else {
+                                               style.height = (containerRect.height + containerRect.top) + "px";
+                                       }
+
+
+                                       style.top = ((alignTo === "container") ? containerRect.top : 0) + "px";
+                                       style.left = containerRect.left + "px";
+                               },
+
+                               /**
+                                * Sets value of widget.
+                                * @method setValue
+                                * @param {string} value
+                                * @member ns.widget.wearable.indexscrollbar.IndexIndicator
+                                */
+                               setValue: function (value) {
+                                       var selected = "",
+                                               remained = "";
+
+                                       this.value = value;     // remember value
+                                       value = value.toUpperCase();
+
+                                       selected = value.substr(value.length - 1);
+                                       remained = value.substr(0, value.length - 1);
+
+                                       this.element.firstChild.innerHTML = "<span>" + remained + "</span><span class=\"ui-selected\">" +
+                                               selected + "</span>";   // Set indicator text
+                               },
+
+                               /**
+                                * Shows widget.
+                                * @method show
+                                * @member ns.widget.wearable.indexscrollbar.IndexIndicator
+                                */
+                               show: function () {
+                                       //this.element.style.visibility="visible";
+                                       this.element.style.display = "block";
+                               },
+
+                               /**
+                                * Hides widget.
+                                * @method hide
+                                * @member ns.widget.wearable.indexscrollbar.IndexIndicator
+                                */
+                               hide: function () {
+                                       this.element.style.display = "none";
+                               },
+
+                               /**
+                                * Destroys widget.
+                                * @method destroy
+                                * @member ns.widget.wearable.indexscrollbar.IndexIndicator
+                                */
+                               destroy: function () {
+                                       var element = this.element;
+
+                                       while (element.firstChild) {
+                                               element.removeChild(element.firstChild);
+                                       }
+                                       events.off(element, ["touchstart", "touchmove"], blockEvent, false);
+                                       this.element = null;    // unreference element
+
+                               }
+                       };
+                       ns.widget.core.indexscrollbar.IndexIndicator = IndexIndicator;
+                       }(window.document, ns));
+
+/*global define, ns, document, window */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * #Index Scrollbar
+ * Shows an index scroll bar with indices, usually for the list.
+ *
+ * The index scroll bar widget shows on the screen a scrollbar with indices,
+ * and fires a select event when the index characters are clicked.
+ * The following table describes the supported index scroll bar APIs.
+ *
+ * ## Manual constructor
+ * For manual creation of widget you can use constructor of widget from **tau** namespace:
+ *
+ *        @example
+ *        var indexscrollbarElement = document.getElementById('indexscrollbar'),
+ *            indexscrollbar = tau.widget.IndexScrollbar(IndexScrollbar, {index: "A,B,C"});
+ *
+ * Constructor has one require parameter **element** which are base **HTMLElement** to create widget.
+ * We recommend get this element by method *document.getElementById*. Second parameter is **options**
+ * and it is a object with options for widget.
+ *
+ * To add an IndexScrollbar widget to the application, use the following code:
+ *
+ *      @example
+ *      <div id="foo" class="ui-indexscrollbar" data-index="A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z"></div>
+ *      <script>
+ *          (function() {
+ *              var elem = document.getElementById("foo");
+ *              tau.widget.IndexScrollbar(elem);
+ *              elem.addEventListener("select", function( event ) {
+ *                  var index = event.detail.index;
+ *                  console.log(index);
+ *              });
+ *          }());
+ *      </script>
+ *
+ * The index value can be retrieved by accessing event.detail.index property.
+ *
+ * In the following example, the list scrolls to the position of the list item defined using
+ * the li-divider class, selected by the index scroll bar:
+ *
+ *      @example
+ *         <div id="pageIndexScrollbar" class="ui-page">
+ *             <header class="ui-header">
+ *                 <h2 class="ui-title">IndexScrollbar</h2>
+ *             </header>
+ *             <section class="ui-content">
+ *                 <div style="overflow-y:scroll;">
+ *                     <div id="indexscrollbar1"
+ *                          class="ui-indexscrollbar"
+ *                          data-index="A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z">
+ *                     </div>
+ *                     <ul class="ui-listview" id="list1">
+ *                         <li class="li-divider">A</li>
+ *                         <li>Anton</li>
+ *                         <li>Arabella</li>
+ *                         <li>Art</li>
+ *                         <li class="li-divider">B</li>
+ *                         <li>Barry</li>
+ *                         <li>Bibi</li>
+ *                         <li>Billy</li>
+ *                         <li>Bob</li>
+ *                         <li class="li-divider">D</li>
+ *                         <li>Daisy</li>
+ *                         <li>Derek</li>
+ *                         <li>Desmond</li>
+ *                     </ul>
+ *                 </div>
+ *             </section>
+ *             <script>
+ *                 (function () {
+ *                     var page = document.getElementById("pageIndexScrollbar");
+ *                     page.addEventListener("pagecreate", function () {
+ *                         var elem = document.getElementById("indexscrollbar1"), // Index scroll bar element
+ *                                 elList = document.getElementById("list1"), // List element
+ *                                 elDividers = elList.getElementsByClassName("li-divider"), // List items (dividers)
+ *                                 elScroller = elList.parentElement, // List's parent item (overflow-y:scroll)
+ *                                 dividers = {}, // Collection of list dividers
+ *                                 indices = [], // List of index
+ *                                 elDivider,
+ *                                 i, idx;
+ *
+ *                         // For all list dividers
+ *                         for (i = 0; i < elDividers.length; i++) {
+ *                             // Add the list divider elements to the collection
+ *                             elDivider = elDividers[i];
+ *                             // li element having the li-divider class
+ *                             idx = elDivider.innerText;
+ *                             // Get a text (index value)
+ *                             dividers[idx] = elDivider;
+ *                             // Remember the element
+ *
+ *                             // Add the index to the index list
+ *                             indices.push(idx);
+ *                         }
+ *
+ *                         // Change the data-index attribute to the indexscrollbar element
+ *                         // before initializing IndexScrollbar widget
+ *                         elem.setAttribute("data-index", indices.join(","));
+ *
+ *                         // Create index scroll bar
+ *                         tau.IndexScrollbar(elem);
+ *
+ *                         // Bind the select callback
+ *                         elem.addEventListener("select", function (ev) {
+ *                             var elDivider,
+ *                                     idx = ev.detail.index;
+ *                             elDivider = dividers[idx];
+ *                             if (elDivider) {
+ *                                 // Scroll to the li-divider element
+ *                                 elScroller.scrollTop = elDivider.offsetTop - elScroller.offsetTop;
+ *                             }
+ *                         });
+ *                     });
+ *                 }());
+ *             </script>
+ *         </div>
+ *
+ * The following example uses the supplementScroll argument, which shows a level 2 index scroll bar.
+ * The application code must contain a level 2 index array for each level 1 index character.
+ * The example shows a way to analyze list items and create a dictionary (secondIndex) for level 1
+ * indices for the index scroll bar, and a dictionary (keyItem) for moving list items at runtime:
+ *
+ *      @example
+ *         <div id="indexscrollbar2" class="ui-indexscrollbar"
+ *              data-index="A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z">
+ *         </div>
+ *         <ul class="ui-listview" id="iBar2_list2">
+ *             <li>Anton</li>
+ *             <li>Arabella</li>
+ *             <li>Art</li>
+ *             <li>Barry</li>
+ *             <li>Bibi</li>
+ *             <li>Billy</li>
+ *             <li>Bob</li>
+ *             <li>Carry</li>
+ *             <li>Cibi</li>
+ *             <li>Daisy</li>
+ *             <li>Derek</li>
+ *             <li>Desmond</li>
+ *         </ul>
+ *
+ *         <script>
+ *             (function () {
+ *                 var page = document.getElementById("pageIndexScrollbar2"),
+ *                         isb,
+ *                         index = [],
+ *                         supIndex = {},
+ *                         elIndex = {};
+ *                 page.addEventListener("pageshow", function () {
+ *                     var elisb = document.getElementById("indexscrollbar2"),
+ *                             elList = document.getElementById("iBar2_list2"), // List element
+ *                             elItems = elList.children,
+ *                             elScroller = elList.parentElement, // Scroller (overflow-y:hidden)
+ *                             indexData = getIndexData(
+ *                                     {
+ *                                         array: elItems,
+ *                                         getTextValue: function (array, i) {
+ *                                             return array[i].innerText;
+ *                                         }
+ *                                     });
+ *
+ *                     function getIndexData(options) {
+ *                         var array = options.array,
+ *                                 getTextValue = options.getTextValue,
+ *                                 item,
+ *                                 text,
+ *                                 firstIndex = [],
+ *                                 secondIndex = {},
+ *                                 keyItem = {},
+ *                                 c1 = null,
+ *                                 c2 = null,
+ *                                 i;
+ *
+ *                         for (i = 0; i < array.length; i++) {
+ *                             item = array[i];
+ *                             text = getTextValue(array, i);
+ *                             if (text.length > 0) {
+ *                                 if (!c1 || c1 !== text[0]) {
+ *                                     // New c1
+ *                                     c1 = text[0];
+ *                                     firstIndex.push(c1);
+ *                                     keyItem[c1] = item;
+ *                                     secondIndex[c1] = [];
+ *                                     c2 = text[1];
+ *                                     if (c2) {
+ *                                         secondIndex[c1].push(c2);
+ *                                     }
+ *                                     else {
+ *                                         c2 = '';
+ *                                     }
+ *                                     keyItem[c1 + c2] = item;
+ *                                 }
+ *                                 else {
+ *                                     // Existing c1
+ *                                     if (c2 !== text[1]) {
+ *                                         c2 = text[1];
+ *                                         secondIndex[c1].push(c2);
+ *                                         keyItem[c1 + c2] = item;
+ *                                     }
+ *                                 }
+ *                             }
+ *                         }
+ *                         return {
+ *                             firstIndex: firstIndex,
+ *                             secondIndex: secondIndex,
+ *                             keyItem: keyItem
+ *                         };
+ *                     }
+ *
+ *                     // Update the data-index attribute to the indexscrollbar element, with the index list above
+ *                     elisb.setAttribute("data-index", indexData.firstIndex);
+ *                     // Create IndexScrollbar
+ *                     isb = new tau.IndexScrollbar(elisb, {
+ *                         index: indexData.firstIndex,
+ *                         supplementaryIndex: function (firstIndex) {
+ *                             return indexData.secondIndex[firstIndex];
+ *                         }
+ *                     });
+ *                     // Bind the select callback
+ *                     elisb.addEventListener("select", function (ev) {
+ *                         var el,
+ *                             index = ev.detail.index;
+ *                         el = indexData.keyItem[index];
+ *                         if (el) {
+ *                             // Scroll to the li-divider element
+ *                             elScroller.scrollTop = el.offsetTop - elScroller.offsetTop;
+ *                         }
+ *                     });
+ *                 });
+ *                 page.addEventListener("pagehide", function () {
+ *                     console.log('isb2:destroy');
+ *                     isb.destroy();
+ *                     index.length = 0;
+ *                     supIndex = {};
+ *                     elIndex = {};
+ *                 });
+ *             }());
+ *         </script>
+ *
+ * ##Options for widget
+ *
+ * Options for widget can be defined as _data-..._ attributes or give as parameter in constructor.
+ *
+ * You can change option for widget using method **option**.
+ *
+ * ##Methods
+ *
+ * To call method on widget you can use tau API:
+ *
+ * First API is from tau namespace:
+ *
+ *        @example
+ *        var indexscrollbarElement = document.getElementById('indexscrollbar'),
+ *            indexscrollbar = tau.widget.IndexScrollbar(indexscrollbarElement);
+ *
+ *        indexscrollbar.methodName(methodArgument1, methodArgument2, ...);
+ *
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Jadwiga Sosnowska <j.sosnowska@samsung.com>
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ * @class ns.widget.core.IndexScrollbar
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var IndexScrollbar = function () {
+                                       var self = this;// Support calling without 'new' keyword
+
+                                       self.indicator = null;
+                                       self.indexBar1 = null;  // First IndexBar. Always shown.
+                                       self.indexBar2 = null;  // 2-depth IndexBar. shown if needed.
+
+                                       self._ui = {};
+
+                                       self.index = null;
+                                       self.touchAreaOffsetLeft = 0;
+                                       self.indexElements = null;
+                                       self.selectEventTriggerTimeoutId = null;
+                                       self.ulMarginTop = 0;
+
+                                       self.eventHandlers = {};
+
+                               },
+                               BaseWidget = ns.widget.BaseWidget,
+                               /**
+                                * Alias for class {@link ns.event}
+                                * @property {Object} events
+                                * @member ns.widget.core.IndexScrollbar
+                                * @private
+                                * @static
+                                */
+                               events = ns.event,
+                               selectors = ns.util.selectors,
+                               /**
+                                * Alias for class {@link ns.util.object}
+                                * @property {Object} utilsObject
+                                * @member ns.widget.core.IndexScrollbar
+                                * @private
+                                * @static
+                                */
+                               utilsObject = ns.util.object,
+                               /**
+                                * Alias for class ns.util.DOM
+                                * @property {ns.util.DOM} doms
+                                * @member ns.widget.wearable.IndexScrollbar
+                                * @private
+                                * @static
+                                */
+                               doms = ns.util.DOM,
+
+                               IndexBar = ns.widget.core.indexscrollbar.IndexBar,
+                               IndexIndicator = ns.widget.core.indexscrollbar.IndexIndicator,
+                               Page = ns.widget.core.Page,
+                               pageSelector = ns.engine.getWidgetDefinition("Page").selector,
+                               EventType = {
+                                       /**
+                                        * Event triggered after select index by user
+                                        * @event select
+                                        * @member ns.widget.core.IndexScrollbar
+                                        */
+                                       SELECT: "select"
+                               },
+
+                               POINTER_START = "vmousedown",
+                               POINTER_MOVE = "vmousemove",
+                               POINTER_END = "vmouseup",
+
+                               pointerIsPressed = false,
+                               prototype = new BaseWidget();
+
+                       IndexScrollbar.prototype = prototype;
+
+                       utilsObject.merge(prototype, {
+                               widgetName: "IndexScrollbar",
+                               widgetClass: "ui-indexscrollbar",
+
+                               _configure: function () {
+                                       /**
+                                        * All possible widget options
+                                        * @property {Object} options
+                                        * @property {string} [options.moreChar="*"] more character
+                                        * @property {string} [options.selectedClass="ui-state-selected"] disabled class name
+                                        * @property {string} [options.delimiter=","] delimiter in index
+                                        * @property {string|Array} [options.index=["A","B","C","D","E","F","G","H","I",
+                                        * "J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","1"]]
+                                        * String with list of letters separate be delimiter or array of letters
+                                        * @property {boolean} [options.maxIndexLen=0]
+                                        * @property {boolean} [options.indexHeight=41]
+                                        * @property {boolean} [options.keepSelectEventDelay=50]
+                                        * @property {?boolean} [options.container=null]
+                                        * @property {?boolean} [options.supplementaryIndex=null]
+                                        * @property {number} [options.supplementaryIndexMargin=1]
+                                        * @member ns.widget.core.IndexScrollbar
+                                        */
+                                       this.options = {
+                                               moreChar: "*",
+                                               indexScrollbarClass: "ui-indexscrollbar",
+                                               selectedClass: "ui-state-selected",
+                                               indicatorClass: "ui-indexscrollbar-indicator",
+                                               delimiter: ",",
+                                               index: [
+                                                       "A", "B", "C", "D", "E", "F", "G", "H",
+                                                       "I", "J", "K", "L", "M", "N", "O", "P", "Q",
+                                                       "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "1"
+                                               ],
+                                               maxIndexLen: 0,
+                                               indexHeight: 41,
+                                               keepSelectEventDelay: 50,
+                                               container: null,
+                                               supplementaryIndex: null,
+                                               supplementaryIndexMargin: 1,
+                                               moreCharLineHeight: 9,
+                                               verticalCenter: true,
+                                               indicatorAlignTo: "container"
+                                       };
+                               },
+
+                               /**
+                                * This method builds widget.
+                                * @method _build
+                                * @protected
+                                * @param {HTMLElement} element
+                                * @return {HTMLElement}
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _build: function (element) {
+                                       return element;
+                               },
+
+                               /**
+                                * This method inits widget.
+                                * @method _init
+                                * @protected
+                                * @param {HTMLElement} element
+                                * @return {HTMLElement}
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _init: function (element) {
+                                       var self = this,
+                                               options = self.options;
+
+                                       element.classList.add(options.indexScrollbarClass);
+
+                                       self._ui.page = selectors.getClosestBySelector(element, pageSelector);
+                                       self._setIndex(element, options.index);
+                                       self._setMaxIndexLen(element, options.maxIndexLen);
+                                       self._setInitialLayout(); // This is needed for creating sub objects
+                                       self._createSubObjects();
+
+                                       self._updateLayout();
+
+                                       // Mark as extended
+                                       self._extended(true);
+                                       return element;
+                               },
+
+                               /**
+                                * This method refreshes widget.
+                                * @method _refresh
+                                * @protected
+                                * @return {HTMLElement}
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _refresh: function () {
+                                       var self = this;
+
+                                       if (self._isExtended()) {
+                                               self._unbindEvent();
+                                               self.indicator.hide();
+                                               self._extended(false);
+                                       }
+
+                                       self._setIndex(self.element, self.options.index);
+                                       self._updateLayout();
+                                       self.indexBar1.options.index = self.options.index;
+                                       self.indexBar1.refresh();
+                                       self.indicator.fitToContainer();
+                                       self._bindEvents();
+                                       self._extended(true);
+                               },
+
+                               /**
+                                * This method destroys widget.
+                                * @method _destroy
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _destroy: function () {
+                                       var self = this;
+
+                                       if (self.isBound()) {
+                                               self._unbindEvent();
+                                               self._extended(false);
+                                               self._destroySubObjects();
+                                               self.indicator = null;
+                                               self.index = null;
+                                               self.eventHandlers = {};
+                                       }
+                               },
+
+                               /**
+                                * This method creates indexBar1 and indicator in the indexScrollbar
+                                * @method _createSubObjects
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _createSubObjects: function () {
+                                       var self = this,
+                                               options = self.options,
+                                               element = self.element;
+                                       // indexBar1
+
+                                       self.indexBar1 = new IndexBar(document.createElement("UL"), {
+                                               container: element,
+                                               offsetLeft: 0,
+                                               index: options.index,
+                                               verticalCenter: options.verticalCenter,
+                                               indexHeight: options.indexHeight,
+                                               maxIndexLen: options.maxIndexLen,
+                                               paddingBottom: options.paddingBottom,
+                                               moreCharLineHeight: options.moreCharLineHeight
+                                       });
+
+                                       // indexBar2
+                                       if (typeof options.supplementaryIndex === "function") {
+                                               self.indexBar2 = new IndexBar(document.createElement("UL"), {
+                                                       container: element,
+                                                       offsetLeft: -element.clientWidth - options.supplementaryIndexMargin,
+                                                       index: [],      // empty index
+                                                       indexHeight: options.indexHeight,
+                                                       ulClass: "ui-indexscrollbar-supplementary"
+                                               });
+                                               self.indexBar2.hide();
+                                       }
+
+                                       // indicator
+                                       self.indicator = new IndexIndicator(document.createElement("DIV"), {
+                                               container: self._getContainer(),
+                                               referenceElement: self.element,
+                                               className: options.indicatorClass,
+                                               alignTo: options.indicatorAlignTo
+                                       });
+
+                               },
+
+                               /**
+                                * This method destroys sub-elements: index bars and indicator.
+                                * @method _destroySubObjects
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _destroySubObjects: function () {
+                                       var subObjs = {
+                                                       iBar1: this.indexBar1,
+                                                       iBar2: this.indexBar2,
+                                                       indicator: this.indicator
+                                               },
+                                               subObj,
+                                               el,
+                                               i;
+
+                                       for (i in subObjs) {
+                                               if (subObjs.hasOwnProperty(i)) {
+                                                       subObj = subObjs[i];
+                                                       if (subObj) {
+                                                               el = subObj.element;
+                                                               subObj.destroy();
+                                                               el.parentNode.removeChild(el);
+                                                       }
+                                               }
+                                       }
+                               },
+
+                               /**
+                                * This method sets initial layout.
+                                * @method _setInitialLayout
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _setInitialLayout: function () {
+                                       var indexScrollbar = this.element,
+                                               container = this._getContainer(),
+                                               containerPosition = window.getComputedStyle(container).position,
+                                               indexScrollbarStyle = indexScrollbar.style;
+
+                                       // Set the indexScrollbar's position, if needed
+                                       if (containerPosition !== "absolute" && containerPosition !== "relative") {
+                                               indexScrollbarStyle.top = container.offsetTop + "px";
+                                               indexScrollbarStyle.height = container.offsetHeight + "px";
+                                       }
+                               },
+
+                               /**
+                                * This method calculates maximum index length.
+                                * @method _setMaxIndexLen
+                                * @protected
+                                * @param {HTMLElement} element
+                                * @param {number} value
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _setMaxIndexLen: function (element, value) {
+                                       var self = this,
+                                               options = self.options,
+                                               container = self._getContainer(),
+                                               containerHeight = container.offsetHeight;
+
+                                       if (value <= 0) {
+                                               value = Math.floor(containerHeight / options.indexHeight);
+                                       }
+                                       if (value > 0 && value % 2 === 0) {
+                                               value -= 1;     // Ensure odd number
+                                       }
+                                       options.maxIndexLen = value;
+                               },
+
+                               /**
+                                * This method updates layout.
+                                * @method _updateLayout
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _updateLayout: function () {
+                                       var self = this;
+
+                                       self._setInitialLayout();
+                                       self._draw();
+
+                                       self.touchAreaOffsetLeft = self.element.offsetLeft - 10;
+                               },
+
+                               /**
+                                * This method draws additional sub-elements
+                                * @method _draw
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _draw: function () {
+                                       this.indexBar1.show();
+                                       return this;
+                               },
+
+                               /**
+                                * This method removes indicator.
+                                * @method _removeIndicator
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _removeIndicator: function () {
+                                       var indicator = this.indicator,
+                                               parentElem = indicator.element.parentNode;
+
+                                       parentElem.removeChild(indicator.element);
+                                       indicator.destroy();
+                                       this.indicator = null;
+                               },
+
+                               /**
+                                * This method returns the receiver of event by position.
+                                * @method _getEventReceiverByPosition
+                                * @param {number} posX The position relative to the left edge of the document.
+                                * @return {?ns.widget.core.indexscrollbar.IndexBar} Receiver of event
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _getEventReceiverByPosition: function (posX) {
+                                       var windowWidth = window.innerWidth,
+                                               elementWidth = this.element.clientWidth,
+                                               receiver;
+
+                                       if (this.options.supplementaryIndex) {
+                                               if (windowWidth - elementWidth <= posX && posX <= windowWidth) {
+                                                       receiver = this.indexBar1;
+                                               } else {
+                                                       receiver = this.indexBar2;
+                                               }
+                                       } else {
+                                               receiver = this.indexBar1;
+                                       }
+                                       return receiver;
+                               },
+
+                               /**
+                                * This method updates indicator.
+                                * It sets new value of indicator and triggers event "select".
+                                * @method _updateIndicatorAndTriggerEvent
+                                * @param {number} val The value of indicator
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _updateIndicatorAndTriggerEvent: function (val) {
+                                       this.indicator.setValue(val);
+                                       this.indicator.show();
+                                       if (this.selectEventTriggerTimeoutId) {
+                                               window.clearTimeout(this.selectEventTriggerTimeoutId);
+                                       }
+                                       this.selectEventTriggerTimeoutId = window.setTimeout(function () {
+                                               this.trigger(EventType.SELECT, {index: val});
+                                               this.selectEventTriggerTimeoutId = null;
+                                       }.bind(this), this.options.keepSelectEventDelay);
+                               },
+
+                               /**
+                                * This method is executed on event "touchstart"
+                                * @method _onTouchStartHandler
+                                * @param {Event} event Event
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _onTouchStartHandler: function (event) {
+                                       var touches = event.touches || event._originalEvent && event._originalEvent.touches,
+                                               pos = null,
+                                               // At touchstart, only indexBar1 is shown.
+                                               iBar1 = null,
+                                               idx = 0,
+                                               val = 0;
+
+                                       pointerIsPressed = true;
+
+                                       if (touches && (touches.length > 1)) {
+                                               event.preventDefault();
+                                               event.stopPropagation();
+                                               return;
+                                       }
+                                       pos = this._getPositionFromEvent(event);
+                                       // At touchstart, only indexBar1 is shown.
+                                       iBar1 = this.indexBar1;
+                                       idx = iBar1.getIndexByPosition(pos.y);
+                                       val = iBar1.getValueByIndex(idx);
+
+                                       iBar1.select(idx);      // highlight selected value
+
+                                       document.addEventListener(POINTER_MOVE, this.eventHandlers.touchMove);
+                                       document.addEventListener(POINTER_END, this.eventHandlers.touchEnd);
+                                       document.addEventListener("touchcancel", this.eventHandlers.touchEnd);
+
+                                       this._updateIndicatorAndTriggerEvent(val);
+                               },
+
+                               /**
+                                * This method is executed on event "touchmove"
+                                * @method _onTouchMoveHandler
+                                * @param {Event} event Event
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _onTouchMoveHandler: function (event) {
+                                       var touches = event._originalEvent && event._originalEvent.touches,
+                                               pos = null,
+                                               iBar1 = null,
+                                               iBar2 = null,
+                                               idx,
+                                               iBar,
+                                               val;
+
+                                       if (touches && (touches.length > 1) || !pointerIsPressed) {
+                                               events.preventDefault(event);
+                                               events.stopPropagation(event);
+                                               return;
+                                       }
+
+                                       pos = this._getPositionFromEvent(event);
+                                       iBar1 = this.indexBar1;
+                                       iBar2 = this.indexBar2;
+
+                                       // Check event receiver: iBar1 or iBar2
+                                       iBar = this._getEventReceiverByPosition(pos.x);
+                                       if (iBar === iBar2) {
+                                               iBar2.options.index = this.options.supplementaryIndex(iBar1.getValueByIndex(iBar1.selectedIndex));
+                                               iBar2.refresh();
+                                       }
+
+                                       // get index and value from iBar1 or iBar2
+                                       idx = iBar.getIndexByPosition(pos.y);
+                                       val = iBar.getValueByIndex(idx);
+                                       if (iBar === iBar2) {
+                                               // Update val to make a concatenated string for indexIndicator
+                                               val = iBar1.getValueByIndex(iBar1.selectedIndex) + val;
+                                       } else if (iBar2 && !iBar2.isShown()) {
+                                               // iBar1 is selected.
+                                               // Set iBar2's paddingTop, only when the iBar2 isn't shown
+                                               iBar2.setPaddingTop(iBar1.getOffsetTopByIndex(iBar1.selectedIndex));
+                                       }
+
+                                       // update iBars
+                                       iBar.select(idx);       // highlight selected value
+                                       iBar.show();
+                                       if (iBar1 === iBar && iBar2) {
+                                               iBar2.hide();
+                                       }
+
+                                       // update indicator
+                                       this._updateIndicatorAndTriggerEvent(val);
+
+                                       events.preventDefault(event);
+                                       events.stopPropagation(event);
+                               },
+
+                               /**
+                                * This method is executed on event "touchend"
+                                * @method _onTouchEndHandler
+                                * @param {Event} event Event
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _onTouchEndHandler: function (event) {
+                                       var self = this,
+                                               touches = event._originalEvent && event._originalEvent.touches;
+
+                                       if (touches && (touches.length === 0) || !touches) {
+                                               pointerIsPressed = false;
+                                       }
+                                       self.indicator.hide();
+                                       self.indexBar1.clearSelected();
+                                       if (self.indexBar2) {
+                                               self.indexBar2.clearSelected();
+                                               self.indexBar2.hide();
+                                       }
+
+                                       document.removeEventListener(POINTER_MOVE, self.eventHandlers.touchMove);
+                                       document.removeEventListener(POINTER_END, self.eventHandlers.touchEnd);
+                                       document.removeEventListener("touchcancel", self.eventHandlers.touchEnd);
+                               },
+
+                               _bindOnPageShow: function () {
+                                       var self = this;
+
+                                       self.eventHandlers.onPageShow = self.refresh.bind(self);
+                                       if (self._ui.page) {
+                                               self._ui.page.addEventListener(Page.events.BEFORE_SHOW, self.eventHandlers.onPageShow, false);
+                                       }
+                               },
+
+                               _unbindOnPageShow: function () {
+                                       var self = this;
+
+                                       if (self.eventHandlers.onPageShow && self._ui.page) {
+                                               self._ui.page.removeEventListener(Page.events.BEFORE_SHOW, self.eventHandlers.onPageShow, false);
+                                       }
+                               },
+
+                               /**
+                                * This method binds events to widget.
+                                * @method _bindEvents
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _bindEvents: function () {
+                                       var self = this;
+
+                                       self._bindResizeEvent();
+                                       self._bindEventToTriggerSelectEvent();
+                                       self._bindOnPageShow();
+                               },
+
+                               /**
+                                * This method unbinds events to widget.
+                                * @method _unbindEvent
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _unbindEvent: function () {
+                                       var self = this;
+
+                                       self._unbindResizeEvent();
+                                       self._unbindEventToTriggerSelectEvent();
+                                       self._unbindOnPageShow();
+                               },
+
+                               /**
+                                * This method binds event "resize".
+                                * @method _bindResizeEvent
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _bindResizeEvent: function () {
+                                       this.eventHandlers.onresize = function (/* ev */) {
+                                               this.refresh();
+                                       }.bind(this);
+
+                                       window.addEventListener("resize", this.eventHandlers.onresize);
+                               },
+
+                               /**
+                                * This method unbinds event "resize".
+                                * @method _bindResizeEvent
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _unbindResizeEvent: function () {
+                                       if (this.eventHandlers.onresize) {
+                                               window.removeEventListener("resize", this.eventHandlers.onresize);
+                                       }
+                               },
+
+                               /**
+                                * This method binds touch events.
+                                * @method _bindEventToTriggerSelectEvent
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _bindEventToTriggerSelectEvent: function () {
+                                       var self = this;
+
+                                       self.eventHandlers.touchStart = self._onTouchStartHandler.bind(self);
+                                       self.eventHandlers.touchEnd = self._onTouchEndHandler.bind(self);
+                                       self.eventHandlers.touchMove = self._onTouchMoveHandler.bind(self);
+
+                                       self.element.addEventListener(POINTER_START, self.eventHandlers.touchStart);
+                               },
+
+                               /**
+                                * This method unbinds touch events.
+                                * @method _unbindEventToTriggerSelectEvent
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _unbindEventToTriggerSelectEvent: function () {
+                                       var self = this;
+
+                                       self.element.removeEventListener(POINTER_START, self.eventHandlers.touchStart);
+                               },
+
+                               /**
+                                * This method sets or gets data from widget.
+                                * @method _data
+                                * @param {string|Object} key
+                                * @param {*} val
+                                * @return {*} Return value of data or widget's object
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _data: function (key, val) {
+                                       var el = this.element,
+                                               d = el.__data,
+                                               idx;
+
+                                       if (!d) {
+                                               d = el.__data = {};
+                                       }
+                                       if (typeof key === "object") {
+                                               // Support data collection
+                                               for (idx in key) {
+                                                       if (key.hasOwnProperty(idx)) {
+                                                               this._data(idx, key[idx]);
+                                                       }
+                                               }
+                                               return this;
+                                       } else {
+                                               if ("undefined" === typeof val) {       // Getter
+                                                       return d[key];
+                                               } else {        // Setter
+                                                       d[key] = val;
+                                                       return this;
+                                               }
+                                       }
+                               },
+
+                               /**
+                                * This method checks if element is valid element of widget IndexScrollbar.
+                                * @method _isValidElement
+                                * @param {HTMLElement} el
+                                * @return {boolean} True, if element is valid.
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _isValidElement: function (el) {
+                                       return el.classList.contains(this.widgetClass);
+                               },
+
+                               /**
+                                * This method checks if widget is extended.
+                                * @method _isExtended
+                                * @return {boolean} True, if element is extended.
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _isExtended: function () {
+                                       return !!this._data("extended");
+                               },
+
+                               /**
+                                * This method sets value of "extended" to widget.
+                                * @method _extended
+                                * @param {boolean} flag Value for extended
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _extended: function (flag) {
+                                       this._data("extended", flag);
+                                       return this;
+                               },
+
+                               /**
+                                * This method gets indices prepared from parameter
+                                * or index of widget.
+                                * @method _setIndex
+                                * @param {HTMLElement} element element
+                                * @param {string} value Indices to prepared
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _setIndex: function (element, value) {
+                                       var options = this.options;
+
+                                       if (typeof value === "string") {
+                                               value = value.split(options.delimiter); // delimiter
+                                       }
+                                       options.index = value;
+                               },
+
+                               /**
+                                * This method gets offset of element.
+                                * @method _getOffset
+                                * @param {HTMLElement} el Element
+                                * @return {Object} Offset with "top" and "left" properties
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _getOffset: function (el) {
+                                       var left = 0,
+                                               top = 0;
+
+                                       do {
+                                               top += el.offsetTop;
+                                               left += el.offsetLeft;
+                                               el = el.offsetParent;
+                                       } while (el);
+
+                                       return {
+                                               top: top,
+                                               left: left
+                                       };
+                               },
+
+                               /**
+                                * This method returns container of widget.
+                                * @method _getContainer
+                                * @return {HTMLElement} Container
+                                * @protected
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _getContainer: function () {
+                                       var container = this.options.container,
+                                               element = this.element,
+                                               parentElement = element.parentNode,
+                                               overflow;
+
+                                       if (!container) {
+                                               while (parentElement && parentElement !== document.body) {
+                                                       overflow = doms.getCSSProperty(parentElement, "overflow-y");
+                                                       if (overflow === "scroll" || (overflow === "auto" && parentElement.scrollHeight > parentElement.clientHeight)) {
+                                                               return parentElement;
+                                                       }
+                                                       parentElement = parentElement.parentNode;
+                                               }
+                                               container = element.parentNode;
+                                       }
+
+                                       return container || element.parentNode;
+                               },
+
+                               /**
+                                * Returns position of event.
+                                * @method _getPositionFromEvent
+                                * @return {Object} Position of event with properties "x" and "y"
+                                * @protected
+                                * @param {Event} ev
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               _getPositionFromEvent: function (ev) {
+                                       return ev.type.search(/^touch/) !== -1 ?
+                                               {x: ev.touches[0].clientX, y: ev.touches[0].clientY} :
+                                               {x: ev.clientX, y: ev.clientY};
+                               },
+
+                               /**
+                                * Adds event listener to element of widget.
+                                * @method addEventListener
+                                * @param {string} type Name of event
+                                * @param {Function} listener Function to be executed
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               addEventListener: function (type, listener) {
+                                       this.element.addEventListener(type, listener);
+                               },
+
+                               /**
+                                * Removes event listener from element of widget.
+                                * @method removeEventListener
+                                * @param {string} type Name of event
+                                * @param {Function} listener Function to be removed
+                                * @member ns.widget.core.IndexScrollbar
+                                */
+                               removeEventListener: function (type, listener) {
+                                       this.element.removeEventListener(type, listener);
+                               }
+
+                       });
+
+                       // definition
+                       ns.widget.core.IndexScrollbar = IndexScrollbar;
+                       }(window.document, ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true, plusplus: true */
+/**
+ * # Index Scrollbar
+ * Index scrollbar component shows a shortcut list that is bound to its parent scroll bar and list view.
+ *
+ * If you move the mouse on the shortcut column then a pop-up with the text currently
+ * under the cursor is also displayed.
+ *
+ *
+ * ## Default selectors
+ *
+ * In default all elements with class _ui-indexscrollbar_ are changed to Tizen Web UI Index Scrollbar
+ *
+ *             @example
+ *             <div data-role="page" id="main">
+ *                 <div data-role="indexscrollbar" id="indexscrollbar"></div>
+ *                     <div data-role="content">
+ *                             <ul data-role="listview">
+ *                                     <li data-role="list-divider">A</li>
+ *                                     <li>Anton</li>
+ *                                     <li>Arabella</li>
+ *                                     <li data-role="list-divider">B</li>
+ *                                     <li>Barry</li>
+ *                                     <li>Billy</li>
+ *                             </ul>
+ *                     </div>
+ *             </div>
+ *
+ * #### Create Index Scrollbar widget using tau method:
+ *
+ *             @example
+ *             <div data-role="page" id="main">
+ *                 <div data-role="indexscrollbar" id="indexscrollbar"></div>
+ *                     <div data-role="content">
+ *                             <ul id="list">
+ *                                     <li data-role="list-divider">A</li>
+ *                                     <li>Anton</li>
+ *                                     <li>Arabella</li>
+ *                                     <li data-role="list-divider">B</li>
+ *                                     <li>Barry</li>
+ *                                     <li>Billy</li>
+ *                             </ul>
+ *                     </div>
+ *             </div>
+ *             <script>
+ *                     var isb = tau.widget.IndexScrollbar(document.getElementById("indexscrollbar"));
+ *             </script>
+ *
+ * #### Create Index Scrollbar widget using jQueryMobile notation:
+ *
+ *             @example
+ *             <div data-role="page" id="main">
+ *                 <div data-role="indexscrollbar" id="indexscrollbar"></div>
+ *                     <div data-role="content">
+ *                             <ul id="list">
+ *                                     <li data-role="list-divider">A</li>
+ *                                     <li>Anton</li>
+ *                                     <li>Arabella</li>
+ *                                     <li data-role="list-divider">B</li>
+ *                                     <li>Barry</li>
+ *                                     <li>Billy</li>
+ *                             </ul>
+ *                     </div>
+ *             </div>
+ *             <script>
+ *                     var isb = $("#indexscrollbar").IndexScrollbar();
+ *             </script>
+ *
+ * ## Options
+ *
+ * ### Index Scrollbar
+ * _data-fastscroll_ option set to true, creates a fast scroll using the HTML unordered list (&lt;ul&gt;) element.
+ *
+ *             @example
+ *             <div data-role="page" id="main">
+ *                 <div data-role="indexscrollbar" id="indexscrollbar"></div>
+ *                     <div data-role="content">
+ *                             <ul id="contacts" data-role="listview">
+ *                                     <li data-role="list-divider">A</li>
+ *                                     <li>Anton</li>
+ *                                     <li>Arabella</li>
+ *                                     <li data-role="list-divider">B</li>
+ *                                     <li>Barry</li>
+ *                                     <li>Billy</li>
+ *                             </ul>
+ *                     </div>
+ *             </div>
+ *
+ * ## Methods
+ *
+ * To call method on widget you can use tau API:
+ *
+ *             @example
+ *             <div data-role="page" id="main">
+ *                 <div data-role="indexscrollbar" id="indexscrollbar"></div>
+ *                     <div data-role="content">
+ *                             <ul id="contacts">
+ *                                     <li data-role="list-divider">A</li>
+ *                                     <li>Anton</li>
+ *                                     <li>Arabella</li>
+ *                                     <li data-role="list-divider">B</li>
+ *                                     <li>Barry</li>
+ *                                     <li>Billy</li>
+ *                             </ul>
+ *                     </div>
+ *             </div>
+ *             <script>
+ *                     var element = document.getElementById("contacts"),
+ *                             contacts = tau.widget.IndexScrollbar(element);
+ *
+ *                     contacts.methodName(methodArgument1, methodArgument2, ...);
+ *
+ *                     // or JQueryMobile notation:
+ *                     $(element).contacts("methodName", methodArgument1, methodArgument2, ...);
+ *             </script>
+ *
+ * @class ns.widget.mobile.IndexScrollbar
+ * @extends ns.widget.core.IndexScrollbar
+ * @since 2.0
+ */
+(function () {
+       "use strict";
+       
+                       var engine = ns.engine,
+                               selectors = ns.util.selectors,
+                               Page = ns.widget.core.Page,
+                               Scrollview = ns.widget.core.Scrollview,
+                               CoreIndexScrollbar = ns.widget.core.IndexScrollbar,
+                               CoreISBPrototype = CoreIndexScrollbar.prototype,
+                               prototype = new CoreIndexScrollbar(),
+                               IndexScrollbar = function () {
+                                       var self = this;
+
+                                       self._ui = {};
+                                       CoreIndexScrollbar.call(self);
+                               },
+                               classes = {
+                                       PAGE: Page.classes.uiPage,
+                                       CONTENT: Page.classes.uiContent,
+                                       SCROLLVIEW_CLIP: Scrollview.classes.clip,
+                                       FLOATING_BUTTON_CONTAINER: "ui-floatingactions",
+                                       GROUP_INDEX: "ui-group-index"
+                               },
+                               DEFAULT = {
+                                       INDEX_HEIGHT: 20,
+                                       MORE_CHAR_LINEHEIGHT: 4
+                               };
+
+                       IndexScrollbar.classes = classes;
+
+                       function getIndices(elements) {
+                               var indices = [],
+                                       i,
+                                       len;
+
+                               len = elements.length;
+                               for (i = 0; i < len; i++) {
+                                       indices.push(elements[i].textContent.trim());
+                               }
+                               return indices;
+                       }
+                       /**
+                        * Configure IndexScrollbar component
+                        * @method _configure
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.mobile.IndexScrollbar
+                        */
+                       prototype._configure = function (element) {
+                               var self = this,
+                                       page = selectors.getClosestByClass(element, classes.PAGE),
+                                       clip = page.querySelector("." + classes.CONTENT),
+                                       indices = getIndices(page.getElementsByClassName(classes.GROUP_INDEX));
+
+                               CoreISBPrototype._configure.call(self);
+                               if (!self.options.container) {
+                                       self.options.container = clip || element.parentNode;
+                               }
+                               if (indices.length) {
+                                       self.options.index = indices;
+                               }
+                               self.options.indexHeight = DEFAULT.INDEX_HEIGHT;
+                               self.options.moreCharLineHeight = DEFAULT.MORE_CHAR_LINEHEIGHT;
+                               self.options.verticalCenter = false;
+                       };
+
+                       /**
+                        * Init IndexScrollbar component
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.mobile.IndexScrollbar
+                        */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               CoreISBPrototype._init.call(self, element);
+                               self._fitHeight();
+                       };
+
+                       /**
+                        * Set IndexScrollbar layout
+                        * @method _setInitialLayout
+                        * @protected
+                        * @member ns.widget.mobile.IndexScrollbar
+                        */
+                       prototype._setInitialLayout = function () {
+                               var self = this,
+                                       indexScrollbar = self.element,
+                                       options = self.options,
+                                       container = options.container,
+                                       indexScrollbarStyle = indexScrollbar.style,
+                                       containFloating = container.parentElement.querySelector("." + classes.FLOATING_BUTTON_CONTAINER);
+
+                               //if we need to shorten the height of the index, for example when
+                               //floatingButton is presented
+                               if (containFloating) {
+                                       options.paddingBottom = container.offsetHeight -
+                                                       containFloating.offsetTop + container.offsetTop;
+                               }
+
+                               indexScrollbarStyle.height = container.offsetHeight + "px";
+                               indexScrollbarStyle.top = container.offsetTop + "px";
+                       };
+
+                       /**
+                        * Fit IndexScrollbar height
+                        * @method _fitHeight
+                        * @protected
+                        * @member ns.widget.mobile.IndexScrollbar
+                        */
+                       prototype._fitHeight = function () {
+                               var self = this,
+                                       element = self.element,
+                                       wrapper = element.getElementsByTagName("ul")[0],
+                                       lastChild = wrapper.lastChild,
+                                       space;
+
+                               space = element.offsetHeight - wrapper.offsetHeight;
+                               if (lastChild) {
+                                       lastChild.style.height = lastChild.offsetHeight + space + "px";
+                               }
+                       };
+
+                       // definition
+                       IndexScrollbar.prototype = prototype;
+                       ns.widget.mobile.IndexScrollbar = IndexScrollbar;
+
+                       engine.defineWidget(
+                               "IndexScrollbar",
+                               "[data-role='indexscrollbar'], .ui-indexscrollbar",
+                               [],
+                               IndexScrollbar,
+                               "mobile"
+                       );
+
+                       }());
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, define, ns */
+/**
+ * #Button
+ * Button component changes the default browser buttons to special buttons with additional features, such as icons, corners, and shadows.
+ *
+ * @example
+ *    <button>Button element</button>
+ *
+ * @since 2.0
+ * @class ns.widget.mobile.Button
+ * @extends ns.widget.core.Button
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var Button = ns.widget.core.Button;
+
+                       ns.widget.mobile.Button = Button;
+
+                       ns.engine.defineWidget(
+                               "Button",
+                               "button, [data-role='button'], .ui-btn, input[type='button']",
+                               [],
+                               Button,
+                               "mobile",
+                               true
+                       );
+                       }(window, window.document, ns));
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * # Floating Actions
+ * Floating actions component creates a floating button at the bottom of the screen.
+ *
+ * ##Default Selectors
+ * By default, all elements with the class="ui-floatingactions" or data-role="floatingactions" attribute are displayed as floating actions components.
+ *
+ * ##Manual constructor
+ *      @example
+ *      <div class="ui-floatingactions" id="floating">
+ *          <button class="ui-floatingactions-item" data-icon="floating-add"/>
+ *          <button class="ui-floatingactions-item" data-icon="floating-search"/>
+ *      </div>
+ *      <script>
+ *          var elFloatingActions = document.getElementById("floating"),
+ *                floatingActions = tau.widget.FloatingActions(elFloatingActions);
+ *      </script>
+ *
+ * @since 2.4
+ * @class ns.widget.mobile.FloatingActions
+ * @component-selector .ui-floatingactions, [data-role]="floatingactions"
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+       
+                       var BaseWidget = ns.widget.BaseWidget,
+                               PageClasses = ns.widget.core.Page.classes,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               KEY_CODES = BaseKeyboardSupport.KEY_CODES,
+                               engine = ns.engine,
+                               utilsEvents = ns.event,
+                               selectorUtils = ns.util.selectors,
+                               prototype = new BaseWidget(),
+                               MATRIX_REGEXP = /matrix\((.*), (.*), (.*), (.*), (.*), (.*)\)/,
+                               SNAP_WIDTH = 19,
+                               FloatingActions = function () {
+                                       var self = this;
+
+                                       BaseKeyboardSupport.call(self);
+                                       self.element = null;
+                                       self.options = {};
+                                       self._style = null;
+                                       self._startX = 0;
+                                       self._currentX = 0;
+                                       self._hasSingle = true;
+                                       self._padding = {};
+                                       self._position = {};
+                                       self._scope = {};
+                               },
+                               WIDGET_CLASS = "ui-floatingactions",
+                               WIDGET_POSITION = [
+                                       "left-min",
+                                       "left-2nd-icon",
+                                       "left-1st-icon",
+                                       "center",
+                                       "right-1st-icon",
+                                       "right-2nd-icon",
+                                       "right-min"
+                               ],
+                               classes = {
+                                       /**
+                                        * Standard floating actions widget
+                                        * @style ui-floatingactions
+                                        * @member ns.widget.mobile.FloatingActions
+                                        */
+                                       WIDGET: WIDGET_CLASS,
+                                       /**
+                                        * Enable transition for floating actions widget
+                                        * @style ui-floatingactions-transitions
+                                        * @member ns.widget.mobile.FloatingActions
+                                        */
+                                       TRANSITIONS: WIDGET_CLASS + "-transitions",
+                                       /**
+                                        * Expand floating actions to the left
+                                        * @style ui-floatingactions-expand-to-left
+                                        * @member ns.widget.mobile.FloatingActions
+                                        */
+                                       EXPAND_TO_LEFT: WIDGET_CLASS + "-expand-to-left",
+                                       /**
+                                        * Expand floating actions to the right
+                                        * @style ui-floatingactions-expand-to-right
+                                        * @member ns.widget.mobile.FloatingActions
+                                        */
+                                       EXPAND_TO_RIGHT: WIDGET_CLASS + "-expand-to-right",
+                                       /**
+                                        * Set page to implement floating actions
+                                        * @style ui-page-floatingactions
+                                        * @member ns.widget.mobile.FloatingActions
+                                        */
+                                       PAGE_WITH_FLOATING_ACTIONS: "ui-page-floatingactions"
+                               };
+
+
+                       /**
+                       * Configure component
+                       * @method _configure
+                       * @protected
+                       * @member ns.widget.mobile.FloatingActions
+                       */
+                       prototype._configure = function () {
+                               /**
+                                * @property {Object} options Object with default options
+                                * @property {number} [options.duration=300] animation duration for color and opacity (unit of time : millisecond)
+                                * @property {string} [options.position='right-min'] widget position [right-min | right-1st-button | right-2nd-button | center | left-1st-button | left-2nd-button | left-min]
+                                * @member ns.widget.mobile.FloatingActions
+                                */
+                               this.options = {
+                                       duration: 300,
+                                       position: "right-1st-icon"
+                               };
+                       };
+
+                       /**
+                       * Init component
+                       * @method _init
+                       * @param {HTMLElement} element
+                       * @protected
+                       * @member ns.widget.mobile.FloatingActions
+                       */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self._style = element.style;
+                               if (!self.element.hasAttribute("tabindex")) {
+                                       self.element.setAttribute("tabindex", "0");
+                               }
+                               self._hasSingle = element.children.length <= 1;
+                               self._buildInsideButtons();
+                               self._positionCalculation();
+                               self._setScope();
+                               self._updatePosition();
+                               self._toggleParentClasses();
+                               return element;
+                       };
+
+                       /**
+                       * Bind events
+                       * @method _bindEvents
+                       * @protected
+                       * @member ns.widget.mobile.FloatingActions
+                       */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               utilsEvents.enableGesture(
+                                       element,
+
+                                       new utilsEvents.gesture.Drag({
+                                               blockVertical: true
+                                       })
+                               );
+
+                               utilsEvents.on(element, "drag dragstart dragend dragcancel touchstart touchend vmousedown vmouseup keyup", self);
+                       };
+
+                       /**
+                       * Unbind events
+                       * @method _unbindEvents
+                       * @protected
+                       * @member ns.widget.mobile.FloatingActions
+                       */
+                       prototype._unbindEvents = function () {
+                               utilsEvents.disableGesture(this.element);
+                               utilsEvents.off(this.element, "drag dragstart dragend dragcancel touchstart touchend vmousedown vmouseup keyup", this);
+                       };
+
+                       /**
+                       * Refresh component
+                       * @method _refresh
+                       * @protected
+                       * @member ns.widget.mobile.FloatingActions
+                       */
+                       prototype._refresh = function () {
+                               var self = this,
+                                       element = self.element;
+
+                               self._hasSingle = element.children.length <= 1;
+
+                               self._positionCalculation();
+                               self._setScope();
+                               self._updatePosition();
+                       };
+
+                       /**
+                       * Destroy component
+                       * @method _destroy
+                       * @protected
+                       * @member ns.widget.mobile.FloatingActions
+                       */
+                       prototype._destroy = function () {
+                               var self = this;
+
+                               if (self.isBound()) {
+                                       self._unbindEvents();
+                                       self._style = null;
+                                       self._position = null;
+                                       self._scope = null;
+                                       self._padding = null;
+                                       self._toggleParentClasses(true);
+                               }
+                       };
+
+                       prototype._buildInsideButtons = function () {
+                               var i = 0,
+                                       self = this,
+                                       element = self.element,
+                                       elementChildren = element.children,
+                                       length = elementChildren.length;
+
+                               for (; i < length; i++) {
+                                       ns.widget.Button(elementChildren[i]);
+                               }
+                       };
+
+                       /**
+                       * Set position for move effect
+                       * @method _positionCalculation
+                       * @protected
+                       * @member ns.widget.mobile.FloatingActions
+                       */
+                       prototype._positionCalculation = function () {
+                               var self = this,
+                                       element = self.element,
+                                       elementStyle = window.getComputedStyle(element),
+                                       position = self._position,
+                                       padding = self._padding,
+                                       paddingLeft,
+                                       paddingRight,
+                                       elementWidth = element.offsetWidth;
+
+                               paddingLeft = parseInt(elementStyle.paddingLeft, 10);
+                               paddingLeft = parseInt(elementStyle.paddingLeft, 10);
+                               paddingRight = parseInt(elementStyle.paddingRight, 10);
+
+                               position.min = -window.innerWidth + paddingLeft;
+                               position.max = elementWidth - paddingRight;
+                               position.center = (position.max + position.min) / 2;
+                               position.left = position.min + elementWidth - (paddingLeft + paddingRight);
+                               position.leftOneButton = position.min + (position.left - position.min) / 2;
+                               position.right = position.max - elementWidth + (paddingRight + paddingLeft);
+                               position.rightOneButton = position.right + (position.max - position.right) / 2;
+
+                               padding.left = paddingLeft;
+                               padding.right = paddingRight;
+                               padding.ratioInShow = SNAP_WIDTH / (position.center - position.left);
+                               padding.ratioInHide = SNAP_WIDTH / (position.left - position.min);
+                       };
+
+                       /**
+                       * Set scope for move effect
+                       * @method _setScope
+                       * @protected
+                       * @member ns.widget.mobile.FloatingActions
+                       */
+                       prototype._setScope = function () {
+                               var self = this,
+                                       position = self._position,
+                                       scope = self._scope,
+                                       padding = self._padding,
+                                       hasSingle = self._hasSingle;
+
+                               scope.min = position.min + padding.left / 2;
+                               scope.leftOneButton = !hasSingle ? position.min + (position.left - position.min) * 3 / 4 : null;
+                               scope.left = position.left + (position.center - position.left) / 2;
+                               scope.center = position.center + (position.right - position.center) / 2;
+                               scope.right = position.right + padding.right / 2;
+                               scope.rightOneButton = !hasSingle ? position.right + (position.max - position.right) * 3 / 4 : null;
+                               scope.max = position.max;
+                       };
+
+                       /**
+                        * Dragstart event handler
+                        * @method _start
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.mobile.FloatingActions
+                        */
+                       prototype._start = function (event) {
+                               var self = this,
+                                       element = self.element;
+
+                               self._startX = event.detail.pointer.clientX;
+                               // get current x value of translated3d
+                               self._currentX =
+                                       parseInt(window.getComputedStyle(element).webkitTransform.match(MATRIX_REGEXP)[5], 10);
+                               element.classList.remove(classes.TRANSITIONS);
+                               self._clearExpandWidget();
+                       };
+
+                       prototype._clearExpandWidget = function () {
+                               var classList = this.element.classList;
+
+                               classList.remove(classes.EXPAND_TO_LEFT);
+                               classList.remove(classes.EXPAND_TO_RIGHT);
+                       };
+
+                       prototype._expandWidget = function (name) {
+                               var self = this,
+                                       classList = self.element.classList;
+
+                               switch (name) {
+                                       case "left-min" :
+                                       case "left-1st-icon" :
+                                       case "left-2nd-icon" :
+                                               classList.add(classes.EXPAND_TO_LEFT);
+                                               classList.remove(classes.EXPAND_TO_RIGHT);
+                                               break;
+                                       case "center" :
+                                               self._clearExpandWidget();
+                                               break;
+                                       case "right-min" :
+                                       case "right-1st-icon" :
+                                       case "right-2nd-icon" :
+                                               classList.remove(classes.EXPAND_TO_LEFT);
+                                               classList.add(classes.EXPAND_TO_RIGHT);
+                                               break;
+                               }
+                       };
+
+                       /**
+                       * Drag event handler
+                       * @method _move
+                        * @param {Event} event
+                       * @protected
+                       * @member ns.widget.mobile.FloatingActions
+                       */
+                       prototype._move = function (event) {
+                               var self = this,
+                                       style = self._style,
+                                       moveX = event.detail.estimatedX - self._startX + self._currentX,
+                                       position = self._position,
+                                       transform;
+
+                               if (moveX >= position.min && moveX <= position.max) {
+                                       // for component position
+                                       transform = "translate3d(" + moveX + "px, 0, 0)";
+                                       style.webkitTransform = transform;
+                                       style.transform = transform;
+                               }
+                       };
+
+                       /**
+                        * Set widget position by position name
+                        * @method _setPosition
+                        * @param {HTMLElement} element widget html element
+                        * @param {string} name name of preset position
+                        * @protected
+                        * @member ns.widget.mobile.FloatingActions
+                        */
+                       prototype._setPosition = function (element, name) {
+                               var self = this,
+                                       hasSingle = self._hasSingle;
+
+                               if (hasSingle && name === "left-2nd-icon") {
+                                       name = "left-1st-icon";
+                                       ns.warn("Cannot set 2nd icon when widget has 1 icon");
+                               }
+                               if (hasSingle && name === "right-2nd-icon") {
+                                       name = "right-1st-icon";
+                                       ns.warn("Cannot set 2nd icon when widget has 1 icon");
+                               }
+
+                               self.options.position = name;
+
+                               self._updatePosition();
+                       };
+
+                       /**
+                        * Get widget position by position name
+                        * @method _getPositionByName
+                        * @param {string} name name of preset position
+                        * @protected
+                        * @member ns.widget.mobile.FloatingActions
+                        */
+                       prototype._getPositionByName = function (name) {
+                               var position = this._position;
+
+                               switch (name) {
+                                       case "left-min": return position.min;
+                                       case "left-2nd-icon": return position.leftOneButton;
+                                       case "left-1st-icon": return position.left;
+                                       case "center": return position.center;
+                                       case "right-1st-icon": return position.right;
+                                       case "right-2nd-icon": return position.rightOneButton;
+                                       case "right-min": return position.max;
+                                       default: return position.max;
+                               }
+                       };
+
+
+                       /**
+                        * Find parent element and add/remove widget class
+                        * @method _updateParentClasses
+                        * @param {boolean} [remove=false] add or remove floating action class from page element
+                        * @protected
+                        * @member ns.widget.mobile.FloatingActions
+                        */
+                       prototype._toggleParentClasses = function (remove) {
+                               var self = this,
+                                       parentElement = selectorUtils.getClosestByClass(self.element, PageClasses.uiPage);
+
+                               if (parentElement) {
+                                       parentElement.classList.toggle(classes.PAGE_WITH_FLOATING_ACTIONS, !remove);
+                               }
+                       };
+
+                       /**
+                        * Set widget position by position name
+                        * @method _getPositionByName
+                        * @protected
+                        * @member ns.widget.mobile.FloatingActions
+                        */
+                       prototype._updatePosition = function () {
+                               var self = this,
+                                       style = self.element.style,
+                                       positionName = self.options.position,
+                                       transform;
+
+                               self.element.classList.add(classes.TRANSITIONS);
+
+                               transform = "translate3d(" + self._getPositionByName(positionName) + "px, 0, 0)";
+                               style.webkitTransform = transform;
+                               style.transform = transform;
+
+                               self._expandWidget(positionName);
+                       };
+
+                       /**
+                        * Get widget position name by position X
+                        * @method _getPositionNameByPosition
+                        * @param {number} positionX current widget position
+                        * @protected
+                        * @member ns.widget.mobile.FloatingActions
+                        */
+                       prototype._getPositionNameByPosition = function (positionX) {
+                               var self = this,
+                                       scope = self._scope,
+                                       hasSingle = self._hasSingle;
+
+                               if (positionX < scope.min) {
+                                       return "left-min";
+                               } else if (!hasSingle && positionX < scope.leftOneButton) {
+                                       return "left-2nd-icon";
+                               } else if (positionX < scope.left) {
+                                       return "left-1st-icon";
+                               } else if (positionX < scope.center) {
+                                       return "center";
+                               } else if (positionX < scope.right) {
+                                       return "right-1st-icon";
+                               } else if (!hasSingle && positionX < scope.rightOneButton) {
+                                       return "right-2nd-icon";
+                               } else {
+                                       return "right-min";
+                               }
+                       };
+
+                       /**
+                        * Move widget to position X
+                        * @method _moveTo
+                        * @param {number} positionX current widget position
+                        * @protected
+                        * @member ns.widget.mobile.FloatingActions
+                        */
+                       prototype._moveTo = function (positionX) {
+                               var self = this;
+
+                               self.options.position = self._getPositionNameByPosition(positionX);
+                               self._updatePosition();
+                       };
+
+                       /**
+                        * Dragend event handler
+                        * @method _end
+                        * @param {Event} event
+                        * @protected
+                        * @member ns.widget.mobile.FloatingActions
+                        */
+                       prototype._end = function (event) {
+                               var self = this;
+
+                               self._moveTo(
+                                       event.detail.estimatedX - self._startX + self._currentX
+                               );
+                       };
+
+                       prototype._moveOnLeft = function () {
+                               var positionIndex = Math.max(
+                                       WIDGET_POSITION.indexOf(this.options.position) - 1, 0
+                                       );
+
+                               this.option("position", WIDGET_POSITION[positionIndex]);
+                       };
+
+                       prototype._moveOnRight = function () {
+                               var positionIndex = Math.min(
+                                       WIDGET_POSITION.indexOf(this.options.position) + 1,
+                                       WIDGET_POSITION.length - 1
+                                       );
+
+                               this.option("position", WIDGET_POSITION[positionIndex]);
+                       };
+
+                       prototype._onkeyup = function (event) {
+                               var options = event,
+                                       self = this;
+
+                               switch (options.keyCode) {
+                                       case KEY_CODES.left:
+                                               if (self._reposition) {
+                                                       self._moveOnLeft();
+                                               }
+                                               break;
+                                       case KEY_CODES.right:
+                                               if (self._reposition) {
+                                                       self._moveOnRight();
+                                               }
+                                               break;
+                                       case KEY_CODES.enter:
+                                               // @TODO context enter
+                                               // re-enter in reposition mode back from reposition (position confirm by enter)
+                                               if (event.target === this.element) {
+                                                       self._toggleRepositionMode(!self._reposition);
+                                               }
+                                               break;
+                                       case KEY_CODES.escape:
+                                               // this also is done by hwkey
+                                               self._toggleRepositionMode(false);
+                                               break;
+                                       default:
+                                               return;
+                               }
+                       }
+
+                       prototype._toggleRepositionMode = function (enable) {
+                               var self = this;
+
+                               if (enable) {
+                                       self.element.classList.add("ui-floatingactions-reposition");
+                                       self.disableFocusableElements(self.element);
+                               } else {
+                                       self.element.classList.remove("ui-floatingactions-reposition");
+                                       self.enableDisabledFocusableElements(self.element);
+                               }
+                               self._reposition = enable;
+                       }
+
+                       /**
+                        * @static
+                        */
+                       prototype._focus = function (element) {
+                               if (!element.hasAttribute("tabindex")) {
+                                       element.setAttribute("tabindex", 0);
+                               }
+                               element.classList.add("ui-focus");
+                               element.focus();
+                       }
+
+                       /**
+                        * @static
+                        */
+                       prototype._blur = function (element) {
+                               if (element.hasAttribute("tabindex")) {
+                                       element.removeAttribute("tabindex", 0);
+                               }
+                               element.classList.remove("ui-focus");
+                       }
+
+                       /**
+                        * Handle events
+                        * @method handleEvent
+                        * @public
+                        * @param {Event} event Event
+                        * @member ns.widget.mobile.FloatingActions
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "dragstart":
+                                               self._start(event);
+                                               break;
+                                       case "drag":
+                                               self._move(event);
+                                               break;
+                                       case "dragend":
+                                       case "dragcancel":
+                                               self._end(event);
+                                               break;
+                                       case "keyup":
+                                               self._onkeyup(event);
+                                               break;
+                               }
+                       };
+
+                       prototype.onAttach = function () {
+                               this.refresh();
+                       };
+
+                       // definition
+                       FloatingActions.prototype = prototype;
+                       FloatingActions.classes = classes;
+                       ns.widget.mobile.FloatingActions = FloatingActions;
+
+                       engine.defineWidget(
+                               "FloatingActions",
+                               "[data-role='floatingactions'], ." + WIDGET_CLASS,
+                               [],
+                               FloatingActions,
+                               "mobile"
+                       );
+
+                       }(window.document, ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/**
+ * #Spin
+ *
+ * @class ns.widget.core.Spin
+ * @since 1.2
+ * @extends ns.widget.core.BaseWidget
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+/**
+ * Main file of applications, which connect other parts
+ */
+// then we can load plugins for libraries and application
+(function (window, ns) {
+       "use strict";
+                       var document = window.document,
+                       BaseWidget = ns.widget.BaseWidget,
+                       Page = ns.widget.core.Page,
+                       Appbar = ns.widget.core.Appbar,
+                       engine = ns.engine,
+                       utilsEvents = ns.event,
+                       gesture = utilsEvents.gesture,
+                       utilSelectors = ns.util.selectors,
+
+                       Animation = ns.util.Animate,
+
+                       ENABLING_DURATION = 300, // [ms]
+                       ROLL_DURATION = 600,
+                       DELTA_Y = 100,
+                       DRAG_STEP_TO_VALUE = 60,
+                       NUMBER_OF_CAROUSEL_ITEMS = 13,
+                       EVENT_DRAG_END_TIMEOUT = 500,
+
+                       /**
+                        * Alias for class Spin
+                        * @method Spin
+                        * @member ns.widget.core.Spin
+                        * @private
+                        * @static
+                        */
+                       Spin = function () {
+                               var self = this;
+
+                               /**
+                                * Object with default options
+                                * @property {Object} options
+                                * @property {number} options.min minimum value of spin
+                                * @property {number} options.max maximum value of spin
+                                * @property {number} options.step step of decrease / increase value
+                                * @property {string} [options.moduloValue="enabled"] value will be show as modulo
+                                *  // if enabled then value above max will be show as modulo eg. 102
+                                *  // with range 0-9 will be show as 2 (12 % 10)
+                                * @property {string} [options.shortPath="enabled"] spin rotate with short path
+                                *  // eg. when value will be 1 and then will change to 8
+                                *  // the spin will rotate by 1 -> 0 -> 9 -> 8
+                                * @property {number} [options.duration=ROLL_DURATION] time of rotate to indicated value
+                                * @property {string} [options.direction="up"] direction of spin rotation
+                                * @property {string} [options.rollHeight="custom"] size of frame to rotate one item
+                                * @property {number} [options.itemHeight=38] size of frame for "custom" rollHeight
+                                * @property {number} [options.momentumLevel=0] define momentum level on drag
+                                * @property {number} [options.scaleFactor=0.4] second / next items scale factor
+                                * @property {number} [options.moveFactor=0.4] second / next items move factor from center
+                                * @property {number} [options.loop="enabled"] when the spin reaches max value then loops to min value
+                                * @property {string} [options.labels=""] defines labels for values likes days of week separated by ","
+                                * // eg. "Monday,Tuesday,Wednesday"
+                                * @property {string} [options.digits=0] value filling with zeros, eg. 002 for digits=3;
+                                * @property {string} [options.dragTarget="document"] set target element for drag gesture
+                                * @member ns.widget.core.Spin
+                                */
+                               self.options = {
+                                       min: 0,
+                                       max: 9,
+                                       step: 1,
+                                       moduloValue: "enabled",
+                                       shortPath: "enabled",
+                                       duration: ROLL_DURATION,
+                                       direction: "up",
+                                       rollHeight: "custom", // "container" | "item" | "custom"
+                                       itemHeight: 38,
+                                       momentumLevel: 0, // 0 - one item on swipe,
+                                       momentumDuration: 800,
+                                       scaleFactor: 0.4,
+                                       moveFactor: 0.4,
+                                       loop: "enabled",
+                                       labels: [],
+                                       digits: 0, // 0 - doesn't complete by zeros
+                                       value: 0,
+                                       dragTarget: "document", // "document" | "self",
+                                       enabled: false
+                               };
+                               self._ui = {
+                                       scrollableParent: null,
+                                       page: null,
+                                       appbar: null
+                               };
+                               self._carouselItems = [];
+                               self._numberOfCarouselItems = NUMBER_OF_CAROUSEL_ITEMS;
+                               self.length = self.options.max - self.options.min + self.options.step;
+                               self._prevValue = null; // self property has to be "null" on start
+                               self._overflowYBeforeDrag = null;
+                               self._lastCurrentIndex = null;
+                               self._currentCentralCarouseItem = 0;
+                               self._count = 0;
+                               self._dragTimeoutHandler = null;
+                       },
+
+                       WIDGET_CLASS = "ui-spin",
+
+                       classes = {
+                               SPIN: WIDGET_CLASS,
+                               PREFIX: WIDGET_CLASS + "-",
+                               ITEM: WIDGET_CLASS + "-item",
+                               SELECTED: WIDGET_CLASS + "-item-selected",
+                               NEXT: WIDGET_CLASS + "-item-next",
+                               PREV: WIDGET_CLASS + "-item-prev",
+                               ENABLED: "enabled",
+                               ENABLING: WIDGET_CLASS + "-enabling",
+                               PLACEHOLDER: WIDGET_CLASS + "-placeholder",
+                               CAROUSEL: WIDGET_CLASS + "-carousel",
+                               CAROUSEL_ITEM: WIDGET_CLASS + "-carousel-item"
+                       },
+
+                       prototype = new BaseWidget();
+
+               Spin.classes = classes;
+               Spin.timing = Animation.timing;
+
+               prototype._fillCarouselByCount = function (count) {
+                       var self = this,
+                               itemToAppend,
+                               diff,
+                               restDiff,
+                               i;
+
+                       count = Math.round(count);
+                       // remove all items
+                       for (i = 0; i < self._numberOfCarouselItems; i++) {
+                               if (self._carouselItems[i].element.firstElementChild) {
+                                       self._carouselItems[i].element.removeChild(self._carouselItems[i].element.firstElementChild);
+                               }
+                       }
+
+                       // for case of count of items is less then carousel items
+                       diff = self._numberOfCarouselItems - self.length;
+                       if (diff < 0) {
+                               diff = 0;
+                       }
+
+                       // append new items
+                       i = Math.floor(diff / 2);
+                       restDiff = diff - i;
+                       for (; i < self._numberOfCarouselItems - restDiff; i++) {
+                               itemToAppend = self._itemByCount(count + i - self._carouselCenterIndex);
+                               if (itemToAppend) {
+                                       self._carouselItems[self._carouselItemByCount(count + i - self._carouselCenterIndex)]
+                                               .element.appendChild(itemToAppend);
+                               }
+                       }
+               };
+
+               prototype._rollItems = function (delta, count) {
+                       var self = this,
+                               direction = delta > 0 ? 1 : -1,
+                               borderItem,
+                               newItemToPlace;
+
+                       delta = Math.abs(delta);
+                       if (delta === 1) { // move one item
+                               borderItem = self._carouselItems[
+                                       self._carouselItemByCount(count + direction * self._carouselCenterIndex)
+                               ];
+                               newItemToPlace = self._itemByCount(count + direction * self._carouselCenterIndex);
+
+                               if (borderItem.element.firstElementChild) {
+                                       borderItem.element.removeChild(borderItem.element.firstElementChild);
+                               }
+                               if (newItemToPlace) {
+                                       borderItem.element.appendChild(newItemToPlace);
+                               }
+                       } else if (delta > 1) {
+                               self._fillCarouselByCount(count);
+                       }
+               }
+
+               function transform(value, index, centerY, options, self) {
+                       var diff,
+                               direction,
+                               diffAbs,
+                               scale,
+                               moveY,
+                               opacity,
+                               count = value,
+                               currentIndex = self._carouselItemByCount(count);
+
+                       // change carousel items content on change current index
+                       if (self._lastCurrentIndex !== Math.round(value)) {
+                               if (self._lastCurrentIndex !== null) {
+                                       self._rollItems(Math.round(value) - self._lastCurrentIndex, Math.round(value));
+                               }
+                               self._lastCurrentIndex = Math.round(value);
+                       }
+
+                       diff = index - currentIndex;
+                       if (diff < -self._carouselCenterIndex) {
+                               diff += self._numberOfCarouselItems;
+                       } else if (diff > self._carouselCenterIndex) {
+                               diff -= self._numberOfCarouselItems;
+                       }
+
+                       direction = diff < 0 ? -1 : 1;
+                       diffAbs = Math.abs(diff);
+
+                       scale = 1 - options.scaleFactor * diffAbs;
+                       moveY = 1 - options.moveFactor * diffAbs;
+                       opacity = 1 - ((options.enabled) ? options.scaleFactor : 1) * diffAbs;
+
+                       scale = (scale < 0) ? 0 : scale;
+                       opacity = (opacity < 0) ? 0 : opacity;
+                       moveY = direction * (DELTA_Y * (1 - moveY)) + centerY;
+
+                       return {
+                               moveY: moveY,
+                               scale: scale,
+                               opacity: opacity
+                       }
+               }
+
+
+               function showAnimationTick(self) {
+                       var carouselItems = self._carouselItems,
+                               options = self.options,
+                               itemHeight = self._itemHeight,
+                               state = self._objectValue,
+                               centerY = (self._containerHeight - itemHeight) / 2;
+
+                       carouselItems.forEach(function (carouselItem, index) {
+                               var change = transform(state.value, index, centerY, options, self);
+
+                               // set carouselItem position
+                               if (change.opacity > 0) {
+                                       carouselItem.element.style.transform = "translateY(" + change.moveY + "px) scale(" + change.scale + ")";
+                               } else {
+                                       carouselItem.element.style.transform = "translateY(-1000px)"; // move carouselItem from active area
+                               }
+                               carouselItem.element.style.opacity = change.opacity;
+                       });
+
+                       ns.event.trigger(self.element, "spinstep", parseInt(state.value, 10));
+               }
+
+               prototype._removeSelectedLayout = function () {
+                       var self = this,
+                               item = self._itemByCount(self._previousCount);
+
+                       if (item) {
+                               item.classList.remove(classes.SELECTED);
+                       }
+               };
+
+               prototype._addSelectedLayout = function () {
+                       var self = this,
+                               item = self._itemByCount(self._count);
+
+                       if (item) {
+                               item.classList.add(classes.SELECTED);
+                       }
+               };
+
+               prototype._show = function () {
+                       var self = this,
+                               animation = new Animation({}),
+                               state = null,
+                               objectValue = {
+                                       value: self._previousCount
+                               };
+
+                       self._removeSelectedLayout();
+
+                       state = {
+                               animation: [{
+                                       object: objectValue,
+                                       property: "value",
+                                       to: self._count
+                               }],
+                               animationConfig: {
+                                       // when widget is disabled then duration of animation should be minimal
+                                       duration: (self.options.enabled) ? self.options.duration : 1,
+                                       timing: Spin.timing.ease
+                               }
+                       };
+                       self.state = state;
+                       self._objectValue = objectValue;
+                       self._animation = animation;
+
+                       animation.set(state.animation, state.animationConfig);
+                       animation.tick(showAnimationTick.bind(null, self));
+                       animation.start(function () {
+                               self._addSelectedLayout();
+                               self._prevValue = self.options.value;
+                               self.options.value = self._getValueByCount(self._count);
+
+                               ns.event.trigger(self.element, "spinchange", {
+                                       value: parseInt(self.options.value, 10),
+                                       dValue: parseInt(self.options.value, 10) - parseInt(self._prevValue, 10)
+                               });
+                       });
+
+               };
+
+               prototype._modifyItems = function () {
+                       var self = this,
+                               options = self.options,
+                               itemHeight = 0,
+                               items = [],
+                               len = Math.abs(options.max - options.min) / options.step + 1,
+                               index = 0,
+                               textValue = "",
+                               centerY,
+                               item = null,
+                               i = 0;
+
+                       // remove previous
+                       self._ui.items = items;
+
+                       // add new items
+                       for (; i < len; i++) {
+                               item = document.createElement("div");
+                               item.classList.add(classes.ITEM);
+                               items.push(item);
+                       }
+
+                       // set content for new items
+                       for (index = 0; index < len; index++) {
+                               item = items[index];
+                               textValue = "";
+
+                               if (self.options.labels.length) {
+                                       textValue = self.options.labels[index];
+                               } else {
+                                       textValue += (options.min + index * options.step);
+                                       if (options.digits > 0) {
+                                               while (textValue.length < options.digits) {
+                                                       textValue = "0" + textValue;
+                                               }
+                                       }
+                               }
+                               item.innerHTML = textValue;
+                       }
+
+                       // determine item height for scroll
+                       if (options.rollHeight === "container") {
+                               itemHeight = self._containerHeight;
+                       } else if (options.rollHeight === "custom") {
+                               itemHeight = options.itemHeight;
+                       } else { // item height
+                               item = items[0];
+                               itemHeight = (item) ?
+                                       item.getBoundingClientRect().height :
+                                       self._containerHeight;
+                       }
+                       self._itemHeight = itemHeight;
+                       centerY = (self._containerHeight - itemHeight) / 2;
+
+                       // set position of carousel items;
+                       self._carouselItems.forEach(function (carouselItem, index) {
+                               var change = transform(self._valueToCount(options.value), index, centerY, options, self);
+
+                               // set carouselItem position
+                               carouselItem.element.style.transform = "translateY(" + change.moveY + "px) scale(" + change.scale + ")";
+                               carouselItem.element.style.opacity = change.opacity;
+                       });
+               };
+
+               prototype._setItemHeight = function (element, value) {
+                       value = (typeof value === "string") ? parseInt(value.replace("px").trim(), 10) : value;
+                       this.options.itemHeight = value;
+               };
+
+               /**
+                * Update items
+                * @method _updateItems
+                * @member ns.widget.core.Spin
+                * @protected
+                */
+               prototype._updateItems = function () {
+                       var self = this;
+
+                       self._removeSelectedLayout();
+                       self._modifyItems();
+                       self._addSelectedLayout();
+               }
+
+               prototype._refresh = function () {
+                       var self = this,
+                               computedHeight = getComputedStyle(self.element).height || 0;
+
+                       self._containerHeight = parseInt(computedHeight, 10);
+                       self._modifyItems();
+                       self._fillCarouselByCount(self._count);
+                       self._show();
+               };
+
+               /**
+                * Widget init method
+                * @protected
+                * @method _init
+                * @member ns.widget.core.Spin
+                */
+               prototype._init = function () {
+                       var self = this,
+                               options = self.options;
+
+                       // convert options
+                       options.min = (options.min !== undefined) ? parseInt(options.min, 10) : 0;
+                       options.max = (options.max !== undefined) ? parseInt(options.max, 10) : 0;
+                       options.value = (options.value !== undefined) ? parseInt(options.value, 10) : 0;
+                       options.step = (options.step !== undefined) ? parseInt(options.step, 10) : 1;
+                       options.duration = (options.duration !== undefined) ? parseInt(options.duration, 10) : 0;
+                       options.labels = (Array.isArray(options.labels)) ? options.labels : options.labels.split(",");
+
+                       self.length = options.max - options.min + options.step;
+                       self._count = self._valueToCount(options.value);
+
+                       self.dragTarget = (options.dragTarget === "document") ? document : self.element;
+
+                       self._refresh();
+               };
+
+               prototype._buildCarousel = function (count) {
+                       // create carousel
+                       var self = this,
+                               carousel = document.createElement("div"),
+                               carouselElement,
+                               fragment = document.createDocumentFragment(),
+                               i = 0;
+
+                       self._carouselItems = [];
+                       self._numberOfCarouselItems = count;
+                       self._carouselCenterIndex = Math.floor(count / 2)
+
+                       carousel.classList.add(classes.CAROUSEL, classes.PREFIX + count);
+                       for (; i < count; i++) {
+                               carouselElement = document.createElement("div");
+                               carouselElement.id = "cel-" + i;
+                               carouselElement.classList.add(classes.CAROUSEL_ITEM);
+                               self._carouselItems[i] = {
+                                       element: carouselElement
+                               };
+                               fragment.appendChild(carouselElement);
+                       }
+                       carousel.appendChild(fragment);
+                       return carousel;
+               };
+
+               prototype._build = function (element) {
+                       var placeholder = document.createElement("div"),
+                               carousel = null,
+                               self = this;
+
+                       element.classList.add(classes.SPIN);
+
+                       placeholder.classList.add(classes.PLACEHOLDER);
+                       element.appendChild(placeholder);
+
+                       carousel = self._buildCarousel(self._numberOfCarouselItems);
+                       element.appendChild(carousel);
+
+                       self._ui.carousel = carousel;
+                       self._ui.placeholder = placeholder;
+
+                       return element;
+               };
+
+               prototype._valueToCount = function (value) {
+                       var self = this;
+
+                       return (value - self.options.min) / self.options.step || 0;
+               };
+
+               prototype._setValue = function (value) {
+                       var self = this;
+
+                       value = window.parseFloat(value, 10);
+                       // @todo: for spin with labels the textContent should contains label by value;
+                       self._ui.placeholder.textContent = value;
+
+                       if (isNaN(value)) {
+                               ns.warn("Spin: value is not a number");
+                       } else {
+                               if ((value < self.options.min || value > self.options.max) && self.options.loop === "disabled") {
+                                       value = Math.min(Math.max(value, self.options.min), self.options.max);
+                               }
+                               if (value !== self.options.value) {
+                                       self._previousCount = self._count;
+                                       self._count = self._valueToCount(value);
+
+                                       self.options.value = value;
+                                       // set data-value on element
+                                       self.element.dataset.value = value;
+
+                                       // stop previous animation
+                                       self._stopAnimation();
+
+                                       // update status of widget
+                                       self._show();
+                               }
+                       }
+               };
+
+               prototype._stopAnimation = function () {
+                       var self = this,
+                               animation = self.state.animation[0];
+
+                       if (animation !== null && animation.to !== animation.current) {
+                               self._animation.stop();
+                       }
+               };
+
+               prototype._carouselItemByCount = function (count) {
+                       var centerIndex = this._carouselCenterIndex,
+                               carouselItemIndex = (count + centerIndex) % this._numberOfCarouselItems;
+
+                       if (carouselItemIndex < 0) {
+                               carouselItemIndex += this._numberOfCarouselItems;
+                       }
+
+                       return carouselItemIndex;
+               };
+
+               prototype._getValueByCount = function (count) {
+                       var value,
+                               self = this,
+                               options = self.options,
+                               rest;
+
+                       if (options.loop !== "enabled") {
+                               value = count * options.step + options.min;
+                       } else {
+                               if (count >= 0) {
+                                       value = (count % self.length) * options.step + options.min;
+                               } else {
+                                       rest = count % self.length || 0;
+                                       if (rest < 0) {
+                                               rest += self.length;
+                                       }
+                                       value = rest * options.step + options.min;
+                               }
+                       }
+                       return value;
+               };
+
+               prototype._getValue = function () {
+                       var self = this,
+                               options = self.options,
+                               value = self._getValueByCount(self._count);
+
+                       if (self.options.loop !== "enabled") {
+                               self._objectValue.value = Math.min(Math.max(value, options.min), options.max);
+                       }
+                       return value;
+               };
+
+               prototype._setMax = function (element, max) {
+                       var options = this.options;
+
+                       options.max = (max !== undefined) ? parseInt(max, 10) : 0;
+                       this.length = options.max - options.min + options.step;
+               };
+
+               prototype._setMin = function (element, min) {
+                       var options = this.options;
+
+                       options.min = (min !== undefined) ? parseInt(min, 10) : 0;
+                       this.length = options.max - options.min + options.step;
+               };
+
+               prototype._setLabels = function (element, value) {
+                       var self = this;
+
+                       self.options.labels = value.split(",");
+                       self._refresh();
+               };
+
+               prototype._setModuloValue = function (element, value) {
+                       this.options.moduloValue = (value === "enabled") ? "enabled" : "disabled";
+               };
+
+               prototype._setShortPath = function (element, value) {
+                       this.options.shortPath = (value === "enabled") ? "enabled" : "disabled";
+               };
+
+               prototype._setLoop = function (element, value) {
+                       this.options.loop = (value === "enabled") ? "enabled" : "disabled";
+               };
+
+               prototype._setDuration = function (element, value) {
+                       this.options.duration = window.parseInt(value, 10);
+               };
+
+               prototype._setEnabled = function (element, value) {
+                       var self = this;
+
+                       self.options.enabled = (value === "false") ? false : value;
+                       if (self.options.enabled) {
+                               element.classList.add(classes.ENABLING);
+                               window.setTimeout(function () {
+                                       element.classList.remove(classes.ENABLING);
+                               }, ENABLING_DURATION);
+                               element.classList.add(classes.ENABLED);
+                               utilsEvents.on(self.dragTarget, "drag dragend dragstart", self);
+                               utilsEvents.on(self.dragTarget, "vmousedown vmouseup", self);
+                       } else {
+                               element.classList.add(classes.ENABLING);
+                               window.setTimeout(function () {
+                                       element.classList.remove(classes.ENABLING);
+                                       self.refresh();
+                               }, ENABLING_DURATION);
+                               element.classList.remove(classes.ENABLED);
+                               utilsEvents.off(self.dragTarget, "drag dragend dragstart", self);
+                               utilsEvents.off(self.dragTarget, "vmousedown vmouseup", self);
+                               // disable animation
+                               self._animation.stop();
+                       }
+                       // reset previous value;
+                       this._prevValue = null;
+                       return true;
+               };
+
+               prototype._setDirection = function (element, direction) {
+                       this.options.direction = (["up", "down"].indexOf(direction) > -1) ? direction : "up";
+               };
+
+               prototype._drag = function (e) {
+                       var self = this;
+
+                       // if element is detached from DOM then event listener should be removed
+                       if (document.getElementById(self.element.id) === null) {
+                               utilsEvents.off(self.dragTarget, "drag dragend dragstart", self);
+                       } else {
+                               if (self.options.enabled) {
+                                       self._objectValue.value = self._startDragCount - e.detail.deltaY / DRAG_STEP_TO_VALUE;
+                                       if (self.options.loop !== "enabled") {
+                                               self._objectValue.value = Math.min(Math.max(self._objectValue.value, 0), self.length - 1);
+                                       }
+                                       showAnimationTick(self);
+                               }
+                       }
+                       // set timeout in case of drag outside screen
+                       window.clearTimeout(self._dragTimeoutHandler);
+                       self._dragTimeoutHandler = window.setTimeout(function () {
+                               self._dragEnd({
+                                       detail: {
+                                               velocityY: e.velocityY,
+                                               distance: e.distance,
+                                               direction: e.direction
+                                       }
+                               });
+                               self._dragTimeoutHandler = null;
+                               ns.event.gesture.Manager.getInstance().resetDetecting();
+                       }, EVENT_DRAG_END_TIMEOUT);
+               };
+
+               prototype._dragStart = function () {
+                       var self = this;
+
+                       self._animation.pause();
+                       self._startDragCount = self._count;
+                       self._previousCount = self._count;
+                       self._removeSelectedLayout();
+               };
+
+               prototype._dragEnd = function (e) {
+                       var self = this,
+                               chain = self._animation._animate.chain[0],
+                               momentum = 0,
+                               duration = self.options.duration;
+
+                       window.clearTimeout(self._dragTimeoutHandler);
+
+                       if (self.options.momentumLevel > 0 &&
+                               e.detail.velocityY > 0.7 &&
+                               e.detail.distance) {
+
+                               momentum = self.options.momentumLevel * Math.round(e.detail.distance / 20);
+                               if (e.detail.direction === "up") {
+                                       momentum = -momentum;
+                               }
+                               self._count = Math.round(self._objectValue.value) - momentum || 0;
+                               if (self.options.loop !== "enabled") {
+                                       self._count = Math.min(Math.max(self._count, 0), self.length - 1);
+                               }
+                               duration = self.options.momentumDuration;
+                               chain[0].timing = Spin.timing.easeOut;
+                       } else {
+                               self._count = Math.round(self._objectValue.value) || 0;
+                               if (self.options.loop !== "enabled") {
+                                       self._count = Math.min(Math.max(self._count, 0), self.length - 1);
+                               }
+                               duration = Math.abs(self._count - self._objectValue.value) * duration;
+                       }
+
+                       chain[0].from = self._objectValue.value;
+                       // @todo: move to nearest
+                       chain[0].to = self._count;
+                       chain[0].duration = duration;
+                       self._animation.start(self._animation._animate.callback);
+               };
+
+               /**
+                * Handler for mouse down / touch start event
+                * The method is intended to block the scroll during drag event on Spin widget
+                * @protected
+                * @method _vmouseDown
+                * @member ns.widget.core.Spin
+                */
+               prototype._vmouseDown = function () {
+                       var self = this,
+                               ui = self._ui;
+
+                       ui.scrollableParent = utilSelectors.getScrollableParent(self.element);
+                       if (ui.scrollableParent) {
+                               self._overflowYBeforeDrag = ui.scrollableParent.style.overflowY;
+                               ui.scrollableParent.style.overflowY = "hidden";
+                       }
+                       ui.page = utilSelectors.getClosestBySelector(self.element, Page.selector);
+                       if (ui.page) {
+                               ui.appbar = ui.page.querySelector(Appbar.selector);
+                               if (ui.appbar) {
+                                       ns.widget.Appbar(ui.appbar).lockExpanding(true);
+                               }
+                       }
+               };
+
+               /**
+                * Handler for mouse up / touch end event
+                * The method is intended to unblock the scroll after drag event on Spin widget
+                * @protected
+                * @method _vmouseUp
+                * @member ns.widget.core.Spin
+                */
+               prototype._vmouseUp = function () {
+                       var self = this,
+                               ui = self._ui;
+
+                       if (ui.scrollableParent) {
+                               ui.scrollableParent.style.overflowY = self._overflowYBeforeDrag;
+                       }
+                       if (ui.appbar) {
+                               ns.widget.Appbar(ui.appbar).lockExpanding(false);
+                       }
+               };
+
+               prototype._itemIndexByValue = function (value) {
+                       var options = this.options;
+
+                       return Math.round((value - options.min) / options.step);
+               };
+
+               prototype._itemByCount = function (count) {
+                       var self = this,
+                               value = self._getValueByCount(count);
+
+                       return self._ui.items[self._itemIndexByValue(value)];
+               };
+
+               prototype._click = function (e) {
+                       var self = this,
+                               target = e.target,
+                               items = self._ui.items,
+                               count = self._count,
+                               targetIndex = items.indexOf(target);
+
+                       if (!self.element.classList.contains(classes.ENABLING) &&
+                               targetIndex > -1) {
+                               self._previousCount = count;
+
+                               if (target === self._itemByCount(count - 1)) {
+                                       self._count--;
+                               } else if (target === self._itemByCount(count + 1)) {
+                                       self._count++;
+                               }
+                               if (self._previousCount !== self._count) {
+                                       self._show();
+                               }
+                       }
+               }
+
+               prototype.handleEvent = function (event) {
+                       var self = this;
+
+                       switch (event.type) {
+                               case "drag":
+                                       self._drag(event);
+                                       break;
+                               case "vmousedown":
+                                       self._vmouseDown(event);
+                                       break;
+                               case "vmouseup":
+                                       self._vmouseUp(event);
+                                       break;
+                               case "dragend":
+                                       self._dragEnd(event);
+                                       break;
+                               case "dragstart":
+                                       self._dragStart(event);
+                                       break;
+                               case "vclick":
+                                       self._click(event);
+                                       break;
+                       }
+               };
+
+               prototype._bindEvents = function () {
+                       var self = this;
+
+                       // enabled drag gesture for document
+                       utilsEvents.enableGesture(self.dragTarget, new gesture.Drag({
+                               blockHorizontal: true,
+                               threshold: 7 // minimal allowed value from Drag module
+                       }));
+
+                       utilsEvents.on(self.element, "vclick", self);
+               };
+
+               prototype._unbindEvents = function () {
+                       var self = this;
+
+                       utilsEvents.disableGesture(self.dragTarget);
+
+                       utilsEvents.off(self.dragTarget, "drag dragend dragstart", self);
+                       utilsEvents.off(self.element, "vclick", self);
+               };
+
+               /**
+                * Destroy widget instance
+                * @protected
+                * @method _destroy
+                * @member ns.widget.core.Spin
+                * @protected
+                */
+               prototype._destroy = function () {
+                       var self = this,
+                               element = self.element,
+                               ui = self._ui;
+
+                       self._unbindEvents();
+                       ui.items.forEach(function (item) {
+                               if (item.parentNode) {
+                                       item.parentNode.removeChild(item);
+                               }
+                       });
+                       self._carouselItems.forEach(function (carouselItem) {
+                               carouselItem.element.parentNode.removeChild(carouselItem.element);
+                       });
+                       element.removeChild(ui.carousel);
+                       element.removeChild(ui.placeholder);
+                       element.classList.remove(classes.SPIN);
+               };
+
+               Spin.prototype = prototype;
+               ns.widget.core.Spin = Spin;
+
+               engine.defineWidget(
+                       "Spin",
+                       ".ui-spin",
+                       [],
+                       Spin,
+                       "core"
+               );
+
+               
+})(window, ns);
+
+/*global define, ns */
+/*jslint nomen: true, plusplus: true */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+/**
+ * #Spin
+ *
+ * @class ns.widget.mobile.Spin
+ * @since 1.2
+ * @extends ns.widget.core.BaseWidget
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ * @author Hunseop Jeong <hs85.jeong@samsung.com>
+ */
+(function (window, ns) {
+       "use strict";
+                       var CoreSpin = ns.widget.core.Spin,
+                       CoreSpinPrototype = CoreSpin.prototype,
+                       engine = ns.engine,
+                       objectUtil = ns.util.object,
+                       classes = objectUtil.copy(CoreSpin.classes),
+                       Spin = function () {
+                               var self = this,
+                                       options = {
+                                               scaleFactor: 0,
+                                               moveFactor: 0.5,
+                                               itemHeight: 54,
+                                               dragTarget: "self"
+                                       };
+
+                               CoreSpin.call(self);
+
+                               // Merge options from prototype
+                               self.options = (!self.options) ?
+                                       options :
+                                       objectUtil.fastMerge(self.options, options);
+                       },
+                       prototype = new CoreSpin();
+
+               prototype._init = function () {
+                       var self = this;
+
+                       CoreSpinPrototype._init.call(self);
+
+                       // Enable the spin by default
+                       self.option("enabled", true);
+               }
+
+               Spin.prototype = prototype;
+               Spin.classes = classes;
+               Spin.timing = CoreSpin.timing;
+
+               ns.widget.mobile.Spin = Spin;
+
+               engine.defineWidget(
+                       "Spin",
+                       ".ui-spin",
+                       [],
+                       Spin,
+                       "mobile",
+                       true
+               );
+
+               
+})(window, ns);
+
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* global define */
+/**
+ * # TimePicker Widget
+ * Shows a control that can be used to set hours and minutes.
+ * It support 12/24 hours format. It contains two inputs which control the values
+ *
+ * ## Default selectors
+ *
+ * Default selector for timepicker is class *ui-time-picker*
+ *
+ * ### HTML Examples
+ *
+ * #### 12 hours format
+ * To add a timepicker widget to the application, use the following code:
+ *
+ *      @example
+ *      <div class="ui-time-picker" data-format="12">
+ *
+ * #### 24 hours format
+ * To add a timepicker widget to the application, use the following code:
+ *
+ *      @example
+ *      <div class="ui-time-picker" data-format="24">
+ *
+ * @class ns.widget.mobile.TimePicker
+ * @since 1.2
+ * @component-selector .ui-time-picker
+ * @extends ns.widget.mobile.TimePicker
+ * @author Hunseop Jeong <hs85.jeong@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               engine = ns.engine,
+                               utilsEvents = ns.event,
+                               getClosestByClass = ns.util.selectors.getClosestByClass,
+                               Spin = ns.widget.mobile.Spin,
+                               WIDGET_CLASS = "ui-time-picker",
+                               classes = {
+                                       CONTAINER: WIDGET_CLASS + "-container",
+                                       HOUR_CONTAINER: WIDGET_CLASS + "-container-hour",
+                                       MINUTE_CONTAINER: WIDGET_CLASS + "-container-minute",
+                                       FORMAT_CONTAINER: WIDGET_CLASS + "-container-format",
+                                       ACTIVE_CONTAINER: WIDGET_CLASS + "-container-active",
+                                       TIME_INPUT: WIDGET_CLASS + "-input",
+                                       TIME_INPUT_ACTIVE: WIDGET_CLASS + "-input-active"
+                               },
+                               WIDGET_SELECTOR = "." + WIDGET_CLASS,
+                               TimePicker = function () {
+                                       this.options = {
+                                               format: "12"
+                                       };
+
+                                       this._spins = {
+                                               hour: null,
+                                               minute: null,
+                                               format: null
+                                       };
+
+                                       this._ui = {};
+                                       this._previousInputValue = -1;
+                                       // Variable to check the current state of input element (false: first, true: second)
+                                       this._inputValueState = false;
+                               },
+                               prototype = new BaseWidget();
+
+                       TimePicker.classes = classes;
+
+                       /**
+                       * Init method
+                       * @method _init
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._init = function () {
+                               var self = this,
+                                       options = self.options;
+
+                               options.format = (options.format !== undefined) ? options.format : "12";
+
+                               self._setValue(new Date());
+
+                               self.option("format", options.format);
+
+                               // Calculate the spin widget after building the widget
+                               Object.keys(self._spins).forEach(function (key) {
+                                       self._spins[key].refresh();
+                               });
+                       };
+
+                       /**
+                       * Build widget instance
+                       * @method _build
+                       * @param {HTMLElement} element
+                       * @return {HTMLElement} Builded element
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       hourPicker = self._buildTimePicker("hour"),
+                                       minutePicker = self._buildTimePicker("minute"),
+                                       formatPicker = self._buildFormat();
+
+                               element.appendChild(hourPicker);
+                               element.appendChild(minutePicker);
+                               element.appendChild(formatPicker);
+
+                               return element;
+                       };
+
+                       /**
+                       * Build Spin Widget for the time
+                       * @method _buildTimePicker
+                       * @param {string} name
+                       * @return {HTMLElement} container for time spin
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._buildTimePicker = function (name) {
+                               var self = this,
+                                       ui = self._ui,
+                                       spin = document.createElement("div"),
+                                       spinInput = document.createElement("input"),
+                                       spinContainer = document.createElement("div"),
+                                       options = {
+                                               momentumLevel: 1
+                                       },
+                                       spinWidget;
+
+                               spin.classList.add(Spin.classes.SPIN);
+                               spinContainer.classList.add(TimePicker.classes.CONTAINER);
+
+                               if (name === "hour") {
+                                       if (self.options.format === "24") {
+                                               options.min = 0;
+                                               options.max = 23;
+                                       } else {
+                                               options.min = 1;
+                                               options.max = 12;
+                                       }
+                                       spinContainer.classList.add(TimePicker.classes.HOUR_CONTAINER);
+                               } else if (name === "minute") {
+                                       options.min = 0;
+                                       options.max = 59;
+                                       options.digits = 2;
+                                       spinContainer.classList.add(TimePicker.classes.MINUTE_CONTAINER);
+                               }
+
+                               spinInput.min = options.min;
+                               spinInput.max = options.max;
+                               spinInput.type = "number";
+                               spinInput.step = "1";
+                               spinInput.classList.add(TimePicker.classes.TIME_INPUT);
+
+                               spin.appendChild(spinInput);
+                               spinContainer.appendChild(spin);
+
+                               ui[name + "Spin"] = spin;
+                               ui[name + "Input"] = spinInput;
+                               ui[name + "Container"] = spinContainer;
+
+                               spinWidget = ns.widget.Spin(spin, options);
+                               self._spins[name] = spinWidget;
+
+                               return spinContainer;
+                       };
+
+                       /**
+                       * Build Spin Widget for the format
+                       * @method _buildFormat
+                       * @return {HTMLElement} container for format spin
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._buildFormat = function () {
+                               var self = this,
+                                       spin = document.createElement("div"),
+                                       spinContainer = document.createElement("div"),
+                                       options = {
+                                               min: 0,
+                                               max: 1,
+                                               labels: "AM,PM",
+                                               loop: "false"
+                                       },
+                                       spinWidget;
+
+                               spin.classList.add(Spin.classes.SPIN);
+                               spinContainer.classList.add(TimePicker.classes.CONTAINER);
+                               spinContainer.classList.add(TimePicker.classes.FORMAT_CONTAINER);
+                               spinContainer.appendChild(spin);
+
+                               spinWidget = ns.widget.Spin(spin, options);
+                               self._spins.format = spinWidget;
+
+                               return spinContainer;
+                       };
+
+                       /**
+                       * Set the value for Date object
+                       * @method _setDateValue
+                       * @param {Date} value
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._setDateValue = function (value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       spins = self._spins,
+                                       hours,
+                                       minutes;
+
+                               hours = value.getHours();
+                               minutes = value.getMinutes();
+
+                               if (self.options.format === "12") {
+                                       if (hours > 12) {
+                                               hours -= 12;
+                                               spins.format.value(1);
+                                       } else {
+                                               spins.format.value(0);
+                                       }
+                               }
+
+                               ui.hourInput.setAttribute("value", hours);
+                               ui.hourInput.value = hours;
+                               ui.minuteInput.setAttribute("value", minutes);
+                               ui.minuteInput.value = minutes;
+
+                               spins.hour.value(hours);
+                               spins.minute.value(minutes);
+                       };
+
+                       /**
+                       * Set the value for the input element
+                       * @method _setInputValue
+                       * @param {string} name
+                       * @param {number} value
+                       * @param {boolean} state
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._setInputValue = function (name, value, state) {
+                               var self = this,
+                                       ui = self._ui,
+                                       spins = self._spins;
+
+                               if (name === "hour") {
+                                       ui.hourInput.setAttribute("value", value);
+                                       ui.hourInput.value = value;
+                                       spins.hour.value(value);
+                               } else if (name === "minute") {
+                                       ui.minuteInput.setAttribute("value", value);
+                                       ui.minuteInput.value = value;
+                                       spins.minute.value(value);
+                               }
+
+                               self._previousInputValue = value;
+                               self._inputValueState = state;
+                       }
+
+                       /**
+                       * Focus input element
+                       * @method _focusInput
+                       * @param {string} name
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._focusInput = function (name) {
+                               var self = this,
+                                       ui = self._ui;
+
+                               if (name === "hour") {
+                                       self.element.classList.add(TimePicker.classes.TIME_INPUT_ACTIVE);
+                                       ui.hourContainer.classList.add(TimePicker.classes.ACTIVE_CONTAINER);
+                                       ui.minuteContainer.classList.remove(TimePicker.classes.ACTIVE_CONTAINER);
+                                       ui.hourInput.focus();
+                                       self._previousInputValue = ui.hourInput.value;
+                               } else if (name === "minute") {
+                                       self.element.classList.add(TimePicker.classes.TIME_INPUT_ACTIVE);
+                                       ui.minuteContainer.classList.add(TimePicker.classes.ACTIVE_CONTAINER);
+                                       ui.hourContainer.classList.remove(TimePicker.classes.ACTIVE_CONTAINER);
+                                       ui.minuteInput.focus();
+                                       self._previousInputValue = ui.minuteInput.value;
+                               }
+
+                               self._inputValueState = false;
+                       }
+
+                       /**
+                       * Set the value of TimePicker
+                       * @method _setValue
+                       * @param {Date} value
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._setValue = function (value) {
+                               var self = this;
+
+                               if (value instanceof Date) {
+                                       self._setDateValue(value);
+                               }
+                       };
+
+                       /**
+                       * Get the value of TimePicker
+                       * @method _getValue
+                       * @return {Date} current time of time picker
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._getValue = function () {
+                               var time = new Date(0),
+                                       self = this,
+                                       spins = self._spins,
+                                       hours = parseInt(spins.hour.value(), 10);
+
+                               if (self.options.format === "12" && spins.format.value() === 1) {
+                                       hours += 12;
+                               }
+
+                               time.setHours(hours);
+                               time.setMinutes(parseInt(spins.minute.value(), 10));
+
+                               return time;
+                       };
+
+                       /**
+                       * Handle the click event
+                       * @method _onClick
+                       * @param {Event} event
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._onClick = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       element = self.element,
+                                       eventTargetElement = event.target,
+                                       hourContainer = ui.hourContainer,
+                                       minuteContainer = ui.minuteContainer,
+                                       parentContainer = getClosestByClass(eventTargetElement, TimePicker.classes.CONTAINER);
+
+                               if (parentContainer && parentContainer.classList.contains(TimePicker.classes.HOUR_CONTAINER) &&
+                                       getClosestByClass(eventTargetElement, Spin.classes.SELECTED)) {
+                                       self._focusInput("hour");
+                               } else if (parentContainer && parentContainer.classList.contains(TimePicker.classes.MINUTE_CONTAINER) &&
+                                       getClosestByClass(eventTargetElement, Spin.classes.SELECTED)) {
+                                       self._focusInput("minute");
+                               } else {
+                                       element.classList.remove(TimePicker.classes.TIME_INPUT_ACTIVE);
+                                       minuteContainer.classList.remove(TimePicker.classes.ACTIVE_CONTAINER);
+                                       hourContainer.classList.remove(TimePicker.classes.ACTIVE_CONTAINER);
+                               }
+                       };
+
+                       // Get a new added value
+                       function diffValue(origin, change) {
+                               var diff = change.toString().split(origin).join("");
+
+                               if (diff.length === 0) {
+                                       return origin;
+                               }
+                               return diff;
+                       }
+
+                       /**
+                       * Change the value of input element included in Spin
+                       * @method _onInputChange
+                       * @param {Event} event
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._onInputChange = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       value = event.target.value,
+                                       activeContainer = getClosestByClass(event.target, TimePicker.classes.CONTAINER),
+                                       visibleValue;
+
+                               if (activeContainer && activeContainer.classList.contains(TimePicker.classes.HOUR_CONTAINER)) {
+                                       if (!self._inputValueState) {
+                                               visibleValue = parseInt(diffValue(self._previousInputValue, value), 10);
+                                               self._setInputValue("hour", visibleValue, true);
+
+                                               if ((options.format === "12" && visibleValue > 1) || (options.format === "24" && visibleValue > 2)) {
+                                                       self._focusInput("minute");
+                                               }
+                                       } else {
+                                               visibleValue = parseInt(value, 10);
+
+                                               if (visibleValue > ui.hourInput.max || visibleValue < ui.hourInput.min) {
+                                                       // TODO: Show toast error message
+                                                       self._setInputValue("hour", self._previousInputValue, true);
+                                                       return;
+                                               }
+
+                                               self._setInputValue("hour", visibleValue, false);
+                                               self._focusInput("minute");
+                                       }
+                               } else if (activeContainer && activeContainer.classList.contains(TimePicker.classes.MINUTE_CONTAINER)) {
+                                       if (!self._inputValueState) {
+                                               visibleValue = parseInt(diffValue(self._previousInputValue, value), 10);
+                                               self._setInputValue("minute", visibleValue, true);
+                                       } else {
+                                               visibleValue = parseInt(value, 10);
+
+                                               if (visibleValue > ui.minuteInput.max || visibleValue < ui.minuteInput.min) {
+                                                       // TODO: Show toast error message
+                                                       self._setInputValue("minute", self._previousInputValue, false);
+                                                       return;
+                                               }
+
+                                               self._setInputValue("minute", visibleValue, false);
+                                       }
+                               }
+                       };
+
+                       /**
+                       * Change the value of spin included in TimePicker
+                       * @method _onSpinChange
+                       * @param {Event} event
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._onSpinChange = function (event) {
+                               var self = this,
+                                       parentContainer = getClosestByClass(event.target, TimePicker.classes.CONTAINER);
+
+                               if (parentContainer && parentContainer.classList.contains(TimePicker.classes.HOUR_CONTAINER)) {
+                                       self._setInputValue("hour", event.detail.value, false);
+                               } else if (parentContainer && parentContainer.classList.contains(TimePicker.classes.MINUTE_CONTAINER)) {
+                                       self._setInputValue("minute", event.detail.value, false);
+                               }
+                       };
+
+                       /**
+                       * Handle events
+                       * @method handleEvent
+                       * @param {Event} event
+                       * @member ns.widget.mobile.TimePicker
+                       * @public
+                       */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "click":
+                                               self._onClick(event);
+                                               break;
+                                       case "input":
+                                               self._onInputChange(event);
+                                               break;
+                                       case "spinchange":
+                                               self._onSpinChange(event);
+                                               break;
+                               }
+                       };
+
+                       /**
+                       * Bind widget event handlers
+                       * @method _bindEvents
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       ui = self._ui;
+
+                               utilsEvents.on(document, "click", self);
+                               utilsEvents.on(ui.hourInput, "input", self);
+                               utilsEvents.on(ui.minuteInput, "input", self);
+                               utilsEvents.on(ui.hourSpin, "spinchange", self);
+                               utilsEvents.on(ui.minuteSpin, "spinchange", self);
+                       };
+
+                       /**
+                       * Unbind widget event handlers
+                       * @method _unbindEvents
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._unbindEvents = function () {
+                               var self = this,
+                                       ui = self._ui;
+
+                               utilsEvents.off(document, "click", self);
+                               utilsEvents.off(ui.hourInput, "input", self);
+                               utilsEvents.off(ui.minuteInput, "input", self);
+                               utilsEvents.off(ui.hourSpin, "spinchange", self);
+                               utilsEvents.off(ui.minuteSpin, "spinchange", self);
+                       };
+
+                       /**
+                       * Destory TimePicker widget
+                       * @method _destory
+                       * @member ns.widget.mobile.TimePicker
+                       * @protected
+                       */
+                       prototype._destory = function () {
+                               var self = this,
+                                       spins = self._spins;
+
+                               Object.keys(spins).forEach(function (key) {
+                                       spins[key]._destory();
+                               });
+
+                               self._unbindEvents();
+                       };
+
+                       TimePicker.prototype = prototype;
+
+                       // definition
+                       ns.widget.mobile.TimePicker = TimePicker;
+                       engine.defineWidget(
+                               "TimePicker",
+                               WIDGET_SELECTOR,
+                               [],
+                               TimePicker,
+                               "mobile"
+                       );
+
+                       }(window, window.document, window.tau));
+
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.1 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/* global define */
+/**
+* # DatePicker Widget
+* Shows a control that can be used to set day, month, and year.
+* It support calendar/wheel view mode.
+*
+* ## Default selectors
+*
+* Default selector for timepicker is class *ui-date-picker*
+*
+* ### HTML Examples
+*
+* #### Wheel view
+* To add a datepicker widget to the application, use the following code:
+*
+*      @example
+*      <div class="ui-date-picker" data-view="wheel">
+*
+* @class ns.widget.mobile.DatePicker
+* @since 1.2
+* @component-selector .ui-date-picker
+* @extends ns.widget.mobile.DatePicker
+* @author Hunseop Jeong <hs85.jeong@samsung.com>
+*/
+(function (window, document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               engine = ns.engine,
+                               utilsEvents = ns.event,
+                               getClosestByClass = ns.util.selectors.getClosestByClass,
+                               Spin = ns.widget.mobile.Spin,
+                               WIDGET_CLASS = "ui-date-picker",
+                               classes = {
+                                       HEADER: WIDGET_CLASS + "-header",
+                                       CONTENT: WIDGET_CLASS + "-content",
+                                       CONTAINER: WIDGET_CLASS + "-container",
+                                       DAY_CONTAINER: WIDGET_CLASS + "-container-day",
+                                       MONTH_CONTAINER: WIDGET_CLASS + "-container-month",
+                                       YEAR_CONTAINER: WIDGET_CLASS + "-container-year"
+                               },
+                               MONTH_NAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+                               MIN_YEAR = 1900,
+                               MAX_YEAR = 2050,
+                               WIDGET_SELECTOR = "." + WIDGET_CLASS,
+                               DatePicker = function () {
+                                       this.options = {
+                                               view: "wheel"
+                                       };
+
+                                       this._spins = {
+                                               day: null,
+                                               month: null,
+                                               year: null
+                                       };
+                                       this._ui = {
+                                               header: null
+                                       };
+                               },
+                               prototype = new BaseWidget();
+
+                       DatePicker.classes = classes;
+
+                       /**
+                       * Init method
+                       * @method _init
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._init = function () {
+                               var self = this;
+
+                               self._setValue(new Date());
+                               // Update day in month
+                               self._changeMonth(self._getDateValue("month"));
+
+                               // Calculate the spin widget after building the widget
+                               Object.keys(self._spins).forEach(function (key) {
+                                       self._spins[key].refresh();
+                               });
+                       };
+
+                       /**
+                       * Build widget for the date picker
+                       * @method _buildDatePicker
+                       * @param {string} name
+                       * @return {HTMLElement} container for date spin
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._buildDatePicker = function (name) {
+                               var self = this,
+                                       ui = self._ui,
+                                       spin = document.createElement("div"),
+                                       spinContainer = document.createElement("div"),
+                                       options = {
+                                               momentumLevel: 1
+                                       },
+                                       spinWidget;
+
+                               spin.classList.add(Spin.classes.SPIN);
+                               spinContainer.classList.add(DatePicker.classes.CONTAINER);
+
+                               if (name === "day") {
+                                       options = {
+                                               min: 1,
+                                               max: 31,
+                                               momentumLevel: 1
+                                       };
+                                       spinContainer.classList.add(DatePicker.classes.DAY_CONTAINER);
+                               } else if (name === "month") {
+                                       options = {
+                                               min: 1,
+                                               max: MONTH_NAMES.length,
+                                               labels: MONTH_NAMES.map(function (value) {
+                                                       return value.toUpperCase().substring(0, 3);
+                                               }).join(","),
+                                               momentumLevel: 1
+                                       };
+                                       spinContainer.classList.add(DatePicker.classes.MONTH_CONTAINER);
+                               } else if (name === "year") {
+                                       options = {
+                                               min: MIN_YEAR,
+                                               max: MAX_YEAR,
+                                               value: 2020,
+                                               momentumLevel: 1
+                                       }
+                                       spinContainer.classList.add(DatePicker.classes.YEAR_CONTAINER);
+                               }
+
+                               spinContainer.appendChild(spin);
+
+                               ui[name + "Spin"] = spin;
+
+                               spinWidget = ns.widget.Spin(spin, options);
+                               self._spins[name] = spinWidget;
+
+                               return spinContainer;
+                       };
+
+                       /**
+                       * Build widget instance
+                       * @method _build
+                       * @param {HTMLElement} element
+                       * @return {HTMLElement} Builded element
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       header = document.createElement("div"),
+                                       content = document.createElement("div"),
+                                       dayPicker = self._buildDatePicker("day"),
+                                       monthPicker = self._buildDatePicker("month"),
+                                       yearPicker = self._buildDatePicker("year");
+
+                               header.classList.add(DatePicker.classes.HEADER);
+                               element.appendChild(header);
+
+                               ui.header = header;
+
+                               content.classList.add(DatePicker.classes.CONTENT);
+                               content.appendChild(dayPicker);
+                               content.appendChild(monthPicker);
+                               content.appendChild(yearPicker);
+
+                               element.appendChild(content);
+
+                               return element;
+                       };
+
+                       /**
+                       * Return Date value
+                       * @method _getValue
+                       * @return {Date}
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._getValue = function () {
+                               return this._value;
+                       }
+
+                       /**
+                       * Return value of one field
+                       * @method _getDateValue
+                       * @param {string} type
+                       * @return {Date|number}
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._getDateValue = function (type) {
+                               var value = this._value;
+
+                               switch (type) {
+                                       case "day":
+                                               return value.getDate();
+                                       case "month":
+                                               return value.getMonth() + 1;
+                                       case "year":
+                                               return value.getFullYear();
+                                       default:
+                                               return value;
+                               }
+                       }
+
+                       /**
+                       * Set the value of DatePicker
+                       * @method _setValue
+                       * @param {Date} value
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._setValue = function (value) {
+                               var self = this,
+                                       spins = self._spins,
+                                       headerText;
+
+                               if (value instanceof Date) {
+                                       self._value = value;
+
+                                       Object.keys(spins).forEach(function (name) {
+                                               spins[name].value(self._getDateValue(name));
+                                       });
+
+                                       headerText = MONTH_NAMES[value.getMonth()] + " " + value.getFullYear();
+                                       self._ui.header.innerHTML = headerText;
+                               }
+                       };
+
+                       /**
+                       * Change a day value
+                       * @method _changeDay
+                       * @param {number} day
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._changeDay = function (day) {
+                               var self = this,
+                                       value = self.value();
+
+                               value.setDate(day);
+                               self.value(value);
+                       };
+
+                       /**
+                       * Calculate the day count in month
+                       * @method _dayInMonth
+                       * @param {number} year
+                       * @param {number} month
+                       * @return {number}
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._dayInMonth = function (year, month) {
+                               if (year === undefined) {
+                                       year = this._getDateValue("year");
+                               }
+                               if (month === undefined) {
+                                       month = this._getDateValue("month");
+                               }
+                               return new Date(year, month, 0).getDate();
+                       }
+
+                       /**
+                       * Change a month value
+                       * @method _changeMonth
+                       * @param {number} month
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._changeMonth = function (month) {
+                               var self = this,
+                                       spins = self._spins,
+                                       value = self.value(),
+                                       day = value.getDate(),
+                                       dayInMonth;
+
+                               dayInMonth = self._dayInMonth(value.getFullYear(), month);
+
+                               if (day > dayInMonth) {
+                                       day = dayInMonth;
+                               }
+
+                               value.setDate(day);
+                               value.setMonth(month - 1);
+
+                               spins.day.option("max", dayInMonth);
+                               spins.day._prevValue = day;
+                               spins.day._updateItems();
+
+                               self.value(value);
+                       };
+
+                       /**
+                       * Change a year value
+                       * @method _changeYear
+                       * @param {number} year
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._changeYear = function (year) {
+                               var self = this,
+                                       spins = self._spins,
+                                       value = self.value(),
+                                       month = value.getMonth(),
+                                       day = value.getDate(),
+                                       dayInMonth;
+
+                               dayInMonth = self._dayInMonth(year, month + 1);
+                               if (day > dayInMonth) {
+                                       day = dayInMonth;
+                               }
+
+                               value.setFullYear(year);
+                               value.setDate(day);
+
+                               spins.day.option("max", dayInMonth);
+                               spins.day._updateItems();
+
+                               self.value(value);
+                       };
+
+                       /**
+                       * Handle spinchange event
+                       * @method _onSpinChange
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DatePicker
+                       * @protected
+                       */
+                       prototype._onSpinChange = function (event) {
+                               var self = this,
+                                       parentContainer = getClosestByClass(event.target, DatePicker.classes.CONTAINER);
+
+                               if (parentContainer && parentContainer.classList.contains(DatePicker.classes.DAY_CONTAINER)) {
+                                       self._changeDay(event.detail.value);
+                               } else if (parentContainer && parentContainer.classList.contains(DatePicker.classes.MONTH_CONTAINER)) {
+                                       self._changeMonth(event.detail.value);
+                               } else if (parentContainer && parentContainer.classList.contains(DatePicker.classes.YEAR_CONTAINER)) {
+                                       self._changeYear(event.detail.value);
+                               }
+                       };
+
+                       /**
+                       * Handle events of the DatePicker
+                       * @method handleEvent
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DatePicker
+                       * @public
+                       */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               if (event.type === "spinchange") {
+                                       self._onSpinChange(event);
+                               }
+                       }
+
+                       /**
+                       * Bind events
+                       * @method _bindEvents
+                       * @member ns.widget.mobile.DatePicker
+                       * @public
+                       */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       ui = self._ui;
+
+                               utilsEvents.on(ui.daySpin, "spinchange", self, false);
+                               utilsEvents.on(ui.monthSpin, "spinchange", self, false);
+                               utilsEvents.on(ui.yearSpin, "spinchange", self, false);
+                       };
+
+                       /**
+                       * Unbind events
+                       * @method _bindEvents
+                       * @member ns.widget.mobile.DatePicker
+                       * @public
+                       */
+                       prototype._unbindEvents = function () {
+                               var self = this,
+                                       ui = self._ui;
+
+                               utilsEvents.off(ui.daySpin, "spinchange", self, false);
+                               utilsEvents.off(ui.monthSpin, "spinchange", self, false);
+                               utilsEvents.off(ui.yearSpin, "spinchange", self, false);
+                       }
+
+                       DatePicker.prototype = prototype;
+
+                       // definition
+                       ns.widget.mobile.DatePicker = DatePicker;
+                       engine.defineWidget(
+                               "DatePicker",
+                               WIDGET_SELECTOR,
+                               [],
+                               DatePicker,
+                               "mobile"
+                       );
+
+                       }(window, window.document, window.tau));
+
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* global define */
+/**
+ * # DateTimePickerWheel Widget
+ * Shows a control that can be used to set hours and minutes.
+ * It support 12/24 hours format. It contains two inputs which control the values
+ *
+ * ## Default selectors
+ *
+ * Default selector for timepicker is class *ui-datetime-picker-wheel*
+ *
+ * ### HTML Examples
+ *
+ * #### 12 hours format
+ * To add a timepicker widget to the application, use the following code:
+ *
+ *      @example
+ *      <div class="ui-datetime-picker-wheel" data-format="12">
+ *
+ * #### 24 hours format
+ * To add a timepicker widget to the application, use the following code:
+ *
+ *      @example
+ *      <div class="ui-datetime-picker-wheel" data-format="24">
+ *
+ * @class ns.widget.mobile.DateTimePickerWheel
+ * @since 1.2
+ * @component-selector .ui-datetime-picker-wheel
+ * @extends ns.widget.mobile.DateTimePickerWheel
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               engine = ns.engine,
+                               utilsEvents = ns.event,
+                               getClosestByClass = ns.util.selectors.getClosestByClass,
+                               Spin = ns.widget.mobile.Spin,
+                               WIDGET_CLASS = "ui-datetime-picker-wheel",
+                               classes = {
+                                       WIDGET: WIDGET_CLASS,
+                                       CONTAINER: WIDGET_CLASS + "-container",
+                                       HOUR_CONTAINER: WIDGET_CLASS + "-container-hour",
+                                       MINUTE_CONTAINER: WIDGET_CLASS + "-container-minute",
+                                       FORMAT_CONTAINER: WIDGET_CLASS + "-container-format",
+                                       DATE_CONTAINER: WIDGET_CLASS + "-container-date",
+                                       ACTIVE_CONTAINER: WIDGET_CLASS + "-container-active",
+                                       TIME_INPUT: WIDGET_CLASS + "-input",
+                                       TIME_INPUT_ACTIVE: WIDGET_CLASS + "-input-active",
+                                       SEPARATOR: WIDGET_CLASS + "-container-separator"
+                               },
+                               WIDGET_SELECTOR = "." + WIDGET_CLASS,
+                               DAYS_OF_WEEK = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+                               MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
+                               DateTimePickerWheel = function () {
+                                       this.options = {
+                                               format: "12",
+                                               value: (new Date()).toUTCString()
+                                       };
+
+                                       this._spins = {
+                                               date: null,
+                                               hour: null,
+                                               minute: null,
+                                               format: null
+                                       };
+
+                                       this._ui = {};
+                                       this._previousInputValue = -1;
+                                       // Variable to check the current state of input element (false: first, true: second)
+                                       this._inputValueState = false;
+                               },
+                               events = {
+                                       /**
+                                        * Event will be triggered when user tap/click selected date
+                                        * @event
+                                        */
+                                       SELECTED: "datetimepickerwheelselected",
+                                       CHANGE: "datetimepickerwheelchange"
+                               },
+                               prototype = new BaseWidget();
+
+                       DateTimePickerWheel.classes = classes;
+
+                       /**
+                       * Init method
+                       * @method _init
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._init = function () {
+                               var self = this,
+                                       options = self.options;
+
+                               options.format = (options.format !== undefined) ? options.format : "12";
+
+                               self._setValue(options.value);
+
+                               self.option("format", options.format);
+
+                               // Calculate the spin widget after building the widget
+                               Object.keys(self._spins).forEach(function (key) {
+                                       self._spins[key].refresh();
+                               });
+                       };
+
+                       /**
+                       * Build widget instance
+                       * @method _build
+                       * @param {HTMLElement} element
+                       * @return {HTMLElement} Builded element
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       datePicker = self._buildDatePicker(),
+                                       hourPicker = self._buildDateTimePickerWheel("hour"),
+                                       minutePicker = self._buildDateTimePickerWheel("minute"),
+                                       formatPicker = self._buildFormat(),
+                                       separator = document.createElement("div");
+
+                               element.classList.add(classes.WIDGET);
+                               separator.classList.add(classes.SEPARATOR);
+                               element.appendChild(datePicker);
+                               element.appendChild(hourPicker);
+                               element.appendChild(separator);
+                               element.appendChild(minutePicker);
+                               element.appendChild(formatPicker);
+
+                               return element;
+                       };
+
+                       /**
+                       * Build Spin Widget for the time
+                       * @method _buildDateTimePickerWheel
+                       * @param {string} name
+                       * @return {HTMLElement} container for time spin
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._buildDateTimePickerWheel = function (name) {
+                               var self = this,
+                                       ui = self._ui,
+                                       spin = document.createElement("div"),
+                                       spinInput = document.createElement("input"),
+                                       spinContainer = document.createElement("div"),
+                                       options = {
+                                               momentumLevel: 1
+                                       },
+                                       spinWidget;
+
+                               spin.classList.add(Spin.classes.SPIN);
+                               spinContainer.classList.add(classes.CONTAINER);
+
+                               if (name === "hour") {
+                                       if (self.options.format === "24") {
+                                               options.min = 0;
+                                               options.max = 23;
+                                       } else {
+                                               options.min = 1;
+                                               options.max = 12;
+                                       }
+                                       spinContainer.classList.add(classes.HOUR_CONTAINER);
+                               } else if (name === "minute") {
+                                       options.min = 0;
+                                       options.max = 59;
+                                       options.digits = 2;
+                                       spinContainer.classList.add(classes.MINUTE_CONTAINER);
+                               }
+
+                               spinInput.min = options.min;
+                               spinInput.max = options.max;
+                               spinInput.type = "number";
+                               spinInput.step = "1";
+                               spinInput.classList.add(classes.TIME_INPUT);
+
+                               spin.appendChild(spinInput);
+                               spinContainer.appendChild(spin);
+
+                               ui[name + "Spin"] = spin;
+                               ui[name + "Input"] = spinInput;
+                               ui[name + "Container"] = spinContainer;
+
+                               spinWidget = ns.widget.Spin(spin, options);
+                               self._spins[name] = spinWidget;
+
+                               return spinContainer;
+                       };
+
+                       /**
+                       * Build Date Picker (Spin Widget) for the time
+                       * @method _buildDatePicker
+                       * @param {Date} selectedDate
+                       * @return {HTMLElement} container for time spin
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._buildDatePicker = function (selectedDate) {
+                               var self = this,
+                                       ui = self._ui,
+                                       spin = document.createElement("div"),
+                                       spinContainer = document.createElement("div"),
+                                       options = {},
+                                       spinWidget,
+                                       firstDayOfYear,
+                                       date,
+                                       year;
+
+                               selectedDate = selectedDate || new Date();
+                               year = selectedDate.getFullYear();
+                               firstDayOfYear = new Date(year.toString());
+                               date = firstDayOfYear;
+
+                               spin.classList.add(Spin.classes.SPIN);
+                               spinContainer.classList.add(classes.CONTAINER);
+                               spinContainer.classList.add(classes.DATE_CONTAINER);
+
+                               options.labels = [];
+                               while (date.getFullYear() === year) {
+                                       options.labels.push(
+                                               DAYS_OF_WEEK[date.getDay()] + ", " +
+                                               MONTH_NAMES_SHORT[date.getMonth()] + " " +
+                                               date.getDate()
+                                       );
+                                       date.setDate(date.getDate() + 1);
+                               }
+
+                               options.min = 0;
+                               options.max = options.labels.length - 1;
+                               options.loop = false;
+                               options.momentumLevel = 1;
+
+                               spinContainer.appendChild(spin);
+
+                               ui["dateSpin"] = spin;
+                               ui["dateContainer"] = spinContainer;
+
+                               spinWidget = ns.widget.Spin(spin, options);
+                               self._spins["date"] = spinWidget;
+
+                               self._year = year;
+
+                               return spinContainer;
+                       };
+
+                       /**
+                       * Build Spin Widget for the format
+                       * @method _buildFormat
+                       * @return {HTMLElement} container for format spin
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._buildFormat = function () {
+                               var self = this,
+                                       spin = document.createElement("div"),
+                                       spinContainer = document.createElement("div"),
+                                       options = {
+                                               min: 0,
+                                               max: 1,
+                                               labels: "AM,PM",
+                                               loop: "false"
+                                       },
+                                       spinWidget;
+
+                               spin.classList.add(Spin.classes.SPIN);
+                               spinContainer.classList.add(classes.CONTAINER);
+                               spinContainer.classList.add(classes.FORMAT_CONTAINER);
+                               spinContainer.appendChild(spin);
+
+                               spinWidget = ns.widget.Spin(spin, options);
+                               self._spins.format = spinWidget;
+
+                               return spinContainer;
+                       };
+
+                       /**
+                       * Set the value for Date object
+                       * @method _setDateValue
+                       * @param {Date} value
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._setDateValue = function (value) {
+                               var self = this,
+                                       ui = self._ui,
+                                       spins = self._spins,
+                                       hours,
+                                       minutes,
+                                       firstDayOfYear,
+                                       DAY_MILLISECONDS = 24 * 3600 * 1000;
+
+                               hours = value.getHours();
+                               minutes = value.getMinutes();
+
+                               if (self.options.format === "12") {
+                                       if (hours > 12) {
+                                               hours -= 12;
+                                               spins.format.value(1);
+                                       } else {
+                                               spins.format.value(0);
+                                       }
+                               }
+
+                               ui.hourInput.setAttribute("value", hours);
+                               ui.hourInput.value = hours;
+                               ui.minuteInput.setAttribute("value", minutes);
+                               ui.minuteInput.value = minutes;
+
+                               firstDayOfYear = new Date(value.getFullYear(), 0, 1);
+                               spins.date.value(Math.floor((value - firstDayOfYear) / DAY_MILLISECONDS));
+
+                               spins.hour.value(hours);
+                               spins.minute.value(minutes);
+
+                               self.options.value = value;
+                       };
+
+                       /**
+                       * Set the value for the input element
+                       * @method _setInputValue
+                       * @param {string} name
+                       * @param {number} value
+                       * @param {boolean} state
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._setInputValue = function (name, value, state) {
+                               var self = this,
+                                       ui = self._ui,
+                                       spins = self._spins;
+
+                               if (name === "hour") {
+                                       ui.hourInput.setAttribute("value", value);
+                                       ui.hourInput.value = value;
+                                       spins.hour.value(value);
+                               } else if (name === "minute") {
+                                       ui.minuteInput.setAttribute("value", value);
+                                       ui.minuteInput.value = value;
+                                       spins.minute.value(value);
+                               }
+
+                               self._previousInputValue = value;
+                               self._inputValueState = state;
+                       }
+
+                       /**
+                       * Focus input element
+                       * @method _focusInput
+                       * @param {string} name
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._focusInput = function (name) {
+                               var self = this,
+                                       ui = self._ui;
+
+                               if (name === "hour") {
+                                       self.element.classList.add(classes.TIME_INPUT_ACTIVE);
+                                       ui.hourContainer.classList.add(classes.ACTIVE_CONTAINER);
+                                       ui.minuteContainer.classList.remove(classes.ACTIVE_CONTAINER);
+                                       ui.hourInput.focus();
+                                       self._previousInputValue = ui.hourInput.value;
+                               } else if (name === "minute") {
+                                       self.element.classList.add(classes.TIME_INPUT_ACTIVE);
+                                       ui.minuteContainer.classList.add(classes.ACTIVE_CONTAINER);
+                                       ui.hourContainer.classList.remove(classes.ACTIVE_CONTAINER);
+                                       ui.minuteInput.focus();
+                                       self._previousInputValue = ui.minuteInput.value;
+                               }
+
+                               self._inputValueState = false;
+                       }
+
+                       /**
+                       * Set the value of DateTimePickerWheel
+                       * @method _setValue
+                       * @param {Date} value
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._setValue = function (value) {
+                               var self = this;
+
+                               // change string to date eg. "1995-12-17T03:24:00"
+                               if (typeof value === "string") {
+                                       value = new Date(value);
+                               }
+
+                               if (value instanceof Date) {
+                                       self._setDateValue(value);
+                               }
+                       };
+
+                       /**
+                       * Get the value of DateTimePickerWheel
+                       * @method _getValue
+                       * @return {Date} current time of time picker
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._getValue = function () {
+                               var self = this,
+                                       time = new Date(self.options.value),
+                                       spins = self._spins,
+                                       hours = parseInt(spins.hour.value(), 10);
+
+                               if (self.options.format === "12" && spins.format.value() === 1) {
+                                       hours += 12;
+                               }
+
+                               time.setHours(hours);
+                               time.setMinutes(parseInt(spins.minute.value(), 10));
+
+                               return time;
+                       };
+
+                       /**
+                       * Handle the click event
+                       * @method _onClick
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._onClick = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       element = self.element,
+                                       eventTargetElement = event.target,
+                                       hourContainer = ui.hourContainer,
+                                       minuteContainer = ui.minuteContainer,
+                                       parentContainer = getClosestByClass(eventTargetElement, classes.CONTAINER);
+
+                               if (parentContainer && parentContainer.classList.contains(classes.HOUR_CONTAINER) &&
+                                       getClosestByClass(eventTargetElement, Spin.classes.SELECTED)) {
+                                       self._focusInput("hour");
+                               } else if (parentContainer && parentContainer.classList.contains(classes.MINUTE_CONTAINER) &&
+                                       getClosestByClass(eventTargetElement, Spin.classes.SELECTED)) {
+                                       self._focusInput("minute");
+                               } else if (parentContainer && parentContainer.classList.contains(classes.DATE_CONTAINER) &&
+                                       getClosestByClass(eventTargetElement, Spin.classes.SELECTED)) {
+                                       utilsEvents.trigger(self.element, events.SELECTED, {datetime: self._getValue()});
+                               } else {
+                                       element.classList.remove(classes.TIME_INPUT_ACTIVE);
+                                       minuteContainer.classList.remove(classes.ACTIVE_CONTAINER);
+                                       hourContainer.classList.remove(classes.ACTIVE_CONTAINER);
+                               }
+                       };
+
+                       // Get a new added value
+                       function diffValue(origin, change) {
+                               var diff = change.toString().split(origin).join("");
+
+                               if (diff.length === 0) {
+                                       return origin;
+                               }
+                               return diff;
+                       }
+
+                       /**
+                       * Change the value of input element included in Spin
+                       * @method _onInputChange
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._onInputChange = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       options = self.options,
+                                       value = event.target.value,
+                                       activeContainer = getClosestByClass(event.target, classes.CONTAINER),
+                                       visibleValue;
+
+                               if (activeContainer && activeContainer.classList.contains(classes.HOUR_CONTAINER)) {
+                                       if (!self._inputValueState) {
+                                               visibleValue = parseInt(diffValue(self._previousInputValue, value), 10);
+                                               self._setInputValue("hour", visibleValue, true);
+
+                                               if ((options.format === "12" && visibleValue > 1) || (options.format === "24" && visibleValue > 2)) {
+                                                       self._focusInput("minute");
+                                               }
+                                       } else {
+                                               visibleValue = parseInt(value, 10);
+
+                                               if (visibleValue > ui.hourInput.max || visibleValue < ui.hourInput.min) {
+                                                       // TODO: Show toast error message
+                                                       self._setInputValue("hour", self._previousInputValue, true);
+                                                       return;
+                                               }
+
+                                               self._setInputValue("hour", visibleValue, false);
+                                               self._focusInput("minute");
+                                       }
+                               } else if (activeContainer && activeContainer.classList.contains(classes.MINUTE_CONTAINER)) {
+                                       if (!self._inputValueState) {
+                                               visibleValue = parseInt(diffValue(self._previousInputValue, value), 10);
+                                               self._setInputValue("minute", visibleValue, true);
+                                       } else {
+                                               visibleValue = parseInt(value, 10);
+
+                                               if (visibleValue > ui.minuteInput.max || visibleValue < ui.minuteInput.min) {
+                                                       // TODO: Show toast error message
+                                                       self._setInputValue("minute", self._previousInputValue, false);
+                                                       return;
+                                               }
+
+                                               self._setInputValue("minute", visibleValue, false);
+                                       }
+                               }
+                       };
+
+                       /**
+                       * Change the value of spin included in DateTimePickerWheel
+                       * @method _onSpinChange
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._onSpinChange = function (event) {
+                               var self = this,
+                                       parentContainer = getClosestByClass(event.target, classes.CONTAINER);
+
+                               if (parentContainer && parentContainer.classList.contains(classes.HOUR_CONTAINER)) {
+                                       self._setInputValue("hour", event.detail.value, false);
+                               } else if (parentContainer && parentContainer.classList.contains(classes.MINUTE_CONTAINER)) {
+                                       self._setInputValue("minute", event.detail.value, false);
+                               } else if (parentContainer && parentContainer.classList.contains(classes.DATE_CONTAINER)) {
+                                       self._setDate(new Date(self._year, 0, event.detail.value + 1));
+                               }
+                               ns.event.trigger(self.element, "datetimepickerwheelchange", {date: self._getValue()});
+                       };
+
+                       prototype._setDate = function (date) {
+                               var currentValue = new Date(this.options.value);
+
+                               if (typeof date === "string") {
+                                       date = new Date(date);
+                               }
+                               if (date instanceof Date) {
+                                       currentValue.setFullYear(date.getFullYear());
+                                       currentValue.setMonth(date.getMonth());
+                                       currentValue.setDate(date.getDate());
+                                       this.options.value = currentValue;
+                               }
+                       }
+
+                       /**
+                       * Handle events
+                       * @method handleEvent
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @public
+                       */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "vclick":
+                                               self._onClick(event);
+                                               break;
+                                       case "input":
+                                               self._onInputChange(event);
+                                               break;
+                                       case "spinchange":
+                                               self._onSpinChange(event);
+                                               break;
+                               }
+                       };
+
+                       /**
+                       * Bind widget event handlers
+                       * @method _bindEvents
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       ui = self._ui;
+
+                               utilsEvents.on(self.element, "vclick", self);
+                               utilsEvents.on(ui.hourInput, "input", self);
+                               utilsEvents.on(ui.minuteInput, "input", self);
+                               utilsEvents.on(ui.hourSpin, "spinchange", self);
+                               utilsEvents.on(ui.minuteSpin, "spinchange", self);
+                               utilsEvents.on(ui.dateSpin, "spinchange", self);
+                       };
+
+                       /**
+                       * Unbind widget event handlers
+                       * @method _unbindEvents
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._unbindEvents = function () {
+                               var self = this,
+                                       ui = self._ui;
+
+                               utilsEvents.off(self.element, "vclick", self);
+                               utilsEvents.off(ui.hourInput, "input", self);
+                               utilsEvents.off(ui.minuteInput, "input", self);
+                               utilsEvents.off(ui.hourSpin, "spinchange", self);
+                               utilsEvents.off(ui.minuteSpin, "spinchange", self);
+                               utilsEvents.off(ui.dateSpin, "spinchange", self);
+                       };
+
+                       /**
+                       * Destory DateTimePickerWheel widget
+                       * @method _destory
+                       * @member ns.widget.mobile.DateTimePickerWheel
+                       * @protected
+                       */
+                       prototype._destory = function () {
+                               var self = this,
+                                       spins = self._spins;
+
+                               Object.keys(spins).forEach(function (key) {
+                                       // @todo change "_destroy()" to "destroy()"
+                                       spins[key]._destory();
+                               });
+
+                               self._unbindEvents();
+                       };
+
+                       DateTimePickerWheel.prototype = prototype;
+
+                       // definition
+                       ns.widget.mobile.DateTimePickerWheel = DateTimePickerWheel;
+                       engine.defineWidget(
+                               "DateTimePickerWheel",
+                               WIDGET_SELECTOR,
+                               [],
+                               DateTimePickerWheel,
+                               "mobile"
+                       );
+
+                       }(window, window.document, window.tau));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @example
+ * 1. default
+ * <div class="ui-calendar"></div>
+ *
+ * 2. past selection option
+ * <div class="ui-calendar" data-past-selection="true"></div>
+ *
+ * @since 1.2
+ * @class ns.widget.mobile.Calendar
+ * @extends ns.widget.BaseWidget
+ * @author Dohyung Lim <delight.lim@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var utilsObject = ns.util.object,
+                               engine = ns.engine,
+                               events = ns.event,
+                               days = ["MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"],
+                               fullNameMonth = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+
+                               classes = {
+                                       WIDGET: "ui-calendar",
+
+                                       PREV_MONTH_DAY: "ui-calendar-prev-month-day",
+                                       NEXT_MONTH_DAY: "ui-calendar-next-month-day",
+                                       CURRENT_MONTH_DAY: "ui-calendar-current-month-day",
+
+                                       DISABLED: "ui-calendar-disabled",
+                                       ARROW_DISABLED: "ui-calendar-disabled-arrow",
+                                       SELECTION: "ui-calendar-selection",
+
+                                       CONTROLLER: "ui-calendar-controller",
+                                       ARROW: "ui-calendar-arrow",
+                                       ARROW_RIGHT: "ui-calendar-right-arrow",
+                                       ARROW_LEFT: "ui-calendar-left-arrow",
+
+                                       ONE_WEEK: "ui-calendar-one-week",
+                                       TOP_SPACE: "ui-calendar-top-space",
+
+                                       SWITCH_VIEW: "ui-calendar-switch",
+                                       CALENDAR_VIEW: "ui-calendar-view"
+                               },
+
+                               /**
+                               * Options for widget
+                               * @property {Object} options
+                               * @property {boolean} [options.pastSelection=true]
+                               * @member ns.widget.mobile.Calendar
+                               */
+                               defaultOptions = {
+                                       pastSelection: false,
+                                       closeOnSelect: false
+                               },
+
+                               Calendar = function () {
+                                       var self = this;
+
+                                       self.options = utilsObject.merge({}, defaultOptions);
+                                       self._value = new Date();
+
+                                       self._dateData = self._value;
+                                       self._todayYear = self._dateData.getFullYear();
+                                       self._todayMonth = self._dateData.getMonth() + 1;
+                                       self._defaultToday = self._dateData.getUTCDate();
+                                       self._selectDay = null;
+                                       self._activeMonth = null;
+                                       self._fixMonth = null;
+                                       self._loadTodayFlag = true;
+                                       /**
+                                        * time properties are not used by calendar but
+                                        * there are required when change view to DateTimePicker
+                                        */
+                                       self._hours = self._dateData.getHours();
+                                       self._minutes = self._dateData.getMinutes();
+                                       self._seconds = self._dateData.getSeconds();
+
+                                       self._ui = {
+                                               switch: null,
+                                               leftArrow: null,
+                                               rightArrow: null,
+                                               calendarView: null
+                                       };
+                               },
+
+                               BaseWidget = ns.widget.BaseWidget,
+                               prototype = new BaseWidget();
+
+                       Calendar.prototype = prototype;
+                       Calendar.classes = classes;
+
+                       /**
+                       * Init widget
+                       * @method _init
+                       * @param {HTMLElement} element
+                       * @return {HTMLElement} Returns built element
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._init = function (element) {
+                               var self = this;
+
+                               self._ui.calendarView = element.querySelector("." + classes.CALENDAR_VIEW);
+                               self._ui.switch = element.querySelector("." + classes.SWITCH_VIEW);
+                               self._ui.leftArrow = element.querySelector("." + classes.ARROW_LEFT);
+                               self._ui.rightArrow = element.querySelector("." + classes.ARROW_RIGHT);
+
+                               if (!self.options.pastSelection) {
+                                       self._ui.leftArrow.classList.add(classes.ARROW_DISABLED);
+                               }
+
+                               if (self._activeMonth === null) {
+                                       self._fixMonth = self._activeMonth = self._todayMonth;
+                               }
+
+                               if (self._selectDay === null) {
+                                       self._selectDay = self._defaultToday;
+                               }
+
+                               self._buildCalendar(self._ui.calendarView);
+
+                               return element;
+                       };
+
+                       /**
+                       * Create and append div element for calendar day
+                       * @method createDayInRow
+                       * @param {HTMLElement} row
+                       * @member ns.widget.mobile.Calendar
+                       * @private
+                       */
+                       function createDayInRow(row) {
+                               var cell = row.insertCell();
+
+                               cell.insertAdjacentHTML("afterbegin", "<div></div>");
+                               return cell.firstChild;
+                       }
+
+                       /**
+                       * Draw a calendar on the table
+                       * @method _buildCalendar
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._buildCalendar = function (calendarElement) {
+                               var self = this,
+                                       ui = self._ui,
+                                       firstDate = new Date(self._todayYear, self._todayMonth - 1, 0),
+                                       lastDate = new Date(self._todayYear, self._todayMonth, 0),
+                                       day = firstDate.getDay(),
+                                       prevFirstDate = firstDate.getDate(),
+                                       prevLastDate = lastDate.getDate(),
+                                       week = Math.ceil(prevLastDate / 7) + 1,
+                                       leftDays = 7,
+                                       setDays = 1,
+                                       nextMonthDate = 1,
+                                       marginRow = calendarElement.insertRow(),
+                                       idx,
+                                       row,
+                                       div = null;
+
+                               marginRow.style.height = "7px";
+
+                               for (idx = 1; idx < week + 1; idx++) {
+                                       row = calendarElement.insertRow();
+
+                                       while (day != 0) { // days of previous month
+                                               day = day - 1;
+                                               leftDays = leftDays - 1;
+                                               div = createDayInRow(row);
+                                               div.classList.add(classes.PREV_MONTH_DAY);
+                                               div.innerHTML = prevFirstDate - day;
+                                               if (self._fixMonth === self._todayMonth && !self.options.pastSelection) {
+                                                       div.classList.add(classes.DISABLED);
+                                               }
+                                       }
+                                       while (leftDays != 0) {
+                                               div = createDayInRow(row);
+                                               if (setDays > prevLastDate) { // days of next month.
+                                                       div.classList.add(classes.NEXT_MONTH_DAY);
+                                                       div.innerHTML = nextMonthDate;
+                                                       leftDays = leftDays - 1;
+                                                       nextMonthDate = nextMonthDate + 1;
+                                               } else { // current enabled days.
+                                                       div.innerHTML = setDays;
+                                                       div.classList.add(classes.CURRENT_MONTH_DAY);
+                                                       setDays = setDays + 1;
+                                                       leftDays = leftDays - 1;
+
+                                                       if (self._defaultToday > parseInt(div.innerHTML, 10)) {
+                                                               if (self._fixMonth === self._todayMonth && !self.options.pastSelection) {
+                                                                       div.classList.add(classes.DISABLED);
+                                                               }
+                                                       }
+
+                                                       if (self._loadTodayFlag && div.innerHTML === self._defaultToday.toLocaleString()) { // dateData selected.
+                                                               div.classList.add(classes.SELECTION);
+                                                               self._selectDay = div;
+                                                               self._activeMonth = self._todayMonth;
+                                                               self._loadTodayFlag = false;
+                                                       } else {
+                                                               if (self._activeMonth === self._todayMonth && div.innerHTML === self._selectDay.innerHTML) {
+                                                                       div.classList.add(classes.SELECTION);
+                                                                       self._selectDay = div;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                                       leftDays = 7;
+                               }
+
+                               if (!self.options.pastSelection) {
+                                       ui.leftArrow.classList.toggle(classes.DISABLED, self._fixMonth == self._todayMonth);
+                               }
+                               ui.switch.innerHTML = fullNameMonth[self._todayMonth - 1] + " " + self._todayYear;
+                       };
+
+                       /**
+                       * Moving to another month erases the existing calendar
+                       * @method _deleteCalendar
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._deleteCalendar = function (calendarElement) {
+                               while (calendarElement.rows.length > 2) {
+                                       calendarElement.deleteRow(2);
+                               }
+                       };
+
+                       /**
+                       * Click handler
+                       * @method _onClick
+                       * @param {Event} event
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._onClick = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       target = event.target,
+                                       targetClassList = target.classList;
+
+                               if (!targetClassList.contains(classes.DISABLED)) {
+                                       if (target === ui.rightArrow) {
+                                               self._moveMonth(1);
+                                       } else if (target === ui.leftArrow) {
+                                               self._moveMonth(-1);
+                                       } else if (target === ui.switch) {
+                                               events.trigger(self.element, "calendarswitch", {date: self._getValue()});
+                                       } else {
+                                               // Calendar view
+                                               if (target.tagName === "TD") { // if click on TD instead of DIV
+                                                       target = target.querySelector("div");
+                                                       targetClassList = (target) ? target.classList : null;
+                                               }
+                                               if (targetClassList &&
+                                                       !targetClassList.contains(classes.SELECTION) &&
+                                                       !targetClassList.contains(classes.DISABLED)) {
+                                                       if (targetClassList.contains(classes.PREV_MONTH_DAY)) {
+                                                               self._moveMonth(-1);
+                                                               self._selection(target.innerHTML);
+                                                               if (self.options.closeOnSelect) {
+                                                                       events.trigger(self.element, "calendarswitch", {date: self._getValue()});
+                                                               }
+                                                       } else if (targetClassList.contains(classes.NEXT_MONTH_DAY)) {
+                                                               self._moveMonth(1);
+                                                               self._selection(target.innerHTML);
+                                                               if (self.options.closeOnSelect) {
+                                                                       events.trigger(self.element, "calendarswitch", {date: self._getValue()});
+                                                               }
+                                                       }
+                                                       if (targetClassList.contains(classes.CURRENT_MONTH_DAY)) {
+                                                               self._selection(target.innerHTML);
+                                                               if (self.options.closeOnSelect) {
+                                                                       events.trigger(self.element, "calendarswitch", {date: self._getValue()});
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       };
+
+                       /**
+                       * Set the value of Calendar
+                       * @method _setValue
+                       * @param {Date} value
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._setValue = function (value) {
+                               var self = this;
+
+                               // change string to date eg. "1995-12-17T03:24:00"
+                               if (typeof value === "string") {
+                                       value = new Date(value);
+                               }
+
+                               if (value instanceof Date) {
+                                       self._value = value;
+
+                                       self._hours = value.getHours();
+                                       self._minutes = value.getMinutes();
+                                       self._seconds = value.getSeconds();
+
+                                       self._setMonth(value.getMonth() + 1);
+                                       self._selection(value.getDate());
+                               }
+                       };
+
+                       prototype._getValue = function () {
+                               return new Date(this._value);
+                       };
+
+                       /**
+                       * Selecting a date leaves a mark
+                       * @method _moveMonth
+                       * @param {number} change
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._moveMonth = function (change) {
+                               var self = this;
+
+                               if (change !== 0) {
+                                       self._todayMonth = self._todayMonth + change;
+                                       if (self._todayMonth === 0) {
+                                               self._todayMonth = 12;
+                                               self._todayYear = self._todayYear - 1;
+                                       }
+                                       if (self._todayMonth === 13) {
+                                               self._todayMonth = 1;
+                                               self._todayYear = self._todayYear + 1;
+                                       }
+                               }
+                               self._updateCalendar();
+                       };
+
+                       /**
+                       * Set year
+                       * @method _setYear
+                       * @param {number} year
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._setYear = function (year) {
+                               var self = this;
+
+                               if (self._todayYear !== year) {
+                                       self._todayYear = year;
+                                       self._updateCalendar();
+                               }
+                       };
+
+                       /**
+                       * Set month
+                       * @method _setMonth
+                       * @param {number} month
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._setMonth = function (month) {
+                               var self = this;
+
+                               if (self._todayMonth !== month) {
+                                       self._todayMonth = month;
+                                       self._updateCalendar();
+                               }
+                       };
+
+                       /**
+                       * Selecting a date leaves a mark
+                       * @method _updateCalendar
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._updateCalendar = function () {
+                               var self = this,
+                                       calendarView = self._ui.calendarView;
+
+                               self._deleteCalendar(calendarView);
+                               self._dateData = new Date(self._todayYear, self._todayMonth - 1, 0,
+                                       self._hours, self._minutes, self._seconds);
+                               self._buildCalendar(calendarView);
+                       };
+
+                       /**
+                       * Selecting a date leaves a mark
+                       * @method _selection
+                       * @param {HTMLElement} value
+                       * @member ns.widget.mobile.Calendar
+                       * @protected
+                       */
+                       prototype._selection = function (value) {
+                               var otherMonthDay,
+                                       strValue,
+                                       self = this;
+
+                               if (value != undefined) {
+                                       strValue = value.toString();
+                                       otherMonthDay = self._ui.calendarView.querySelectorAll("div." + classes.CURRENT_MONTH_DAY);
+                                       otherMonthDay.forEach(function (idx) {
+                                               if (idx.innerHTML === strValue) {
+                                                       self._selectDay.classList.remove(classes.SELECTION);
+                                                       idx.classList.add(classes.SELECTION);
+                                                       self._selectDay = idx;
+                                                       self._activeMonth = self._todayMonth;
+                                               }
+                                       });
+                                       // set widget value
+                                       self._value = new Date(self._todayYear, self._todayMonth - 1, value,
+                                               self._hours, self._minutes, self._seconds);
+                               }
+                       };
+
+                       prototype._unBindEvents = function (element) {
+                               events.off(element, "vclick", this, false);
+                       };
+
+                       prototype._bindEvents = function (element) {
+                               events.on(element, "vclick", this, false);
+                       };
+
+                       prototype.handleEvent = function (event) {
+                               if (event.type === "vclick") {
+                                       this._onClick(event);
+                               } else {
+                                       event.preventDefault();
+                               }
+                       };
+
+                       prototype._setPastSelection = function (element, value) {
+                               this.options.pastSelection = value;
+                               return true;
+                       };
+
+                       prototype._refresh = function () {
+                               var self = this,
+                                       calendarView = self._ui.calendarView;
+
+                               self._deleteCalendar(calendarView);
+                               self._buildCalendar(calendarView);
+                       };
+
+                       prototype._build = function (element) {
+                               var controllerElement = document.createElement("div"),
+                                       leftArrowElement = document.createElement("div"),
+                                       rightArrowElement = document.createElement("div"),
+                                       viewChangeElement = document.createElement("div"),
+                                       viewTableElement = document.createElement("table"),
+                                       spaceElement = document.createElement("tr"),
+                                       oneWeekElement = document.createElement("tr"),
+                                       monElement = document.createElement("td"),
+                                       tueElement = document.createElement("td"),
+                                       wedElement = document.createElement("td"),
+                                       thuElement = document.createElement("td"),
+                                       friElement = document.createElement("td"),
+                                       satElement = document.createElement("td"),
+                                       sunElement = document.createElement("td");
+
+                               element.classList.add(classes.WIDGET);
+
+                               // Controller
+                               controllerElement.classList.add(classes.CONTROLLER);
+                               leftArrowElement.classList.add(classes.ARROW_LEFT);
+                               leftArrowElement.classList.add(classes.ARROW);
+                               rightArrowElement.classList.add(classes.ARROW_RIGHT);
+                               rightArrowElement.classList.add(classes.ARROW);
+                               viewChangeElement.classList.add(classes.SWITCH_VIEW);
+
+                               controllerElement.appendChild(leftArrowElement);
+                               controllerElement.appendChild(rightArrowElement);
+                               controllerElement.appendChild(viewChangeElement);
+
+                               // View Container
+                               viewTableElement.classList.add(classes.CALENDAR_VIEW);
+                               spaceElement.classList.add(classes.TOP_SPACE);
+                               oneWeekElement.classList.add(classes.ONE_WEEK);
+
+                               monElement.innerHTML = days[0];
+                               oneWeekElement.appendChild(monElement);
+                               tueElement.innerHTML = days[1];
+                               oneWeekElement.appendChild(tueElement);
+                               wedElement.innerHTML = days[2];
+                               oneWeekElement.appendChild(wedElement);
+                               thuElement.innerHTML = days[3];
+                               oneWeekElement.appendChild(thuElement);
+                               friElement.innerHTML = days[4];
+                               oneWeekElement.appendChild(friElement);
+                               satElement.innerHTML = days[5];
+                               oneWeekElement.appendChild(satElement);
+                               sunElement.innerHTML = days[6];
+                               sunElement.classList.add("ui-sunday");
+                               oneWeekElement.appendChild(sunElement);
+
+                               viewTableElement.appendChild(spaceElement);
+                               viewTableElement.appendChild(oneWeekElement);
+
+                               // append Elements
+                               element.appendChild(controllerElement);
+                               element.appendChild(viewTableElement);
+
+                               return element;
+                       };
+
+                       prototype._destroy = function () {
+                               var self = this;
+
+                               self.options = null;
+                               self._unBindEvents(self.element);
+                       };
+
+                       ns.widget.mobile.Calendar = Calendar;
+                       engine.defineWidget(
+                               "Calendar",
+                               ".ui-calendar",
+                               [],
+                               Calendar,
+                               "mobile"
+                       );
+                       }(document, ns));
+
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.1 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+/* global define */
+/**
+ * # DateTimePicker Widget
+ * Shows a control that can be used to set date and time.
+ * The DataTimePicker has possibility to change view between wheel view and calendar view.
+ *
+ * It support 12/24 hours format. It contains two inputs which control the values
+ *
+ * ## Default selectors
+ *
+ * Default selector for timepicker is class *ui-datetime-picker*
+ *
+ * ### HTML Examples
+ *
+ * #### 12 hours format
+ * To add a timepicker widget to the application, use the following code:
+ *
+ *      @example
+ *      <div class="ui-datetime-picker" data-format="12">
+ *
+ * #### 24 hours format
+ * To add a timepicker widget to the application, use the following code:
+ *
+ *      @example
+ *      <div class="ui-datetime-picker" data-format="24">
+ *
+ * @class ns.widget.mobile.DateTimePicker
+ * @since 1.2
+ * @component-selector .ui-datetime-picker
+ * @extends ns.widget.mobile.DateTimePicker
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               engine = ns.engine,
+                               utilsEvents = ns.event,
+                               WIDGET_CLASS = "ui-datetime-picker",
+                               classes = {
+                                       CONTAINER: WIDGET_CLASS + "-container",
+                                       HIDDEN: WIDGET_CLASS + "-hidden"
+                               },
+                               WIDGET_SELECTOR = "." + WIDGET_CLASS,
+
+                               DateTimePicker = function () {
+                                       var self = this;
+
+                                       self.options = {
+                                               format: "12",
+                                               view: "wheel",
+                                               value: (new Date()).toUTCString()
+                                       };
+
+                                       self._datetime = null;
+                                       self._calendar = null;
+
+                                       self._ui = {
+                                               datetime: null,
+                                               calendar: null
+                                       };
+                               },
+                               events = {
+                                       /**
+                                        * Event will be triggered when datetime change
+                                        * @event
+                                        */
+                                       CHANGE: "datetimepickerchange"
+                               },
+                               prototype = new BaseWidget();
+
+                       DateTimePicker.classes = classes;
+
+                       /**
+                       * Init method
+                       * @method _init
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._init = function () {
+                               var self = this,
+                                       options = self.options;
+
+                               options.format = (options.format !== undefined) ? options.format : "12";
+
+                               self._setValue(options.value);
+
+                               self.option("format", options.format);
+
+                               // Change view on init
+                               self._setView(self.element, options.view);
+                       };
+
+                       /**
+                       * Build widget instance
+                       * @method _build
+                       * @param {HTMLElement} element
+                       * @return {HTMLElement} Builded element
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       datetime = document.createElement("div"),
+                                       calendar = document.createElement("div");
+
+                               element.appendChild(datetime);
+                               element.appendChild(calendar);
+
+                               self._datetime = ns.widget.DateTimePickerWheel(datetime);
+                               self._calendar = ns.widget.Calendar(calendar, {
+                                       closeOnSelect: true
+                               });
+
+                               ui.datetime = datetime;
+                               ui.calendar = calendar;
+                               return element;
+                       };
+
+                       /**
+                       * Handle event for select date on datetime picker
+                       * @method _onDateTimeSelected
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._onDateTimeSelected = function (event) {
+                               var self = this;
+
+                               if (event.target === self._ui.datetime) {
+                                       self._calendar.value(event.detail.datetime);
+                                       self._setView(self.element, "calendar");
+                               }
+                       };
+
+                       /**
+                       * Handle event for calendar change view to wheel view
+                       * @method _onCalendarSwitch
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._onCalendarSwitch = function (event) {
+                               var self = this;
+
+                               if (event.target === self._ui.calendar) {
+                                       self._datetime.value(event.detail.date);
+                                       self._setView(self.element, "wheel");
+                                       ns.event.trigger(self.element, events.CHANGE, {date: self._getValue()});
+                               }
+                       };
+
+                       /**
+                       * Method changes widget look
+                       * @method _setView
+                       * @param {HTMLElement} element
+                       * @param {string} value
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._setView = function (element, value) {
+                               var ui = this._ui;
+
+                               this.options.view = value;
+                               if (value === "wheel") {
+                                       ui.calendar.classList.add(classes.HIDDEN);
+                                       ui.datetime.classList.remove(classes.HIDDEN);
+                               } else if (value === "calendar") {
+                                       ui.datetime.classList.add(classes.HIDDEN);
+                                       ui.calendar.classList.remove(classes.HIDDEN);
+                               }
+                       };
+
+                       /**
+                       * Set the value of DateTimePicker
+                       * @method _setValue
+                       * @param {Date|string} value
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._setValue = function (value) {
+                               var self = this;
+
+                               if (typeof value === "string") {
+                                       value = new Date(value);
+                               }
+
+                               if (value instanceof Date) {
+                                       self._datetime.value(value);
+                                       self._calendar.value(value);
+                                       self.options.value = value;
+                               }
+                       };
+
+                       /**
+                       * Get the value of DateTimePicker
+                       * @method _getValue
+                       * @return {Date} current time of time picker
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._getValue = function () {
+                               var self = this;
+
+                               if (self.options.view === "wheel") {
+                                       return self._datetime.value();
+                               } else if (self.options.view === "calendar") {
+                                       return self._calendar.value();
+                               }
+                               return self.options.value;
+                       };
+
+                       /**
+                       * Handle event for date time change in DateTimePicker
+                       * @method _onDateTimeChange
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._onDateTimeChange = function (event) {
+                               var self = this;
+
+                               self.options.value = event.detail.datetime;
+                               ns.event.trigger(self.element, events.CHANGE, {date: self._getValue()});
+                       };
+
+                       /**
+                       * Set format 12/24h option for DateTimePickerWheel
+                       * @method _setFormat
+                       * @param {HTMLElement} element
+                       * @param {string} format
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._setFormat = function (element, format) {
+                               var self = this;
+
+                               self.options.format = format;
+                               self._datetime.option("format", format);
+                       };
+
+                       /**
+                       * Get format 12/24h option for DateTimePickerWheel
+                       * @method _getFormat
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @return {string} format of time 12/24h
+                       * @protected
+                       */
+                       prototype._getFormat = function () {
+                               return self._datetime.option("format");
+                       };
+
+                       /**
+                       * Handle events
+                       * @method handleEvent
+                       * @param {Event} event
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @public
+                       */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "datetimepickerwheelselected":
+                                               self._onDateTimeSelected(event);
+                                               break;
+                                       case "calendarswitch":
+                                               self._onCalendarSwitch(event);
+                                               break;
+                                       case "datetimepickerwheelchange":
+                                               self._onDateTimeChange(event);
+                                               break;
+                               }
+                       };
+
+                       /**
+                       * Bind widget event handlers
+                       * @method _bindEvents
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._bindEvents = function () {
+                               var self = this;
+
+                               self.element.addEventListener("datetimepickerwheelselected", this, false);
+                               self.element.addEventListener("datetimepickerwheelchange", this, false);
+                               self.element.addEventListener("calendarswitch", this, false);
+                       };
+
+                       /**
+                       * Unbind widget event handlers
+                       * @method _unbindEvents
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._unbindEvents = function () {
+                               var self = this;
+
+                               self.element.removeEventListener("datetimepickerwheelselected", this, false);
+                               self.element.removeEventListener("calendarswitch", this, false);
+                       };
+
+                       /**
+                       * Destory DateTimePicker widget
+                       * @method _destory
+                       * @member ns.widget.mobile.DateTimePicker
+                       * @protected
+                       */
+                       prototype._destory = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       element = self.element;
+
+                               self._unbindEvents();
+
+                               self._calendar.destory();
+                               self._datetime.destory();
+
+                               element.removeChild(ui.datetime);
+                               element.removeChild(ui.calendar);
+                       };
+
+                       DateTimePicker.prototype = prototype;
+
+                       // definition
+                       ns.widget.mobile.DateTimePicker = DateTimePicker;
+                       engine.defineWidget(
+                               "DateTimePicker",
+                               WIDGET_SELECTOR,
+                               [],
+                               DateTimePicker,
+                               "mobile"
+                       );
+
+                       }(window, window.document, window.tau));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * # Chips
+ * Small button containing text value with assign itself remove action
+ *
+ * ## Default selectors
+ * All elements with class _.ui-chip_ are changed to chips component.
+ *
+ * ###HTML Examples
+ *
+ * ####Create chip div using data-role
+ *
+ *             @example
+ *             <div class="ui-chip">Text</div>
+ *
+ * ## Manual constructor
+ * For manual creation of Chip component you can use constructor of component
+ * from **tau** namespace:
+ *
+ *             @example
+ *             <script>
+ *                     var chipElement = document.getElementById("chip"),
+ *                             chip = tau.widget.Chip(chipElement);
+ *             </script>
+ *
+ * Constructor has one require parameter **element** which are base
+ * **HTMLElement** to create widget. We recommend get this element by method
+ * *document.getElementById*. Second parameter is **options** and it is
+ * a object with options for widget.
+ *
+ * ##Options for Chip Widget
+ *
+ * You can change option for widget using method **option**.
+ *
+ * ##Methods
+ *
+ * To call method on widget you can use one of existing API:
+ *
+ *             @example
+ *             var chipElement = document.getElementById("chip"),
+ *                     chip = tau.widget.Chip(chipElement);
+ *
+ *             chip.methodName(methodArgument1, methodArgument2, ...);
+ *
+ * @since 1.2
+ * @class ns.widget.mobile.Chip
+ * @component-selector .ui-chip [data-role]="chip"
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               /**
+                        * @property {Object} BaseWidget alias variable
+                        * @private
+                        * @static
+                        */
+                       var BaseWidget = ns.widget.mobile.BaseWidgetMobile,
+                               /**
+                                * @property {Object} engine alias variable
+                                * @private
+                                * @static
+                                */
+                               engine = ns.engine,
+                               /**
+                                * @property {Object} eventUtil alias variable
+                                * @private
+                                * @static
+                                */
+                               eventUtil = ns.event,
+                               COLOR_CLASS_PREFIX = "ui-color-",
+                               COLOR_CLASS_REGEX = /ui-color-[^\s]+/g,
+
+                               Chip = function () {
+                                       var self = this;
+
+                                       /**
+                                        * Chip widget options.
+                                        * @property {string} [options.icon="delete"] icon on chip button
+                                        */
+                                       self.options = {
+                                               icon: "delete"
+                                       };
+
+                                       self._ui = {
+                                               text: null,
+                                               button: null
+                                       };
+                               },
+
+                               /**
+                                * Dictionary object containing commonly used widget classes
+                                * @property {Object} classes
+                                * @readonly
+                                * @static
+                                * @member ns.widget.mobile.Chip
+                                */
+                               classes = {
+                                       /**
+                                        * Standard chip widget
+                                        * @style ui-chip
+                                        * @member ns.widget.mobile.Chip
+                                        */
+                                       widget: "ui-chip",
+                                       /**
+                                        * Set text content of chip
+                                        * @style ui-chip-text
+                                        * @member ns.widget.mobile.Chip
+                                        */
+                                       text: "ui-chip-text",
+                                       /**
+                                        * Button to remove widget
+                                        * @style ui-chip-button
+                                        * @member ns.widget.mobile.Chip
+                                        */
+                                       button: "ui-chip-button"
+                               },
+                               events = {
+                                       /**
+                                        * Widget triggers this event before remove itself
+                                        * @type {Event}
+                                        * @member ns.widget.mobile.Chip
+                                        */
+                                       BEFORE_REMOVE: "chipbeforeremove"
+                               },
+                               selectors = {
+                                       widget: "." + classes.widget + ", [data-role='chip']",
+                                       text: "." + classes.text,
+                                       button: "." + classes.button
+                               },
+                               prototype = new BaseWidget();
+
+
+                       Chip.prototype = prototype;
+                       Chip.classes = classes;
+                       Chip.events = events;
+
+                       /**
+                        * On click handler
+                        * @method _onClick
+                        * @protected
+                        * @member ns.widget.mobile.Chip
+                        */
+                       prototype._onClick = function () {
+                               var self = this,
+                                       notPrevented;
+
+                               notPrevented = eventUtil.trigger(self.element, events.BEFORE_REMOVE);
+                               if (notPrevented) {
+                                       self.element.parentElement.removeChild(self.element);
+                               }
+                               self.destroy();
+                       };
+
+                       /**
+                        * Common handle event for widget
+                        * @method handleEvent
+                        * @protected
+                        * @param {Event} event
+                        * @member ns.widget.mobile.Chip
+                        */
+                       prototype.handleEvent = function (event) {
+                               if (event.type === "vclick") {
+                                       this._onClick(event);
+                               }
+                       };
+
+                       /**
+                        * Build widget structure
+                        * @method _build
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.Chip
+                        */
+                       prototype._build = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       text,
+                                       button;
+
+                               button = element.querySelector(selectors.button);
+                               if (button) {
+                                       element.removeChild(button);
+                               }
+
+                               text = element.querySelector(selectors.text) ||
+                                       element.querySelector("*:not(" + selectors.button + ")");
+
+                               if (text) {
+                                       element.removeChild(text);
+                               } else {
+                                       text = document.createElement("span");
+                                       text.className = classes.text;
+                                       text.innerHTML = element.textContent;
+                               }
+
+                               element.textContent = "";
+
+                               if (!button) {
+                                       button = document.createElement("button");
+                                       button.className = ["ui-btn", classes.button].join(" ");
+                                       button.setAttribute("data-icon", "minus");
+                                       button.setAttribute("data-style", "flat");
+                               }
+
+                               element.appendChild(text);
+                               element.appendChild(button);
+
+                               ui.text = text;
+                               ui.button = button;
+
+                               return element;
+                       };
+
+                       prototype._updateButtonColor = function () {
+                               var self = this,
+                                       button = self._ui.button,
+                                       actualClass = COLOR_CLASS_PREFIX + self.options.icon,
+                                       colorClasses;
+
+                               colorClasses = button.className.match(COLOR_CLASS_REGEX) || [];
+                               colorClasses.forEach(function (colorClass) {
+                                       if (colorClass !== actualClass) {
+                                               button.classList.remove(colorClass);
+                                       }
+                               });
+                               if (colorClasses.indexOf(actualClass) === -1) {
+                                       button.classList.add(actualClass);
+                               }
+                       };
+
+                       /**
+                        * Init widget structure
+                        * @method _init
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.Chip
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui;
+
+                               ui.text = ui.text || element.querySelector(selectors.text);
+                               ui.button = ui.button || element.querySelector(selectors.button);
+
+                               ns.widget.Button(ui.button, {
+                                       icon: self.options.icon
+                               });
+                               self._updateButtonColor();
+
+                               return element;
+                       };
+
+                       /**
+                        * Bind widget events
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.mobile.Chip
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       button = self._ui.button;
+
+                               eventUtil.on(button, "vclick", self, false);
+                       };
+
+                       /**
+                        * Unbind widget events
+                        * @method _unbindEvents
+                        * @protected
+                        * @member ns.widget.mobile.Chip
+                        */
+                       prototype._unbindEvents = function () {
+                               var self = this,
+                                       button = self._ui.button;
+
+                               eventUtil.off(button, "vclick", self, false);
+                       };
+
+                       /**
+                        * Destroy widget
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.mobile.Chip
+                        */
+                       prototype._destroy = function () {
+                               var self = this;
+
+                               self._unbindEvents();
+
+                               self._ui = null;
+
+                               eventUtil.trigger(document, "destroyed", {
+                                       widget: "Chip"
+                               });
+                       };
+
+                       // definition
+                       ns.widget.mobile.Chip = Chip;
+                       engine.defineWidget(
+                               "Chip",
+                               selectors.widget,
+                               [],
+                               Chip,
+                               "mobile"
+                       );
+                       }(window.document, ns));
+
+/*global window, define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * # Scroll Handler
+ * Extension for Scroll View Widget, adds scroll handler.
+ *
+ * ## Default selectors
+ * All scrollview selectors with have a class _.ui-scrollhandler_
+ * or _data-handler=[DIRECTION]_ will become be enhanced
+ *
+ * ### HTML examples
+ *
+ * #### Enhanced scrollview using data-handler attribute
+ *
+ *             @example
+ *             <div data-role="page">
+ *                     <div data-role="content" data-handler="true">
+ *                             page content
+ *                     </div>
+ *             </div>
+ *
+ * #### Enhanced scrollview using css .ui-scrollhandler class
+ *
+ *             @example
+ *             <div data-role="page">
+ *                     <div data-role="content" class="ui-scrollhandler">
+ *                             page content
+ *                     </div>
+ *             </div>
+ *
+ * ## Manual constructor
+ * To create the widget manually you can use 2 different APIs, the TAU
+ * API or jQuery API
+ *
+ * ### Enhanced scrollview by using TAU API
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     var handlerElement = document.getElementById("myPage")
+ *                                             .querySelector("[data-role=content]");
+ *                     tau.widget.ScrollHandler(handlerElement);
+ *             </script>
+ *
+ * ### Enhanced scrollview by using jQuery API
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     $("#myPage > div[data-role=content]").scrollhandler();
+ *             </script>
+ *
+ * ## Options for ScrollHandler
+ *
+ * Options can be set by using data-* attributes or by passing them to
+ * the constructor.
+ *
+ * There is also a method **option** for changing them after widget
+ * creation
+ *
+ * jQuery mobile API is also supported.
+ *
+ * ### Enable handler
+ *
+ * This option sets the handler status. The default value is true.
+ *
+ * You can change this option by all available methods for options
+ * changing
+ *
+ * #### By data-handler attribute
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content" data-handler="true">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *
+ * #### By passing object to constructor
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     var handlerElement = document.getElementById("myPage")
+ *                                             .querySelector("[data-role=content]");
+ *                     tau.widget.ScrollHandler(handlerElement, {
+ *                             "handler": true
+ *                     });
+ *             </script>
+ *
+ * #### By using jQuery API
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     $("#myPage > div[data-role=content]").scrollhandler({
+ *                             "handler": "true"
+ *                     });
+ *             </script>
+ *
+ * ### handlerTheme
+ *
+ * This option sets the handler theme. The default value is inherited
+ * or "s" if none found.
+ *
+ * You can change this option by all available methods for options
+ * changing
+ *
+ * #### By data-handler-theme attribute
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content" data-handler-theme="s" handler="true">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *
+ *
+ * #### By passing object to constructor
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     var handlerElement = document.getElementById("myPage")
+ *                                             .querySelector("[data-role=content]");
+ *                     tau.widget.ScrollHandler(handlerElement, {
+ *                             "handlerTheme": "s"
+ *                     });
+ *             </script>
+ *
+ * #### By using jQuery API
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     $("#myPage > div[data-role=content]").scrollhandler({
+ *                             "handlerTheme": "s"
+ *                     });
+ *             </script>
+ *
+ * ### direction
+ *
+ * This option sets the the direction of which the handler is presented.
+ * The default value is "y" meaning vertical scroll button.
+ *
+ * You can change this option by all available methods for options
+ * changing
+ *
+ * #### By data-handler-direction attribute
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content" data-direction="y" handler="true">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *
+ * #### By passing object to constructor
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     var handlerElement = document.getElementById("myPage")
+ *                                             .querySelector("[data-role=content]"),
+ *                     tau.widget.ScrollHandler(handlerElement, {
+ *                             "scroll": "y"
+ *                     });
+ *             </script>
+ *
+ * #### By using jQuery API
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     $("#myPage > div[data-role=content]").scrollhandler({
+ *                             "scroll": "y"
+ *                     });
+ *             </script>
+ *
+ * ### scroll
+ *
+ * This option sets the the direction of which the handler is scrolling.
+ * The default value is "y" which means vertical.
+ *
+ * You can change this option by all available methods for options
+ * changing
+ *
+ * #### By data-handler-scroll attribute
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content" data-scroll="x" handler="true">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *
+ * #### By passing object to constructor
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     var handlerElement = document.getElementById("myPage")
+ *                                             .querySelector("[data-role=content]"),
+ *                     tau.widget.ScrollHandler(handlerElement, {
+ *                             "scroll": "x"
+ *                     });
+ *             </script>
+ *
+ * #### By using jQuery API
+ *
+ *             @example
+ *             <div data-role="page" id="myPage">
+ *                     <div data-role="content">
+ *                             page content
+ *                     <div>
+ *             </div>
+ *             <script>
+ *                     $("#myPage > div[data-role=content]").scrollhandler({
+ *                             "scroll": "x"
+ *                     });
+ *             </script>
+ *
+ * ## Methods
+ *
+ * ScrollHandler methods can be called through 2 APIs: TAU API and jQuery
+ * API (jQuery Mobile-like API). Since this widget extends Scrollview,
+ * all the Scrollview methods can be called also.
+ *
+ * @class ns.widget.core.ScrollHandler
+ * @extends ns.widget.core.Scrollview
+ *
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ * @author Piotr Karny <p.karny@samsung.com>
+ * @author Hyunkook Cho <hk0713.cho@samsung.com>
+ * @author Junhyeon Lee <juneh.lee@samsung.com>
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var ScrollHandler = function () {
+                                       var self = this;
+                                       /**
+                                        * Widget options
+                                        * @property {Object} options
+                                        * @property {boolean} [options.handler=true] Enabled flag
+                                        * @property {string} [options.handlerTheme="s"] Handler theme
+                                        * @property {"x"|"y"} [options.direction="y"] The direction of the handler
+                                        * @property {"x"|"y"|"xy"} [options.scroll="y"] The direction of scrolling
+                                        * @property {number} [options.delay=1500] Time in ms after which the scrollhandler disappears.
+                                        * @member ns.widget.core.ScrollHandler
+                                        */
+
+                                       self.options = {
+                                               handler: true,
+                                               handlerTheme: "s",
+                                               direction: "y",
+                                               scroll: "y",
+                                               delay: 1500
+                                       };
+                                       /**
+                                        * A collection of handler UI elements
+                                        * @property {Object} ui
+                                        * @member ns.widget.core.ScrollHandler
+                                        * @instance
+                                        */
+                                       self.ui = {
+                                               handler: null,
+                                               thumb: null,
+                                               track: null,
+                                               handle: null,
+                                               expander: null,
+                                               page: null
+                                       };
+                                       /**
+                                        * Event listeners for various events
+                                        * @property {Object} _callbacks
+                                        * @property {Function} _callbacks.scrollstart Start handler
+                                        * @property {Function} _callbacks.scrollupdate Scrolling handler
+                                        * @property {Function} _callbacks.scrollend Scroll end handler
+                                        * @property {Function} _callbacks.touchstart Start handler
+                                        * @property {Function} _callbacks.touchmove Touch move  handler
+                                        * @property {Function} _callbacks.touchend Touch end handler
+                                        * @property {Function} _callbacks.resize Window resize handler
+                                        * @member ns.widget.core.ScrollHandler
+                                        * @protected
+                                        */
+                                       self._callbacks = {
+                                               scrolstart: null,
+                                               scrollupdate: null,
+                                               scrollend: null,
+                                               touchstart: null,
+                                               touchmove: null,
+                                               touchend: null,
+                                               resize: null
+                                       };
+                                       /**
+                                        * A drag indicator flag
+                                        * @property {boolean} [_dragging=false]
+                                        * @member ns.widget.core.ScrollHandler
+                                        * @protected
+                                        */
+                                       self._dragging = false;
+                                       /**
+                                        * Collection of scroll bounds params
+                                        * @property {Object} _offsets
+                                        * @member ns.widget.core.ScrollHandler
+                                        * @protected
+                                        */
+                                       self._offsets = {
+                                               x: 0,
+                                               y: 0,
+                                               maxX: 0,
+                                               maxY: 0
+                                       };
+                                       /**
+                                        * Holds original pointer events state
+                                        * @property {string} [_lastPointerEvents=""]
+                                        * @member ns.widget.core.ScrollHandler
+                                        * @protected
+                                        */
+                                       self._lastPointerEvents = "";
+                                       /**
+                                        * Holds information about scrollviews available offset
+                                        * @property {number} [_availableOffsetX=0]
+                                        * @member ns.widget.core.ScrollHandler
+                                        * @protected
+                                        */
+                                       self._availableOffsetX = 0;
+                                       /**
+                                        * Holds information about scrollviews available offset
+                                        * @property {number} [_availableOffsetX=0]
+                                        * @member ns.widget.core.ScrollHandler
+                                        * @protected
+                                        */
+                                       self._availableOffsetY = 0;
+                                       /**
+                                        * @property {?number} [_hideTimer=null]
+                                        * Holds timer ID
+                                        * @member ns.widget.core.ScrollHandler
+                                        * @protected
+                                        */
+                                       self._hideTimer = null;
+                                       /**
+                                        * Holds last mouse position
+                                        * @property {Object} _lastMouse
+                                        * @member ns.widget.core.ScrollHandler
+                                        * @protected
+                                        */
+                                       self._lastMouse = {
+                                               x: 0,
+                                               y: 0
+                                       };
+                               },
+                               engine = ns.engine,
+                               tauEvent = ns.event,
+                               CSSUtils = ns.util.DOM,
+                               selectors = ns.util.selectors,
+                               PageClasses = ns.widget.core.Page.classes,
+                               Scrollview = ns.widget.core.Scrollview,
+                               ScrollviewPrototype = Scrollview.prototype,
+                               ScrollviewBuild = ScrollviewPrototype._build,
+                               ScrollviewInit = ScrollviewPrototype._init,
+                               ScrollviewBindEvents = ScrollviewPrototype._bindEvents,
+                               ScrollviewDestroy = ScrollviewPrototype._destroy,
+                               CIRCULAR_ANGLE_RANGE = 60, // degree
+                               max = Math.max,
+                               min = Math.min,
+                               floor = Math.floor,
+                               /**
+                                * A collection of ScrollHandlers classes
+                                * @property {Object} classes
+                                * @property {string} [classes.handler="ui-handler"] Handler main class
+                                * @property {string} [classes.directionPrefix="ui-handler-direction"] Direction class prefix
+                                * @property {string} [classes.track="ui-handler-track"] Handler track class
+                                * @property {string} [classes.thumb="ui-handler-thumb"] Handler thumb button prefix
+                                * @property {string} [classes.themePrefix="ui-handler-"] Handler theme class prefix
+                                * @property {string} [classes.scrollbarDisabled="scrollbar-disabled"] Scrollview scrollbar disabled class
+                                * @property {string} [classes.disabled="disabled"] Disabled class
+                                * @property {string} [classes.hideNativeScrollbar="ui-hide-scrollbar"] Hides native scrollbar in scrollview
+                                * @member ns.widget.core.ScrollHandler
+                                * @static
+                                * @readonly
+                                */
+                               classes = {
+                                       handler: "ui-handler",
+                                       directionPrefix: "ui-handler-direction-",
+                                       track: "ui-handler-track",
+                                       handle: "ui-handler-handle",
+                                       thumb: "ui-handler-thumb",
+                                       expander: "ui-handler-expander",
+                                       visible: "ui-handler-visible",
+                                       themePrefix: "ui-handler-",
+                                       scrollbarDisabled: "scrollbar-disabled",
+                                       disabled: "disabled",
+                                       hideNativeScrollbar: "ui-hide-scrollbar"
+                               },
+                               prototype = new Scrollview();
+
+                       ScrollHandler.classes = classes;
+
+                       /**
+                        * Translates objects position to a new position
+                        * @param {ns.widget.core.ScrollHandler} self
+                        * @param {number} xOffset
+                        * @param {number} yOffset
+                        * @member ns.widget.core.ScrollHandler
+                        * @private
+                        * @static
+                        */
+                       function translate(self, xOffset, yOffset) {
+                               var style = null,
+                                       offsets,
+                                       translateString = null;
+
+                               if (self.options.handler) {
+                                       style = self.ui.handle.style;
+                                       if (ns.support.shape.circle) {
+                                               offsets = self._offsets,
+                                               translateString = "rotateZ(" +
+                                                       (((yOffset / offsets.maxY) * CIRCULAR_ANGLE_RANGE - CIRCULAR_ANGLE_RANGE / 2) || 0) +
+                                                       "deg)";
+                                       } else {
+                                               translateString = "translate3d(" + (xOffset || 0) + "px, " + (yOffset || 0) + "px, 0px)";
+                                       }
+                                       style.webkitTransform = translateString;
+                                       style.mozTransform = translateString;
+                                       style.msTransform = translateString;
+                                       style.oTransform = translateString;
+                                       style.transform = translateString;
+                               }
+                       }
+
+                       /**
+                        * Sets handler position according to scrollviews position
+                        * @param {ns.widget.core.ScrollHandler} self
+                        * @member ns.widget.core.ScrollHandler
+                        * @private
+                        * @static
+                        */
+                       function syncHandleWithScroll(self) {
+                               var position = self.getScrollPosition(),
+                                       offsets = self._offsets,
+                                       direction = self.options.direction,
+                                       x = floor(min(position.x, self._availableOffsetX) / self._availableOffsetX * offsets.maxX),
+                                       y = floor(min(position.y, self._availableOffsetY) / self._availableOffsetY * offsets.maxY);
+
+                               if (isNaN(x) === true) {
+                                       x = offsets.x;
+                               }
+
+                               if (isNaN(y) === true) {
+                                       y = offsets.y;
+                               }
+
+                               translate(
+                                       self,
+                                       direction === "y" ? 0 : x,
+                                       direction === "x" ? 0 : y
+                               );
+
+                               offsets.x = x;
+                               offsets.y = y;
+                       }
+
+                       /**
+                        * Handles scroll start event
+                        * @param {ns.widget.core.ScrollHandler} self
+                        * @member ns.widget.core.ScrollHandler
+                        * @private
+                        * @static
+                        */
+                       function handleScrollstart(self) {
+                               if (self._dragging === false) {
+                                       syncHandleWithScroll(self);
+                                       if (self._hideTimer) {
+                                               window.clearTimeout(self._hideTimer);
+                                       }
+                                       self.ui.handler.classList.add(classes.visible);
+                               }
+                       }
+
+                       /**
+                        * Handles scroll update event
+                        * @param {ns.widget.core.ScrollHandler} self
+                        * @member ns.widget.core.ScrollHandler
+                        * @private
+                        * @static
+                        */
+                       function handleScrollupdate(self) {
+                               if (self._dragging === false) {
+                                       if (self._hideTimer) {
+                                               window.clearTimeout(self._hideTimer);
+                                       }
+                                       syncHandleWithScroll(self);
+                               }
+                       }
+
+                       /**
+                        * Handles scroll stop event
+                        * @param {ns.widget.core.ScrollHandler} self
+                        * @member ns.widget.core.ScrollHandler
+                        * @private
+                        * @static
+                        */
+                       function handleScrollstop(self) {
+                               if (self._dragging === false) {
+                                       syncHandleWithScroll(self);
+                                       if (self._hideTimer) {
+                                               window.clearTimeout(self._hideTimer);
+                                       }
+                                       self._hideTimer = window.setTimeout(function () {
+                                               self.ui.handler.classList.remove(classes.visible);
+                                       }, self.options.delay);
+                               }
+                       }
+
+                       /**
+                        * Handles dragging
+                        * @param {ns.widget.core.ScrollHandler} self
+                        * @param {number} x
+                        * @param {number} y
+                        * @member ns.widget.core.ScrollHandler
+                        * @private
+                        * @static
+                        */
+                       function handleDragging(self, x, y) {
+                               var lastMouse = self._lastMouse,
+                                       offsets = self._offsets,
+                                       direction = self.options.direction,
+                                       diffX = lastMouse.x - x,
+                                       diffY = lastMouse.y - y;
+
+                               lastMouse.x = x;
+                               lastMouse.y = y;
+
+                               // translate with direction locking
+                               offsets.x += -diffX;
+                               offsets.y += -diffY;
+
+                               // cap to between limits
+                               offsets.x = max(0, offsets.x);
+                               offsets.y = max(0, offsets.y);
+                               offsets.x = min(offsets.maxX, offsets.x);
+                               offsets.y = min(offsets.maxY, offsets.y);
+
+                               translate(
+                                       self,
+                                       direction === "y" ? 0 : offsets.x,
+                                       direction === "x" ? 0 : offsets.y
+                               );
+
+                               self.scrollTo(
+                                       direction === "y" ? 0 : offsets.x / offsets.maxX * self._availableOffsetX,
+                                       direction === "x" ? 0 : offsets.y / offsets.maxY * self._availableOffsetY
+                               );
+
+                               if (self._hideTimer) {
+                                       window.clearTimeout(self._hideTimer);
+                               }
+                       }
+
+                       /**
+                        * Handles touch start event
+                        * @param {ns.widget.core.ScrollHandler} self
+                        * @param {MouseEvent|TouchEvent} event
+                        * @member ns.widget.core.ScrollHandler
+                        * @private
+                        * @static
+                        */
+                       function handleTouchstart(self, event) {
+                               var lastMouse = self._lastMouse,
+                                       touches = event.touches,
+                                       touch = touches && touches[0];
+
+                               // remove timer
+                               if (self._hideTimer) {
+                                       window.clearTimeout(self._hideTimer);
+                               }
+
+                               self._dragging = true;
+                               lastMouse.x = touch ? touch.clientX : event.clientX;
+                               lastMouse.y = touch ? touch.clientY : event.clientY;
+
+                               self.ui.handle.classList.add("ui-active");
+                               // disable scroll indicator
+                               if (self.options.direction === "y") {
+                                       self.element.style.overflowY = "hidden";
+                               } else {
+                                       self.element.style.overflowX = "hidden";
+                               }
+
+                               tauEvent.stopImmediatePropagation(event);
+                               tauEvent.preventDefault(event);
+                       }
+
+                       /**
+                        * Handles touch move events
+                        * @param {ns.widget.core.ScrollHandler} self
+                        * @param {MouseEvent|TouchEvent} event
+                        * @member ns.widget.core.ScrollHandler
+                        * @private
+                        * @static
+                        */
+                       function handleTouchmove(self, event) {
+                               var touches = event.touches,
+                                       touch = touches && touches[0],
+                                       x = 0,
+                                       y = 0;
+                               // check for exactly 1 touch event
+                               // or a mouse event
+
+                               if (self._dragging && (touches === undefined || touches.length <= 1)) {
+                                       tauEvent.stopImmediatePropagation(event);
+                                       tauEvent.preventDefault(event);
+
+                                       x = touch ? touch.clientX : event.clientX;
+                                       y = touch ? touch.clientY : event.clientY;
+                                       handleDragging(self, x, y);
+                               }
+                       }
+
+                       /**
+                        * Handles touch end event
+                        * @param {ns.widget.core.ScrollHandler} self
+                        * @param {MouseEvent|TouchEvent} event
+                        * @member ns.widget.core.ScrollHandler
+                        * @private
+                        * @static
+                        */
+                       function handleTouchend(self, event) {
+                               var ui = self.ui;
+
+                               if (self._dragging) {
+                                       self._dragging = false;
+
+                                       tauEvent.stopImmediatePropagation(event);
+                                       tauEvent.preventDefault(event);
+
+                                       // disable scroll indicator
+                                       if (self.options.direction === "y") {
+                                               self.element.style.overflowY = "auto";
+                                       } else {
+                                               self.element.style.overflowX = "auto";
+                                       }
+
+                                       ui.handle.classList.remove("ui-active");
+
+                                       if (self._hideTimer) {
+                                               window.clearTimeout(self._hideTimer);
+                                       }
+                                       self._hideTimer = window.setTimeout(function () {
+                                               ui.handler.classList.remove(classes.visible);
+                                       }, self.options.delay);
+                               }
+                       }
+
+                       /**
+                        * Build the scrollhander and scrollview DOM
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @method _build
+                        * @member ns.widget.core.ScrollHandler
+                        * @protected
+                        */
+                       prototype._build = function (element) {
+                               var node,
+                                       nodeStyle,
+                                       scrollviewViewStyle,
+                                       handler = document.createElement("div"),
+                                       handle = document.createElement("a"),
+                                       expander = document.createElement("span"),
+                                       track = document.createElement("div"),
+                                       thumb = document.createElement("span"),
+                                       options = this.options,
+                                       ui = this.ui;
+
+                               // Set scroll option for scrollview
+                               options.scroll = options.direction === "y" ? "y" : "x";
+                               node = ScrollviewBuild.call(this, element);
+
+                               handler.className = classes.handler + " " + classes.themePrefix + options.handlerTheme + " " + classes.directionPrefix + options.direction;
+                               expander.className = classes.expander;
+                               handle.className = classes.handle;
+                               thumb.className = classes.thumb;
+                               track.className = classes.track;
+
+                               handle.setAttribute("aria-label", (options.direction === "y" ? "Vertical" : "Horizontal") + " handler, double tap and move to scroll");
+
+                               expander.appendChild(thumb);
+                               handle.appendChild(expander);
+                               track.appendChild(handle);
+                               handler.appendChild(track);
+
+                               node.appendChild(handler);
+
+                               // Force scrollview to be full width of container
+                               nodeStyle = node.style;
+                               scrollviewViewStyle = node.firstElementChild.style;
+
+                               // NOTE: to hide native scrollbar, make sure that theme includes
+                               // *display* property set to *none* for
+                               // .ui-content.ui-scrollview-clip.ui-hide-scrollbar::-webkit-scrollbar
+                               element.classList.add(classes.hideNativeScrollbar);
+
+                               if (options.direction === "x") {
+                                       scrollviewViewStyle.display = "inline-block";
+                                       scrollviewViewStyle.minWidth = "100%";
+                               }
+                               if (options.direction === "y") {
+                                       scrollviewViewStyle.display = "block";
+                                       nodeStyle.minWidth = "100%";
+                               }
+
+                               ui.handler = handler;
+                               ui.handle = handle;
+                               ui.expander = expander;
+                               ui.track = track;
+                               ui.thumb = thumb;
+
+                               return node;
+                       };
+
+                       /**
+                        * Init the scrollhander and scrollview
+                        * @param {HTMLElement} element
+                        * @method _init
+                        * @protected
+                        * @member ns.widget.core.ScrollHandler
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self.ui,
+                                       page = ui.page;
+
+                               ScrollviewInit.call(self, element);
+
+                               if (ui.handler === null) {
+                                       ui.handler = element.querySelector("." + classes.handler);
+                               }
+
+                               if (ui.track === null) {
+                                       ui.track = element.querySelector("." + classes.track);
+                               }
+
+                               if (ui.handle === null) {
+                                       ui.handle = element.querySelector("." + classes.handle);
+                               }
+
+                               if (ui.thumb === null) {
+                                       ui.thumb = element.querySelector("." + classes.thumb);
+                               }
+
+                               if (page === null) {
+                                       page = selectors.getClosestByClass(element, PageClasses.uiPage);
+                               }
+                               ui.page = page;
+
+                               self.enableHandler(true);
+                       };
+
+                       /**
+                        * Refreshes the scrollhander bounds and dimensions
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.core.ScrollHandler
+                        */
+                       prototype._refresh = function () {
+                               var self = this,
+                                       element = self.element,
+                                       offsets = self._offsets,
+                                       ui = self.ui,
+                                       handle = ui.handle,
+                                       handleStyle = handle.style,
+                                       trackRect = ui.track.getBoundingClientRect(),
+                                       clipHeight = trackRect.height,
+                                       clipWidth = trackRect.width,
+                                       view = element.querySelector("." + Scrollview.classes.view),
+                                       viewRect = view.getBoundingClientRect(),
+                                       viewHeight = viewRect.height,
+                                       viewWidth = viewRect.width;
+
+
+                               if (self.options.direction === "y") {
+                                       handleStyle.height = floor(clipHeight / viewHeight * clipHeight) + "px";
+                               } else {
+                                       handleStyle.width = floor(clipWidth / viewWidth * clipWidth) + "px";
+                               }
+
+                               offsets.maxX = floor(max(0, clipWidth - CSSUtils.getElementWidth(handle, "inner", true)));
+                               offsets.maxY = floor(max(0, clipHeight - CSSUtils.getElementHeight(handle, "inner", true)));
+
+                               self._availableOffsetX = max(0, viewWidth - clipWidth);
+                               self._availableOffsetY = max(0, viewHeight - clipHeight);
+                       };
+
+                       /**
+                        * Binds the scrollhander and scrollview events
+                        * @param {HTMLElement} element
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.core.ScrollHandler
+                        */
+                       prototype._bindEvents = function (element) {
+                               var self = this,
+                                       callbacks = self._callbacks,
+                                       ui = self.ui;
+
+                               ScrollviewBindEvents.call(self, element);
+
+                               callbacks.scrollstart = handleScrollstart.bind(null, self);
+                               callbacks.scrollupdate = handleScrollupdate.bind(null, self);
+                               callbacks.scrollstop = handleScrollstop.bind(null, self);
+                               callbacks.touchstart = handleTouchstart.bind(null, self);
+                               callbacks.touchmove = handleTouchmove.bind(null, self);
+                               callbacks.touchend = handleTouchend.bind(null, self);
+                               callbacks.resize = self._refresh.bind(self);
+
+                               element.addEventListener("scrollstart", callbacks.scrollstart, false);
+                               element.addEventListener("scrollupdate", callbacks.scrollupdate, false);
+                               element.addEventListener("scrollstop", callbacks.scrollstop, false);
+                               ui.handle.addEventListener("vmousedown", callbacks.touchstart, false);
+                               ui.page.addEventListener("pageshow", callbacks.resize, false);
+                               document.addEventListener("vmousemove", callbacks.touchmove, false);
+                               document.addEventListener("vmouseup", callbacks.touchend, false);
+                               window.addEventListener("throttledresize", callbacks.resize, false);
+                               document.addEventListener("touchcancel", callbacks.touchend, true);
+
+                       };
+
+                       /**
+                        * Enables/disables handler
+                        *
+                        * #### TAU API
+                        *
+                        *              @example
+                        *              <div data-role="page" id="myPage">
+                        *                      <div data-role="content">
+                        *                              page content
+                        *                      <div>
+                        *              </div>
+                        *              <script>
+                        *                      var handlerElement = document.getElementById("myPage")
+                        *                                              .querySelector("[data-role=content]"),
+                        *                              scrollhandler = tau.widget.ScrollHandler(handlerElement);
+                        *                      scrollhandler.enableHandler(true);
+                        *              </script>
+                        *
+                        * #### jQuery API
+                        *
+                        *              @example
+                        *              <div data-role="page" id="myPage">
+                        *                      <div data-role="content">
+                        *                              page content
+                        *                      <div>
+                        *              </div>
+                        *              <script>
+                        *                      #("#myPage > div[data-role=content]).scrollhandler("enableHandler", true);
+                        *              </script>
+                        *
+                        * @param {boolean} enable
+                        * @return {boolean}
+                        * @method enableHandler
+                        * @member ns.widget.core.ScrollHandler
+                        */
+                       prototype.enableHandler = function (enable) {
+                               var self = this,
+                                       scrollBarDisabledClass = classes.scrollbarDisabled,
+                                       disabledClass = classes.disabled,
+                                       element = self.element,
+                                       parentClassList = element.parentNode.classList,
+                                       elementClassList = element.classList;
+
+                               if (enable !== undefined) {
+                                       self.options.handler = enable;
+                                       if (enable) {
+                                               parentClassList.add(scrollBarDisabledClass);
+                                               elementClassList.remove(disabledClass);
+                                               self._refresh();
+                                       } else {
+                                               parentClassList.remove(scrollBarDisabledClass);
+                                               elementClassList.add(disabledClass);
+                                       }
+                               }
+
+                               return self.options.handler;
+                       };
+
+                       /**
+                        * Sets the handlers theme
+                        * @param {string} theme
+                        * @method _setHandlerTheme
+                        * @protected
+                        * @member ns.widget.core.ScrollHandler
+                        */
+                       prototype._setHandlerTheme = function (theme) {
+                               var elementClassList = this.element.classList,
+                                       themePrefix = classes.themePrefix,
+                                       themeClass = themePrefix + theme;
+
+                               if (elementClassList.contains(themeClass) === false) {
+                                       elementClassList.remove(themePrefix + this.options.handlerTheme);
+                                       elementClassList.add(themeClass);
+                               }
+                       };
+
+                       /**
+                        * Destroys the scrollhander and scrollview DOM
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.core.ScrollHandler
+                        */
+                       prototype._destroy = function () {
+                               var self = this,
+                                       ui = self.ui,
+                                       callbacks = self._callbacks,
+                                       element = self.element;
+
+                               // Restore native scrollbar
+                               element.classList.remove(classes.hideNativeScrollbar);
+                               element.removeEventListener("scrollstart", callbacks.scrollstart, false);
+                               element.removeEventListener("scroll", callbacks.scrollupdate, false);
+                               element.removeEventListener("scrollstop", callbacks.scrollstop, false);
+                               ui.handle.removeEventListener("vmousedown", callbacks.touchstart, false);
+                               ui.page.removeEventListener("pageshow", callbacks.touchstart, false);
+                               document.removeEventListener("vmousemove", callbacks.touchmove, false);
+                               document.removeEventListener("vmouseup", callbacks.touchend, false);
+                               document.removeEventListener("touchcancel", callbacks.touchend, true);
+                               window.removeEventListener("throttledresize", callbacks.resize, false);
+
+                               ScrollviewDestroy.call(self);
+                       };
+
+                       ScrollHandler.prototype = prototype;
+
+                       ns.widget.core.ScrollHandler = ScrollHandler;
+                       engine.defineWidget(
+                               "ScrollHandler",
+                               "[data-role='content'][data-handler='true']:not([data-scroll='none']):not(.ui-scrollview-clip):not(.ui-scrolllistview),[data-handler='true'], .ui-scrollhandler",
+                               [
+                                       "enableHandler",
+                                       "scrollTo",
+                                       "ensureElementIsVisible",
+                                       "centerToElement",
+                                       "getScrollPosition",
+                                       "skipDragging",
+                                       "translateTo"
+                               ],
+                               ScrollHandler,
+                               "tizen"
+                       );
+                       }(window, window.document, ns));
+
+
+/*global window, ns, define */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ *
+ * #Tabs
+ * Tabs component shows an unordered list of buttons on the screen wrapped together in a single group.
+ *
+ * The Tabs component is a controller component for operate closely with SubTab and sectionChanger.
+ * So this component should be used with SubTab and sectionChanger.
+ *
+ * ##Default selectors
+ * By default, all elements with the class="ui-tabs" or data-role="tabs" attribute are displayed as a tabs components.
+ *
+ * ##HTML Examples
+ *
+ *      @example
+ *      <div id="tabs" class="ui-tabs">
+ *          <div class="ui-sub-tab">
+ *              <ul>
+ *                  <li><a href="#" class="ui-btn-active">Tab1</a></li>
+ *                  <li><a href="#">Tab2</a></li>
+ *                  <li><a href="#">Tab3</a></li>
+ *              </ul>
+ *          </div>
+ *          <div class="ui-section-changer">
+ *              <div>
+ *                  <section class="ui-section-active">
+ *                      <ul class="ui-listview">
+ *                          <li class="ui-li-static">
+ *                              Section 1
+ *                          </li>
+ *                      </ul>
+ *                  </section>
+ *                  <section class="ui-section-active">
+ *                      <ul class="ui-listview">
+ *                          <li class="ui-li-static">
+ *                              Section 2
+ *                          </li>
+ *                      </ul>
+ *                  </section>
+ *                  <section class="ui-section-active">
+ *                      <ul class="ui-listview">
+ *                          <li class="ui-li-static">
+ *                              Section 3
+ *                          </li>
+ *                      </ul>
+ *                  </section>
+ *              </div>
+ *          </div>
+ *      </div>
+ *
+ * ##Manual constructor
+ * For manual creation of tabs widget you can use constructor of widget
+ *
+ *      @example
+ *      <script>
+ *          var tabsElement = document.getElementById("tabs"),
+ *                tabs;
+ *          tabs = tau.widget.Tabs(tabsElement);
+ *      </script>
+ *
+ * @since 2.4
+ * @class ns.widget.core.Tabs
+ * @component-selector .ui-tabs, [data-role]="tabs"
+ * @extends ns.widget.core.BaseWidget
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               engine = ns.engine,
+                               selectors = ns.util.selectors,
+                               Page = ns.widget.core.Page,
+                               events = ns.event,
+                               Tabs = function () {
+                                       var self = this;
+
+                                       self._ui = {};
+                                       self._component = {};
+                                       self.options = {
+                                               changeDuration: 200
+                                       };
+                               },
+                               classes = {
+                                       /**
+                                        * Standard tabs widget
+                                        * @style ui-tabs-with-title
+                                        * @member ns.widget.core.Tabs
+                                        */
+                                       TABS: "ui-tabs",
+                                       /**
+                                       * Set tabs component with title
+                                       * @style ui-tabs-with-title
+                                       * @member ns.widget.core.Tabs
+                                       */
+                                       WITH_TITLE: "ui-tabs-with-title",
+                                       TITLE: "ui-title",
+                                       PAGE: Page.classes.uiPage
+                               },
+                               prototype = new BaseWidget();
+
+                       Tabs.prototype = prototype;
+                       Tabs.classes = classes;
+
+                       /**
+                        * bind Tabs component necessary events
+                        * @method bindTabsEvents
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Tabs
+                        * @private
+                        * @static
+                        */
+                       function bindTabsEvents(element) {
+                               var self = this;
+
+                               events.on(element, "tabchange sectionchange", self, false);
+                               window.addEventListener("resize", self, false);
+                       }
+
+                       /**
+                        * unbind Tabs component necessary events
+                        * @method unBindTabsEvents
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Tabs
+                        * @private
+                        * @static
+                        */
+                       function unBindTabsEvents(element) {
+                               var self = this;
+
+                               events.off(element, "tabchange sectionchange", self, false);
+                               window.removeEventListener("resize", self, false);
+                       }
+
+                       /**
+                        * Handle events
+                        * @method handleEvent
+                        * @param {Event} event
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "tabchange":
+                                               self._onTabChange(event);
+                                               break;
+                                       case "sectionchange":
+                                               self._onSectionChange(event);
+                                               break;
+                                       case "resize":
+                                               self._refresh();
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * Build the Tabs component
+                        * @method _build
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._build = function (element) {
+
+                               element.classList.add(classes.TABS);
+                               if (element.getElementsByClassName(classes.TITLE).length) {
+                                       element.classList.add(classes.WITH_TITLE);
+                               }
+                               return element;
+                       };
+
+                       /**
+                        * Init height of the Tabs component
+                        * @method _initHeight
+                        * @protected
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._initHeight = function () {
+                               var self = this,
+                                       page;
+
+                               if (!self.element.style.height) {
+                                       page = ns.widget.Page(self._ui.page);
+                                       self.element.style.height = page.getContentHeight() + "px";
+                               }
+                       };
+
+                       /**
+                        * Init the Tabs component
+                        * @method _init
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui;
+
+                               ui.page = selectors.getClosestByClass(element, classes.PAGE);
+                               ui.subtab = element.querySelector(ns.widget.core.SubTab.selector);
+                               ui.title = element.getElementsByClassName(classes.TITLE)[0];
+                               ui.sectionChanger = element.querySelector("[data-role='section-changer'], .ui-section-changer");
+                               self._component.subtab = ns.widget.SubTab(ui.subtab);
+                               self._changed = false;
+                               self._lastIndex = 0;
+                               self._initHeight();
+                               self._initSectionChanger();
+                               return element;
+                       };
+
+                       /**
+                        * Pageshow event handler
+                        * @method _onPageBeforeShow
+                        * @protected
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._initSectionChanger = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       sectionChanger = ui.sectionChanger,
+                                       sectionChangerStyle,
+                                       subtabOffsetHeight = ui.subtab.offsetHeight,
+                                       title = ui.title;
+
+                               if (sectionChanger) {
+                                       sectionChangerStyle = sectionChanger.style;
+                                       sectionChangerStyle.width = window.innerWidth + "px";
+                                       sectionChangerStyle.height = (self.element.offsetHeight - subtabOffsetHeight -
+                                               (title ? title.offsetHeight : 0)) + "px";
+                                       self._component.sectionChanger = engine.instanceWidget(sectionChanger, "SectionChanger");
+                               }
+
+                       };
+
+                       /**
+                        * Tabchange event handler
+                        * @method _onTabChange
+                        * @protected
+                        * @param {Event} event
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._onTabChange = function (event) {
+                               var self = this,
+                                       index = event.detail.active,
+                                       sectionChanger = self._component.sectionChanger;
+
+                               if (self._changed) {
+                                       self._changed = false;
+                               } else if (self._lastIndex !== index) {
+                                       self._changed = true;
+                                       sectionChanger.setActiveSection(index, self.options.changeDuration, false, false);
+                               }
+                               self._lastIndex = index;
+                       };
+
+                       /**
+                        * Sectionchange event handler
+                        * @method _onSectionChange
+                        * @protected
+                        * @param {Event} event
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._onSectionChange = function (event) {
+                               var self = this,
+                                       index = event.detail.active,
+                                       subtab = self._component.subtab;
+
+                               if (self._changed) {
+                                       self._changed = false;
+                               } else if (self._lastIndex !== index) {
+                                       self._changed = true;
+                                       subtab.setActive(index);
+                               }
+                               self._lastIndex = index;
+                       };
+
+                       /**
+                        * bind event to the Tabs component
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this;
+
+                               bindTabsEvents.call(self, self.element);
+                       };
+
+                       /**
+                        * destroy the Tabs component
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._destroy = function () {
+                               var self = this;
+
+                               unBindTabsEvents.call(self, self.element);
+                               self._ui = null;
+                               self._component = null;
+                       };
+
+                       /**
+                        * Refresh Tabs component
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._refresh = function () {
+                               this._initSectionChanger();
+                       };
+                       /**
+                        * Set the active tab
+                        * @method _setIndex
+                        * @protected
+                        * @param {number} index
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._setIndex = function (index) {
+                               var self = this,
+                                       length = self._ui.sectionChanger.getElementsByTagName("section").length;
+
+                               if (index < length && !(index < 0)) {
+                                       self._component.subtab.setActive(index);
+                               } else {
+                                       ns.warn("You inserted the wrong index value");
+                               }
+
+                       };
+
+                       /**
+                        * Set the active tab
+                        * @method setIndex
+                        * @public
+                        * @param {number} index
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype.setIndex = function (index) {
+                               this._setIndex(index);
+                       };
+
+                       /**
+                        * Get the active tab
+                        * @method _getIndex
+                        * @protected
+                        * @return {number} index
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype._getIndex = function () {
+                               return this._lastIndex;
+                       };
+
+                       /**
+                        * Get the active tab
+                        * @method getIndex
+                        * @public
+                        * @return {number} index
+                        * @member ns.widget.core.Tabs
+                        */
+                       prototype.getIndex = function () {
+                               return this._getIndex();
+                       };
+                       ns.widget.core.Tabs = Tabs;
+                       engine.defineWidget(
+                               "Tabs",
+                               "[data-role='tabs'], .ui-tabs",
+                               [
+                                       "setIndex", "getIndex"
+                               ],
+                               Tabs,
+                               "core"
+                       );
+
+                       }(window.document, ns));
+
+/*global define, ns */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*jslint nomen: true */
+/**
+ * # Grid View
+ * Grid View components provides a list of grid-type and presents contents that are easily identified as images.
+ *
+ * ##Default Selectors
+ * By default, all ul elements with the class="ui-gridview" or data-role="gridview" attribute are displayed as grid view components.
+ *
+ * ##Manual constructor
+ *
+ *      @example
+ *      <ul id="gridview" class="ui-gridview">
+ *          <li class="ui-gridview-item">
+ *              <img class="ui-gridview-image" src="images/1.jpg">
+ *              <div class="ui-gridview-handler"></div>
+ *          </li>
+ *          <li class="ui-gridview-item">
+ *              <img class="ui-gridview-image" src="images/2.jpg">
+ *              <div class="ui-gridview-handler"></div>
+ *          </li>
+ *          <li class="ui-gridview-item">
+ *              <img class="ui-gridview-image" src="images/3.jpg">
+ *              <div class="ui-gridview-handler"></div>
+ *          </li>
+ *          <li class="ui-gridview-item">
+ *              <img class="ui-gridview-image" src="images/4.jpg">
+ *              <div class="ui-gridview-handler"></div>
+ *          </li>
+ *      </ul>
+ *      <script>
+ *          var elGridView = document.getElementById("gridview"),
+ *               gridView = tau.widget.GridView(elGridView);
+ *      </script>
+ *
+ * @since 2.4
+ * @class ns.widget.mobile.GridView
+ * @component-selector .ui-gridview, [data-role]="gridview"
+ * @extends ns.widget.BaseWidget
+ */
+(function (document, ns) {
+       "use strict";
+                               var BaseWidget = ns.widget.BaseWidget,
+                               BaseKeyboardSupport = ns.widget.core.BaseKeyboardSupport,
+                               engine = ns.engine,
+                               utilsEvents = ns.event,
+                               utilsSelectors = ns.util.selectors,
+                               utilsDom = ns.util.DOM,
+                               pageEvents = ns.widget.core.Page.events,
+                               Popup = ns.widget.mobile.Popup,
+                               PopupConstructor = ns.widget.Popup,
+                               popupSelector = Popup.selector,
+                               popupEvents = Popup.events,
+                               STYLE_PATTERN = ".ui-gridview li:nth-child({index})",
+                               MATRIX_REGEXP = /matrix\((.*), (.*), (.*), (.*), (.*), (.*)\)/,
+                               DATA_ROLE = "data-role",
+                               RESIZE_TIMEOUT = 300,
+                               BORDER_SIZE = 16,
+                               direction = {
+                                       PREV: 0,
+                                       NEXT: 1
+                               },
+                               labels = {
+                                       IN: "in",
+                                       OUT: "out",
+                                       NONE: "none"
+                               },
+                               classes = {
+                                       /**
+                                        * Standard gridview widget
+                                        * @style ui-gridview
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       GRIDLIST: "ui-gridview",
+                                       /**
+                                        * Set element as item of gridview items list
+                                        * @style ui-gridview-item
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       ITEM: "ui-gridview-item",
+                                       /**
+                                        * Set item of gridview as active
+                                        * @style ui-gridview-item-active
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       ITEM_ACTIVE: "ui-gridview-item-active",
+                                       /**
+                                        * Set helper for gridview items list
+                                        * @style ui-gridview-helper
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       HELPER: "ui-gridview-helper",
+                                       /**
+                                        * Create holder element to help reordering
+                                        * @style ui-gridview-holder
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       HOLDER: "ui-gridview-holder",
+                                       /**
+                                        * Set element as image of gridview items list
+                                        * @style ui-gridview-image
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       IMAGE: "ui-gridview-image",
+                                       /**
+                                        * Set label-type as label in gridview
+                                        * @style ui-gridview-label
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       LABEL: "ui-gridview-label",
+                                       /**
+                                        * Set label-type as label-in in gridview
+                                        * @style ui-gridview-label-in
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       LABEL_IN: "ui-gridview-label-in",
+                                       /**
+                                        * Set label-type as label-out in gridview
+                                        * @style ui-gridview-label-out
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       LABEL_OUT: "ui-gridview-label-out",
+                                       /**
+                                        * Set handler for gridview items list
+                                        * @style ui-gridview-handler
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       HANDLER: "ui-gridview-handler",
+                                       /**
+                                        * Set image as checked
+                                        * @style ui-gridview-image-checked
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       CHECKED: "ui-gridview-image-checked",
+                                       /**
+                                        * Class indicates that gridview item has label
+                                        * @style ui-gridview-item-has-label
+                                        * @member ns.widget.mobile.GridView
+                                        */
+                                       ITEM_HAS_LABEL: "ui-gridview-item-has-label"
+                               },
+                               selectors = {
+                                       ANY_NOT_IMAGE: "*:not(." + classes.IMAGE + ")"
+                               },
+                               GridView = function () {
+                                       var self = this;
+
+                                       BaseKeyboardSupport.call(this);
+
+                                       self.options = {};
+                                       self._direction = 0;
+                                       self._styleElement = null;
+                                       self._inPopup = null;
+                                       self._ui = {
+                                               listElements: [],
+                                               listItems: [],
+                                               helper: {},
+                                               holder: {},
+                                               scrollableParent: null,
+                                               content: null
+                                       };
+                                       self._borderSize = BORDER_SIZE;
+                                       self._refreshSizesCallback = refreshSizes.bind(null, this);
+                               },
+                               prototype = new BaseWidget();
+
+                       GridView.prototype = prototype;
+                       GridView.classes = classes;
+
+                       function getScrollableParent(element) {
+                               var overflow;
+
+                               while (element !== document.body) {
+                                       overflow = utilsDom.getCSSProperty(element, "overflow-y");
+                                       if (overflow === "scroll" || (overflow === "auto" && element.scrollHeight > element.clientHeight)) {
+                                               return element;
+                                       }
+                                       element = element.parentNode;
+                               }
+
+                               return null;
+                       }
+
+                       function refreshSizes(gridViewInstance) {
+                               gridViewInstance._setItemSize();
+                               gridViewInstance._checkItemLabel();
+                               gridViewInstance._setGridStyle();
+                               gridViewInstance._refreshItemsInfo();
+                               gridViewInstance._calculateListHeight();
+                               gridViewInstance._inPopup.refresh();
+                       }
+
+                       /**
+                        * Configure options for GridView
+                        * @method _configure
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._configure = function () {
+                               /**
+                                * Options for widget.
+                                * @property {Object} options
+                                * @property {number} [options.cols=4] the number of columns to be displayed (for landscape 7 mobile)
+                                * @property {boolean} [options.reorder=false] represents whether grid view is reorder mode
+                                * @property {string} [options.label="none"] type of label to be attached to grid item("none", "in", "out")
+                                * @property {number} [options.minWidth="auto"] minimum width px of grid item(number or "auto")
+                                * @property {number} [options.minCols=1] the minimum number of columns
+                                * @property {number} [options.maxCols=5] the maximum number of columns (for landscape 7 mobile)
+                                * @member ns.widget.mobile.GridView
+                                */
+                               this.options = {
+                                       cols: 0, // auto - fit to screen resolution
+                                       reorder: false,
+                                       label: labels.NONE,
+                                       minWidth: "auto",
+                                       minCols: 2,
+                                       maxCols: 5
+                               };
+                               this._direction = direction.NEXT;
+                       };
+
+                       /**
+                        * Build GridView
+                        * @method _build
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._build = function (element) {
+                               element.classList.add("ui-gridview-cols");
+                               return element;
+                       };
+
+                       /**
+                        * Initialize GridView
+                        * @method _init
+                        * @param {HTMLElement} element
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._init = function (element) {
+                               var self = this,
+                                       ui = self._ui,
+                                       popup;
+
+                               ui.listElements = [].slice.call(self.element.getElementsByTagName("li"));
+                               self._setItemSize();
+                               self._setLabel(element);
+                               self._checkItemLabel();
+                               self._setReorder(element, self.options.reorder);
+                               self._calculateListHeight();
+                               self._initCheckboxState(element);
+
+                               self._ui.content = utilsSelectors.getClosestByClass(element, "ui-content") || window;
+                               self._ui.scrollableParent = getScrollableParent(element) || self._ui.content;
+                               popup = utilsSelectors.getClosestBySelector(element, popupSelector);
+                               if (popup) {
+                                       self._inPopup = PopupConstructor(popup);
+                               }
+                       };
+
+                       function animationEndCallback(event) {
+                               var classList = event.target.classList;
+
+                               if (classList.contains(classes.ITEM)) {
+                                       classList.add(classes.ITEM_ACTIVE);
+                                       event.target.style.animation = "";
+                               }
+                       }
+
+                       function onSetGridStyle(self) {
+                               self._setGridStyle();
+                       }
+
+                       prototype._onResize = function () {
+                               var self = this;
+
+                               self.options.cols = 0;
+                               self.refresh();
+                       };
+
+                       prototype._onResizeTimeOut = function () {
+                               var self = this;
+
+                               clearTimeout(self._resizeTimeout);
+                               self._resizeTimeout = window.setTimeout(function () {
+                                       self._onResize();
+                               }, RESIZE_TIMEOUT);
+                       };
+
+                       /**
+                        * Bind events for GridView
+                        * @method _bindEvents
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._bindEvents = function () {
+                               var self = this,
+                                       page = self._getParentPage(self.element),
+                                       popup = this._inPopup;
+
+                               self._onSetGridStyle = onSetGridStyle.bind(null, self);
+                               if (popup) {
+                                       utilsEvents.on(popup.element, popupEvents.transition_start, self._refreshSizesCallback);
+                               }
+
+                               self.on("animationend webkitAnimationEnd", animationEndCallback);
+
+                               self.on("change", self);
+                               utilsEvents.on(window, "resize", self, true);
+
+                               utilsEvents.on(page, pageEvents.SHOW, self._onSetGridStyle);
+                       };
+
+                       /**
+                        * Unbind events for GridView
+                        * @method _unbindEvents
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._unbindEvents = function () {
+                               var self = this,
+                                       element = self.element,
+                                       page = self._getParentPage(element),
+                                       popup = self._inPopup;
+
+                               utilsEvents.disableGesture(element);
+
+                               utilsEvents.off(element, "drag dragstart dragend dragcancel dragprepare", self);
+                               utilsEvents.off(element, "pinchin pinchout", self);
+                               if (popup) {
+                                       utilsEvents.off(popup.element, popupEvents.before_show, this._refreshSizesCallback);
+                               }
+                               self.off("animationend webkitAnimationEnd", animationEndCallback);
+                               self.off("change", self);
+                               utilsEvents.off(page, pageEvents.SHOW, self._onSetGridStyle);
+                       };
+
+                       /**
+                        * Refresh GridView
+                        * @method _refresh
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._refresh = function () {
+                               var self = this,
+                                       ui = self._ui,
+                                       element = self.element;
+
+                               self._removeGridStyle();
+                               ui.listElements = [].slice.call(element.getElementsByTagName("li"));
+                               self._setItemSize();
+                               self._setGridStyle();
+                               self._setLabel(element);
+                               self._checkItemLabel();
+                               self._setReorder(element, self.options.reorder);
+                               self._calculateListHeight();
+                               self._ui.content = utilsSelectors.getClosestByClass(element, "ui-content") || window;
+                               self._ui.scrollableParent = getScrollableParent(element) || self._ui.content;
+                       };
+
+                       /**
+                        * Destroy GridView
+                        * @method _destroy
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._destroy = function () {
+                               this._unbindEvents();
+                               this._removeGridStyle();
+                               this._inPopup = null;
+                       };
+
+                       /**
+                        * Handle events
+                        * @method handleEvent
+                        * @public
+                        * @param {Event} event Event
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype.handleEvent = function (event) {
+                               var self = this;
+
+                               switch (event.type) {
+                                       case "change":
+                                               self._shadeCheckbox(event.target);
+                                               break;
+                                       case "dragprepare":
+                                               if (event.detail.srcEvent.srcElement.classList.contains(classes.HANDLER)) {
+                                                       break;
+                                               }
+                                               event.preventDefault();
+                                               break;
+                                       case "dragstart":
+                                               if (event.detail.srcEvent.srcElement.classList.contains(classes.HANDLER)) {
+                                                       self._start(event);
+                                                       break;
+                                               }
+                                               event.preventDefault();
+                                               break;
+                                       case "drag":
+                                               self._move(event);
+                                               break;
+                                       case "dragend":
+                                               self._end(event);
+                                               break;
+                                       case "pinchin":
+                                               self._in(event);
+                                               break;
+                                       case "pinchout":
+                                               self._out(event);
+                                               break;
+                                       case "resize":
+                                               self._onResizeTimeOut();
+                                               break;
+                               }
+                       };
+
+                       /**
+                        * Method for dragstart event
+                        * @method _start
+                        * @protected
+                        * @param {Event} event Event
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._start = function (event) {
+                               var self = this,
+                                       element = self.element,
+                                       helper = self._ui.helper,
+                                       helperElement = event.detail.srcEvent.srcElement.parentElement,
+                                       helperElementComputed = window.getComputedStyle(helperElement, null),
+                                       helperStyle = helperElement.style,
+                                       transformProperty = helperElementComputed.getPropertyValue("webkit-transform") ||
+                                               helperElementComputed.getPropertyValue("transform") || "",
+                                       translated = transformProperty.match(MATRIX_REGEXP),
+                                       holder,
+                                       top = 0,
+                                       left = 0;
+
+                               self._refreshItemsInfo();
+                               if (translated.length > 0) {
+                                       top = parseInt(translated[6], 10);
+                                       left = parseInt(translated[5], 10);
+                               }
+                               helperElement.classList.add(classes.HELPER);
+                               holder = self._createHolder();
+                               element.insertBefore(holder, helperElement);
+                               element.appendChild(helperElement);
+                               helperStyle.top = top + "px";
+                               helperStyle.left = left + "px";
+
+                               helper.element = helperElement;
+                               helper.style = helperStyle;
+                               helper.position = {
+                                       startTop: top,
+                                       startLeft: left,
+                                       moveTop: top,
+                                       moveLeft: left
+                               };
+
+                               helper.startX = event.detail.estimatedX;
+                               helper.startY = event.detail.estimatedY;
+                               helper.width = parseFloat(helperElementComputed.getPropertyValue("width")) || 0;
+                               helper.height = parseFloat(helperElementComputed.getPropertyValue("height")) || 0;
+
+                               self._ui.holder = holder;
+                               helper.element = helperElement;
+                               self._ui.helper = helper;
+                       };
+
+                       /**
+                        * Method for drag event
+                        * @method _move
+                        * @protected
+                        * @param {Event} event Event
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._move = function (event) {
+                               var self = this,
+                                       ui = self._ui,
+                                       element = self.element,
+                                       listItems = ui.listItems,
+                                       length = listItems.length,
+                                       helper = self._ui.helper,
+                                       style = helper.style,
+                                       position = helper.position,
+                                       helperElement = helper.element,
+                                       startX = helper.startX,
+                                       startY = helper.startY,
+                                       moveX,
+                                       moveY,
+                                       i,
+                                       scrollableParent = self._ui.scrollableParent,
+                                       autoScrollDown,
+                                       autoScrollUp,
+                                       scrollUnit;
+
+                               moveY = position.startTop + event.detail.estimatedY - startY;
+                               moveX = position.startLeft + event.detail.estimatedX - startX;
+                               autoScrollDown = (element.offsetTop + moveY + helperElement.offsetHeight) - (scrollableParent.offsetHeight + scrollableParent.scrollTop);
+                               autoScrollUp = scrollableParent.scrollTop - (element.offsetTop + moveY);
+                               scrollUnit = helperElement.offsetHeight / 5;
+                               if (autoScrollDown > 0 && ((helperElement.offsetTop + helperElement.offsetHeight) < element.offsetHeight)) {
+                                       scrollableParent.scrollTop += scrollUnit;
+                                       moveY += scrollUnit;
+                                       position.startTop += scrollUnit;
+                               }
+                               if (autoScrollUp > 0 && helperElement.offsetTop > 0) {
+                                       scrollableParent.scrollTop -= scrollUnit;
+                                       moveY -= scrollUnit;
+                                       position.startTop -= scrollUnit;
+                               }
+                               style.top = moveY + "px";
+                               style.left = moveX + "px";
+                               position.moveTop = moveY;
+                               position.moveLeft = moveX;
+
+                               for (i = 0; i < length; i++) {
+                                       if (self._compareOverlapItem(listItems[i])) {
+                                               self._direction ? element.insertBefore(ui.holder, listItems[i].element.nextSibling) : element.insertBefore(ui.holder, listItems[i].element);
+                                               self._refreshItemsInfo();
+                                               self._setItemMargin();
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Method for dragend event
+                        * @method _end
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._end = function () {
+                               var self = this,
+                                       element = self.element,
+                                       helper = self._ui.helper,
+                                       helperElement = helper.element,
+                                       holder = self._ui.holder;
+
+                               helperElement.classList.remove(classes.HELPER);
+                               helper.style.top = 0;
+                               helper.style.left = 0;
+                               element.insertBefore(helperElement, holder);
+                               element.removeChild(holder);
+                               self._setItemMargin();
+                               self._ui.helper = {};
+                       };
+
+                       /**
+                        * Method for pinchout event
+                        * @method _out
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._out = function () {
+                               var self = this,
+                                       options = self.options,
+                                       cols = options.cols,
+                                       minCols = options.minCols;
+
+                               if (cols > minCols) {
+                                       self._minWidth = null;
+                                       options.cols = cols - 1;
+                                       self._refresh();
+                               }
+                       };
+
+                       /**
+                        * Method for pinchin event
+                        * @method _in
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._in = function () {
+                               var self = this,
+                                       options = self.options,
+                                       cols = options.cols,
+                                       maxCols = options.maxCols;
+
+                               if (maxCols === null || cols < maxCols) {
+                                       options.cols = cols + 1;
+                                       self._minWidth = null;
+                                       self._refresh();
+                               }
+                       };
+
+                       /**
+                        * Check whether a selected item is overlapped with adjacent items
+                        * @method _compareOverlapItem
+                        * @protected
+                        * @param {HTMLElement} item
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._compareOverlapItem = function (item) {
+                               var self = this,
+                                       helper = self._ui.helper,
+                                       position = helper.position,
+                                       overlapWidth,
+                                       overlapHeight;
+
+                               if (helper.element === item.element) {
+                                       return false;
+                               }
+
+                               if (position.moveTop > item.top || (position.moveTop === item.top && position.moveLeft > item.left)) {
+                                       self._direction = direction.PREV;
+                               } else {
+                                       self._direction = direction.NEXT;
+                               }
+
+                               overlapWidth = position.moveTop > item.top ? item.top + item.height - position.moveTop : position.moveTop + helper.height - item.top;
+                               overlapHeight = position.moveLeft > item.left ? item.left + item.width - position.moveLeft : position.moveLeft + helper.width - item.left;
+
+                               if (overlapWidth <= 0 || overlapHeight <= 0) {
+                                       return false;
+                               } else if (overlapWidth * overlapHeight > item.height * item.width / 2) {
+                                       return true;
+                               }
+                               return false;
+                       };
+
+                       /**
+                        * Calculate and set the height of grid view depending on the number of columns
+                        * @method _calculateListHeight
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._calculateListHeight = function () {
+                               var self = this,
+                                       listElements = self._ui.listElements,
+                                       firstLiComputed = listElements.length && window.getComputedStyle(listElements[0], null),
+                                       itemHeight,
+                                       rows;
+
+                               rows = Math.ceil(listElements.length / self.options.cols);
+                               itemHeight = parseFloat(firstLiComputed.getPropertyValue("height")) || 0;
+
+                               if (self.element.getAttribute("data-label") === "out") {
+                                       self.element.style.height = (itemHeight * rows) + "px";
+                               } else {
+                                       self.element.style.height = (itemHeight + 1) * rows + 1 + "px";
+                               }
+                       };
+
+                       /**
+                        * Set checkbox initial state
+                        * @method _initCheckboxState
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._initCheckboxState = function (element) {
+                               var checkboxNodeList = element.querySelectorAll("input[type=checkbox]"),
+                                       i = 0,
+                                       self = this,
+                                       length = checkboxNodeList.length;
+
+                               for (i = 0; i < length; i++) {
+                                       self._shadeCheckbox(checkboxNodeList[i]);
+                               }
+                       }
+
+                       /**
+                        * Set darker background for checked element in the grid
+                        * @method _shadeCheckbox
+                        * @protected
+                        * @param {HTMLElement} target
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._shadeCheckbox = function (target) {
+                               target.parentElement.classList.toggle(classes.CHECKED, target.checked);
+                       }
+
+                       /**
+                        * Update information of each list item
+                        * @method _refreshItemsInfo
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._refreshItemsInfo = function () {
+                               var self = this,
+                                       listElements = self._ui.listElements,
+                                       length = listElements.length,
+                                       listItems = [],
+                                       translated,
+                                       li,
+                                       i,
+                                       top = 0,
+                                       liComputed = null,
+                                       left = 0,
+                                       transformProperty = "";
+
+                               for (i = 0; i < length; i++) {
+                                       li = listElements[i];
+                                       liComputed = window.getComputedStyle(li, null);
+                                       transformProperty = liComputed.getPropertyValue("webkit-transform") ||
+                                               liComputed.getPropertyValue("transform") || "";
+                                       translated = transformProperty.match(MATRIX_REGEXP);
+                                       if (translated && translated.length > 0) {
+                                               top = parseInt(translated[6], 10);
+                                               left = parseInt(translated[5], 10);
+                                       }
+                                       listItems.push({
+                                               top: top,
+                                               left: left,
+                                               height: parseFloat(liComputed.getPropertyValue("width")) || 0,
+                                               width: parseFloat(liComputed.getPropertyValue("width")) || 0,
+                                               element: li
+                                       });
+                               }
+
+                               self._ui.listItems = listItems;
+
+                       };
+
+                       /**
+                        * Create holder element to help reordering
+                        * @method _createHolder
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._createHolder = function () {
+                               var holder = document.createElement("li"),
+                                       classList = holder.classList;
+
+                               classList.add(classes.ITEM);
+                               classList.add(classes.HOLDER);
+
+                               return holder;
+                       };
+
+                       /**
+                        * Set the margins of each item
+                        * @method _setItemMargin
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._setItemMargin = function () {
+                               var self = this,
+                                       options = self.options,
+                                       // list elements represents current order of list item in DOM tree
+                                       listElements = [].slice.call(self.element.getElementsByTagName("li")),
+                                       i,
+                                       length = listElements.length,
+                                       cols = options.cols,
+                                       elementStyle = null,
+                                       borderSize = self._borderSize;
+
+                               // set margin
+                               for (i = 0; i < length; i++) {
+                                       elementStyle = listElements[i].style;
+                                       // all without last in raw should have right border
+                                       if (i % cols < cols - 1) {
+                                               elementStyle.marginRight = borderSize + "px";
+                                       } else {
+                                               elementStyle.marginRight = "0";
+                                       }
+                                       // first row doesn't have top margin
+                                       if (i > cols - 1) {
+                                               elementStyle.marginTop = borderSize + "px";
+                                       } else {
+                                               elementStyle.marginTop = "0";
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Set the width of each item
+                        * @method _setItemSize
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._setItemSize = function () {
+                               var self = this,
+                                       options = self.options,
+                                       parentComputedStyle = window.getComputedStyle(self.element, null),
+                                       parentWidth = parseFloat(parentComputedStyle.getPropertyValue("width")) || 0,
+                                       minWidth = self._minWidth,
+                                       listElements = self._ui.listElements,
+                                       length = listElements.length,
+                                       cols,
+                                       i,
+                                       width,
+                                       borderSize = self._borderSize,
+                                       elementStyle = null,
+                                       content;
+
+                               if (options.minWidth === "auto") {
+                                       minWidth = 0;
+                               } else {
+                                       minWidth = (minWidth) ? parseInt(minWidth, 10) : null;
+                               }
+                               self._minWidth = minWidth;
+
+                               cols = options.cols;
+                               if (cols === 0) { // fit number of columns to screen resolution
+                                       content = window.getComputedStyle(self.element, ":after").content;
+                                       content = content.replace(/[^0-9]+/, "");
+                                       if (content) {
+                                               cols = parseInt(content.replace(/\"/g, ""), 10);
+                                       }
+                               }
+                               if (cols === 0 && minWidth > 0) { // if cols are still undefined
+                                       cols = minWidth ? Math.floor(parentWidth / minWidth) : cols;
+                               }
+                               if (cols === 0) {
+                                       cols = options.minCols;
+                               }
+                               options.cols = cols;
+
+                               self._itemSize = (parentWidth - (cols - 1) * borderSize) / cols;
+                               self._itemHeight = self._itemSize;
+
+                               width = self._itemSize + "px";
+
+                               self._setItemMargin();
+
+                               // set size
+                               for (i = 0; i < length; i++) {
+                                       elementStyle = listElements[i].style;
+                                       elementStyle.width = width;
+                                       // item height is the same like width
+                                       elementStyle.height = width;
+                               }
+                               // check label
+                               for (i = 0; i < length; i++) {
+                                       // check label
+                                       if (listElements[i].querySelector("*:not(img)")) {
+                                               listElements[i].classList.add(classes.ITEM_HAS_LABEL);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Check item label and add class to indicate it
+                        * @method _checkItemLabel
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._checkItemLabel = function () {
+                               var self = this,
+                                       listElements = self._ui.listElements,
+                                       length = listElements.length,
+                                       i;
+
+                               for (i = 0; i < length; i++) {
+                                       // check label
+                                       if (listElements[i].querySelector(selectors.ANY_NOT_IMAGE)) {
+                                               listElements[i].classList.add(classes.ITEM_HAS_LABEL);
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Get parent page element
+                        * @method _getParentPage
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @return {HTMLElement}
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._getParentPage = function (element) {
+                               while (element && element !== document.body) {
+                                       if (element.getAttribute(DATA_ROLE) === "page" || element.classList.contains("ui-page") === true) {
+                                               return element;
+                                       }
+                                       element = element.parentNode;
+                               }
+                               return document.body;
+                       };
+
+                       /**
+                        * Toggle grid view reordering mode
+                        * @method _setReorder
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @param {boolean} reorder
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._setReorder = function (element, reorder) {
+                               var self = this,
+                                       options = self.options,
+                                       page = self._getParentPage(element),
+                                       appbarElement,
+                                       appbar;
+
+                               utilsEvents.disableGesture(element);
+
+                               if (reorder) {
+                                       utilsEvents.enableGesture(
+                                               element,
+                                               new utilsEvents.gesture.Drag({
+                                                       blockVertical: false
+                                               })
+                                       );
+                                       utilsEvents.on(element, "drag dragstart dragend dragcancel dragprepare", self, true);
+                                       utilsEvents.off(element, "pinchin pinchout", self);
+                                       element.classList.add("ui-gridview-reorder");
+                                       // create handlers if not exists
+                                       self._ui.listElements.forEach(function (liItem) {
+                                               var handler = null;
+
+                                               if (!liItem.querySelector("." + classes.HANDLER)) {
+                                                       handler = document.createElement("div");
+                                                       handler.classList.add(classes.HANDLER);
+                                                       liItem.appendChild(handler);
+                                               }
+                                       });
+
+                                       // lock AppBar if exists
+                                       if (page) {
+                                               appbarElement = page.querySelector(ns.widget.core.Appbar.selector);
+                                               if (appbarElement) {
+                                                       appbar = ns.widget.Appbar(appbarElement);
+                                                       appbar.lockExpanding(true);
+                                               }
+                                       }
+                               } else {
+                                       utilsEvents.enableGesture(
+                                               element,
+                                               new utilsEvents.gesture.Pinch()
+                                       );
+                                       utilsEvents.off(element, "drag dragstart dragend dragcancel dragprepare", self, true);
+                                       utilsEvents.on(element, "pinchin pinchout", self);
+                                       element.classList.remove("ui-gridview-reorder");
+
+                                       // unlock AppBar if exists
+                                       if (page) {
+                                               appbarElement = page.querySelector(ns.widget.core.Appbar.selector);
+                                               if (appbarElement) {
+                                                       appbar = ns.widget.Appbar(appbarElement);
+                                                       appbar.lockExpanding(false);
+                                               }
+                                       }
+                               }
+
+                               options.reorder = reorder;
+                       };
+
+                       /**
+                        * Set style for grid view
+                        * @method _setGridStyle
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._setGridStyle = function () {
+                               var self = this,
+                                       listElements = self._ui.listElements,
+                                       length = listElements.length,
+                                       options = self.options,
+                                       cols = options.cols,
+                                       rows,
+                                       styleElement,
+                                       styles = [],
+                                       index = 0,
+                                       row,
+                                       col;
+
+                               styleElement = document.createElement("style");
+                               styleElement.type = "text/css";
+
+                               rows = Math.ceil(length / cols);
+
+                               for (row = 0; row < rows; row++) {
+                                       for (col = 0; col < cols && index < length; col++) {
+                                               listElements[index].style.animation = "grid_show_item cubic-bezier(0.25, 0.46, 0.45, 1.00) 350ms " + (17 * index) + "ms";
+                                               styles.push(self._getTransformStyle(col, row, ++index));
+                                       }
+                               }
+                               styleElement.textContent = styles.join("\n");
+                               styleElement.id = "GridView";
+                               document.head.appendChild(styleElement);
+                               self._styleElement = styleElement;
+                       };
+
+                       /**
+                        * Set number of cols
+                        * @method _setCols
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._setCols = function (element, value) {
+                               var self = this,
+                                       options = self.options;
+
+                               if (value === "auto") {
+                                       options.cols = 0;
+                               } else {
+                                       options.cols = parseInt(value, 10);
+                               }
+
+                               return true;
+                       };
+
+                       /**
+                        * Set number of cols
+                        * @method _getCols
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._getCols = function () {
+                               var self = this,
+                                       options = self.options;
+
+                               if (options.cols === 0) {
+                                       return "auto";
+                               }
+
+                               return options.cols;
+                       };
+
+                       /**
+                        * Define transform style for positioning of grid items
+                        * @method _getTransformStyle
+                        * @protected
+                        * @param {number} col
+                        * @param {number} row
+                        * @param {number} index
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._getTransformStyle = function (col, row, index) {
+                               var size = this._itemSize + this._borderSize,
+                                       x = col * size + "px",
+                                       y = row * (this._itemHeight) + Math.max(row - 1, 0) * this._borderSize + "px",
+                                       transform,
+                                       style;
+
+                               transform = "{ -webkit-transform: translate3d(" + x + ", " + y + ", 0); transform: translate3d(" + x + ", " + y + ", 0) }";
+                               style = STYLE_PATTERN.replace("{index}", index) + transform;
+
+                               return style;
+                       };
+
+                       /**
+                        * Remove style node
+                        * @method _removeGridStyle
+                        * @protected
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._removeGridStyle = function () {
+                               var styleElement = this._styleElement;
+
+                               if (styleElement) {
+                                       styleElement.parentNode.removeChild(styleElement);
+                                       this._styleElement = null;
+                               }
+                       };
+
+                       /**
+                        * Add an item to grid view
+                        * @method addItem
+                        * @public
+                        * @param {HTMLElement} item
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype.addItem = function (item) {
+                               var self = this,
+                                       listElements = self._ui.listElements,
+                                       styleElement = self._styleElement,
+                                       styles = styleElement.textContent,
+                                       element = self.element,
+                                       cols = self.options.cols,
+                                       col,
+                                       row,
+                                       length,
+                                       firstLiComputed = listElements.length && window.getComputedStyle(listElements[0], null);
+
+                               // append item
+                               item.classList.add(classes.ITEM);
+                               item.style.width = (parseFloat(firstLiComputed.getPropertyValue("width")) || 0) + "px";
+                               element.appendChild(item);
+                               listElements.push(item);
+
+                               // calculate item position
+                               length = listElements.length;
+                               row = Math.floor((length - 1) / cols);
+                               col = (length - 1) % cols;
+
+                               // add transform style for item added
+                               styleElement.textContent = styles.concat("\n" + self._getTransformStyle(col, row, length));
+                       };
+
+                       /**
+                        * Remove an item from grid view
+                        * @method removeItem
+                        * @public
+                        * @param {HTMLElement} item
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype.removeItem = function (item) {
+                               var self = this,
+                                       element = self.element,
+                                       listElements = self._ui.listElements,
+                                       styleElement = self._styleElement,
+                                       styles = styleElement.textContent.split("\n"),
+                                       index;
+
+                               index = listElements.indexOf(item);
+
+                               if (index > -1) {
+                                       listElements.splice(index, 1);
+                                       element.removeChild(item);
+                                       styles.pop();
+                                       styleElement.textContent = styles.join("\n");
+                               }
+                       };
+
+                       /**
+                        * Set label type for grid view
+                        * @method _setLabel
+                        * @protected
+                        * @param {HTMLElement} element
+                        * @param {string} label
+                        * @member ns.widget.mobile.GridView
+                        */
+                       prototype._setLabel = function (element, label) {
+                               var self = this,
+                                       options = self.options,
+                                       labelCheck;
+
+                               labelCheck = label || options.label;
+
+                               element.classList.remove(classes.LABEL_IN);
+                               element.classList.remove(classes.LABEL_OUT);
+
+                               if (labelCheck === labels.IN) {
+                                       element.classList.add(classes.LABEL_IN);
+                               } else if (labelCheck === labels.OUT) {
+                                       element.classList.add(classes.LABEL_OUT);
+                               }
+
+                               options.label = labelCheck;
+                       };
+
+                       BaseKeyboardSupport.registerActiveSelector("." + classes.GRIDLIST + " li." + classes.ITEM);
+
+                       ns.widget.mobile.GridView = GridView;
+
+                       engine.defineWidget(
+                               "GridView",
+                               "ul.ui-gridview, ul[data-role='gridview']",
+                               [],
+                               GridView,
+                               "mobile"
+                       );
+                       }(window.document, ns));
+
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*global window, ns, define, ns */
+/**
+ * @class tau.expose
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function (document) {
+       "use strict";
+       
+                       document.addEventListener("beforerouterinit", function () {
+                               if (ns.autoInitializePage !== undefined) {
+                                       ns.setConfig("autoInitializePage", ns.autoInitializePage);
+                               }
+                       }, false);
+
+                       document.addEventListener("routerinit", function (evt) {
+                               var router = evt.detail,
+                                       utilObject = ns.util.object,
+                                       routePage = router.getRoute("page"),
+                                       routePopup = router.getRoute("popup"),
+                                       history = ns.history,
+                                       back = history.back.bind(router),
+                                       classes = ns.widget.core.Page.classes,
+                                       pageActiveClass = classes.uiPageActive;
+                               /**
+                                * @method changePage
+                                * @inheritdoc ns.router.Router#open
+                                * @member tau
+                                */
+
+                               ns.changePage = router.open.bind(router);
+                               document.addEventListener("pageshow", function () {
+                                       /**
+                                        * Current active page
+                                        * @property {HTMLElement} activePage
+                                        * @member tau
+                                        */
+                                       ns.activePage = document.querySelector("." + pageActiveClass);
+                               });
+                               /**
+                                * First page element
+                                * @inheritdoc ns.router.Router#firstPage
+                                * @property {HTMLElement} firstPage
+                                * @member tau
+                                */
+                               ns.firstPage = routePage.getFirstElement();
+                               /**
+                                * Returns active page element
+                                * @inheritdoc ns.router.Router#getActivePageElement
+                                * @method getActivePage
+                                * @member tau
+                                */
+                               ns.getActivePage = routePage.getActiveElement.bind(routePage);
+                               /**
+                                * @inheritdoc ns.router.history#back
+                                * @method back
+                                * @member tau
+                                */
+                               ns.back = back;
+                               /**
+                                * @inheritdoc ns.router.Router#init
+                                * @method initializePage
+                                * @member tau
+                                */
+                               ns.initializePage = router.init.bind(router);
+                               /**
+                                * Page Container widget
+                                * @property {HTMLElement} pageContainer
+                                * @inheritdoc ns.router.Router#container
+                                * @member tau
+                                */
+                               ns.pageContainer = router.container;
+                               /**
+                                * @method openPopup
+                                * @inheritdoc ns.router.Router#openPopup
+                                * @member tau
+                                */
+                               ns.openPopup = function (to, options) {
+                                       var htmlElementTo;
+
+                                       if (to && to.length !== undefined && typeof to === "object") {
+                                               htmlElementTo = to[0];
+                                       } else {
+                                               htmlElementTo = to;
+                                       }
+                                       options = utilObject.merge({}, options, {rel: "popup"});
+                                       router.open(htmlElementTo, options);
+                               };
+                               /**
+                                * @method closePopup
+                                * @inheritdoc ns.router.Router#closePopup
+                                * @member tau
+                                */
+                               ns.closePopup = routePopup.close.bind(routePopup, null);
+
+                       }, false);
+
+                       }(window.document));
+
+/*global window, ns, define, ns */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Route Page
+ * Support class for router to control changing pages.
+ * @class ns.router.route.page
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function (document) {
+       "use strict";
+                               var util = ns.util,
+                               path = util.path,
+                               DOM = util.DOM,
+                               object = util.object,
+                               utilSelector = util.selectors,
+                               history = ns.history,
+                               engine = ns.engine,
+                               baseElement,
+                               routePage = {},
+                               head;
+
+                       /**
+                        * Tries to find a page element matching id and filter (selector).
+                        * Adds data url attribute to found page, sets page = null when nothing found
+                        * @method findPageAndSetDataUrl
+                        * @param {string} dataUrl DataUrl of searching element
+                        * @param {string} filter Query selector for searching page
+                        * @return {?HTMLElement}
+                        * @private
+                        * @static
+                        * @member ns.router.route.page
+                        */
+                       function findPageAndSetDataUrl(dataUrl, filter) {
+                               var id = path.stripQueryParams(dataUrl).replace("#", ""),
+                                       page = document.getElementById(id);
+
+                               if (page && utilSelector.matchesSelector(page, filter)) {
+                                       if (dataUrl === id) {
+                                               DOM.setNSData(page, "url", "#" + id);
+                                       } else {
+                                               DOM.setNSData(page, "url", dataUrl);
+                                       }
+
+                               } else {
+                                       // if we matched any element, but it doesn't match our filter
+                                       // reset page to null
+                                       page = null;
+                               }
+                               return page;
+                       }
+
+                       routePage.orderNumber = 1;
+                       /**
+                        * Property containing default properties
+                        * @property {Object} defaults
+                        * @property {string} defaults.transition="none"
+                        * @static
+                        * @member ns.router.route.page
+                        */
+                       routePage.defaults = {
+                               transition: "none"
+                       };
+
+                       /**
+                        * Property defining selector without spaces for filtering only page elements.
+                        * @property {string} filter
+                        * @member ns.router.route.page
+                        * @static
+                        */
+                       routePage.filter = engine.getWidgetDefinition("Page").selector.replace(/(\s*)/g, "");
+
+                       /**
+                        * Property contains first page element
+                        * @property {?HTMLElement} firstPage
+                        * @member ns.router.route.page
+                        * @static
+                        */
+                       routePage.firstPage = null;
+
+                       /**
+                        * Property contains href of original Base element if exists
+                        * @property {string} _originalBaseHref
+                        * @member ns.router.route.page
+                        * @static
+                        */
+                       routePage._originalBaseHref = "";
+
+                       /**
+                        * Property contains start URI
+                        * @property {string} _originalLocation
+                        * @member ns.router.route.page
+                        * @static
+                        */
+                       routePage._originalLocationHref = "";
+
+                       /**
+                        * Returns default route options used inside Router.
+                        * @method option
+                        * @static
+                        * @member ns.router.route.page
+                        * @return {Object} default route options
+                        */
+                       routePage.option = function () {
+                               var defaults = object.merge({}, routePage.defaults);
+
+                               defaults.transition = ns.getConfig("pageTransition", defaults.transition);
+                               return defaults;
+                       };
+
+                       routePage.init = function () {
+                               var pages = [].slice.call(document.querySelectorAll(this.filter));
+
+                               pages.forEach(function (page) {
+                                       if (!DOM.getNSData(page, "url")) {
+                                               DOM.setNSData(page, "url",
+                                                       (page.id && "#" + page.id) || location.pathname + location.search);
+                                       }
+                               });
+                       };
+
+                       /**
+                        * This method changes page. It sets history and opens page passed as a parameter.
+                        * @method open
+                        * @param {HTMLElement|string} toPage The page which will be opened.
+                        * @param {Object} [options]
+                        * @param {boolean} [options.fromHashChange] Sets if call was made on hash change.
+                        * @param {string} [options.dataUrl] Sets if page has url attribute.
+                        * @member ns.router.route.page
+                        */
+                       routePage.open = function (toPage, options) {
+                               var pageTitle = document.title,
+                                       url,
+                                       state;
+
+                               if (toPage === this.getFirstElement() && !options.dataUrl) {
+                                       url = path.documentUrl.hrefNoHash;
+                               } else {
+                                       url = DOM.getNSData(toPage, "url");
+                               }
+
+                               // if no url is set, apply the address of chosen page to data-url attribute
+                               // and use it as url, as this is needed for history state
+                               if (!url && options.href) {
+                                       url = options.href;
+                                       DOM.setNSData(toPage, "url", url);
+                               }
+
+                               pageTitle = DOM.getNSData(toPage, "title") ||
+                                       utilSelector.getChildrenBySelector(toPage, ".ui-header > .ui-title").textContent ||
+                                       pageTitle;
+                               if (!DOM.getNSData(toPage, "title")) {
+                                       DOM.setNSData(toPage, "title", pageTitle);
+                               }
+
+                               if (url && !options.fromHashChange) {
+                                       if (!path.isPath(url) && url.indexOf("#") < 0) {
+                                               url = path.makeUrlAbsolute("#" + url, path.documentUrl.hrefNoHash);
+                                       }
+
+                                       state = object.merge(
+                                               {},
+                                               options,
+                                               {
+                                                       url: url
+                                               }
+                                       );
+
+                                       if (options.volatileRecord) {
+                                               history.enableVolatileMode();
+                                       }
+                                       history.replace(state, pageTitle, url);
+
+                                       history.disableVolatileMode();
+                               }
+
+                               // write base element
+                               this._setBase(url);
+
+                               //set page title
+                               document.title = pageTitle;
+                               this.active = true;
+                               this.getContainer().change(toPage, options);
+
+                       };
+
+                       /**
+                        * This method determines target page to open.
+                        * @method find
+                        * @param {string} absUrl Absolute path to opened page
+                        * @member ns.router.route.page
+                        * @return {?HTMLElement} Element of page to open.
+                        */
+                       routePage.find = function (absUrl) {
+                               var self = this,
+                                       router = ns.router.Router.getInstance(),
+                                       dataUrl = self._createDataUrl(absUrl),
+                                       initialContent = self.getFirstElement(),
+                                       pageContainer = router.getContainer(),
+                                       page,
+                                       selector = "[data-url='" + dataUrl + "']",
+                                       filterRegexp = /,/gm;
+
+                               if (/#/.test(absUrl) && path.isPath(dataUrl)) {
+                                       return null;
+                               }
+
+                               // Check to see if the page already exists in the DOM.
+                               // NOTE do _not_ use the :jqmData pseudo selector because parenthesis
+                               //      are a valid url char and it breaks on the first occurrence
+                               // prepare selector for new page
+                               selector += self.filter.replace(filterRegexp, ",[data-url='" + dataUrl + "']");
+                               page = pageContainer.element.querySelector(selector);
+
+                               // If we failed to find the page, check to see if the url is a
+                               // reference to an embedded page. If so, it may have been dynamically
+                               // injected by a developer, in which case it would be lacking a
+                               // data-url attribute and in need of enhancement.
+                               if (!page && dataUrl && !path.isPath(dataUrl)) {
+                                       //Remove search data
+                                       page = findPageAndSetDataUrl(dataUrl, self.filter);
+                               }
+
+                               // If we failed to find a page in the DOM, check the URL to see if it
+                               // refers to the first page in the application. Also check to make sure
+                               // our cached-first-page is actually in the DOM. Some user deployed
+                               // apps are pruning the first page from the DOM for various reasons.
+                               // We check for this case here because we don't want a first-page with
+                               // an id falling through to the non-existent embedded page error case.
+                               if (!page &&
+                                       path.isFirstPageUrl(dataUrl, self.getFirstElement()) &&
+                                       initialContent) {
+                                       page = initialContent;
+                               }
+
+                               return page;
+                       };
+
+                       /**
+                        * This method parses HTML and runs scripts from parsed code.
+                        * Fetched external scripts if required.
+                        * Sets document base to parsed document absolute path.
+                        * @method parse
+                        * @param {string} html HTML code to parse
+                        * @param {string} absUrl Absolute url for parsed page
+                        * @member ns.router.route.page
+                        * @return {?HTMLElement} Element of page in parsed document.
+                        */
+                       routePage.parse = function (html, absUrl) {
+                               var self = this,
+                                       page,
+                                       dataUrl = self._createDataUrl(absUrl);
+
+                               // write base element
+                               self._setBase(absUrl);
+
+                               // Finding matching page inside created element
+                               page = html.querySelector(self.filter);
+
+                               // If a page exists...
+                               if (page) {
+                                       DOM.setNSData(page, "url", dataUrl);
+                                       DOM.setNSData(page, "external", true);
+                               }
+                               return page;
+                       };
+
+                       /**
+                        * This method handles hash change, **currently does nothing**.
+                        * @method onHashChange
+                        * @static
+                        * @member ns.router.route.page
+                        * @return {null}
+                        */
+                       routePage.onHashChange = function (/* url, options */) {
+                               return null;
+                       };
+
+                       /**
+                        * This method creates data url from absolute url given as argument.
+                        * @method _createDataUrl
+                        * @param {string} absoluteUrl
+                        * @protected
+                        * @static
+                        * @member ns.router.route.page
+                        * @return {string}
+                        */
+                       routePage._createDataUrl = function (absoluteUrl) {
+                               return path.convertUrlToDataUrl(absoluteUrl, true);
+                       };
+
+                       /**
+                        * On open fail, currently never used
+                        * @method onOpenFailed
+                        * @member ns.router.route.page
+                        */
+                       routePage.onOpenFailed = function (/* options */) {
+                               this._setBase(path.parseLocation().hrefNoSearch);
+                       };
+
+                       /**
+                        * This method returns base element from document head.
+                        * If no base element is found, one is created based on current location.
+                        * @method _getBaseElement
+                        * @protected
+                        * @static
+                        * @member ns.router.route.page
+                        * @return {HTMLElement}
+                        */
+                       routePage._getBaseElement = function () {
+                               // Fetch document head if never cached before
+                               if (!head) {
+                                       head = document.querySelector("head");
+                               }
+                               // Find base element
+                               if (!baseElement) {
+                                       baseElement = document.querySelector("base");
+                                       if (baseElement) {
+                                               this._originalBaseHref = baseElement.href;
+                                               this._originalLocationHref = path.documentUrl.hrefNoHash;
+                                       } else {
+                                               baseElement = document.createElement("base");
+                                               baseElement.href = path.documentBase.hrefNoHash;
+                                               head.appendChild(baseElement);
+                                       }
+                               }
+                               return baseElement;
+                       };
+
+                       /**
+                        * Sets document base to url given as argument
+                        * @method _setBase
+                        * @param {string} url
+                        * @protected
+                        * @member ns.router.route.page
+                        */
+                       routePage._setBase = function (url) {
+                               var base = this._getBaseElement(),
+                                       baseHref = base.href,
+                                       rel = "";
+
+                               if (this._originalBaseHref) { // update url refering to exists base
+                                       if (this._originalLocationHref !== path.parseUrl(url).hrefNoSearch) {
+                                               rel = path.parseUrl(url).hrefNoSearch.replace(this._originalLocationHref, "");
+                                               path.documentBase = path.parseUrl(path.makeUrlAbsolute(rel, path.documentBase.href));
+                                       } else {
+                                               url = this._originalBaseHref;
+                                       }
+                               }
+                               if (path.isPath(url)) { // set base
+                                       url = path.makeUrlAbsolute(url, path.documentBase);
+                                       if (path.parseUrl(baseHref).hrefNoSearch !== path.parseUrl(url).hrefNoSearch) {
+                                               base.href = url;
+                                               path.documentBase = path.parseUrl(path.makeUrlAbsolute(url, path.documentUrl.href));
+                                       }
+                               }
+                       };
+
+                       /**
+                        * Returns container of pages
+                        * @method getContainer
+                        * @return {?ns.widget.core.Page}
+                        * @member ns.router.route.page
+                        * @static
+                        */
+                       routePage.getContainer = function () {
+                               return ns.router.Router.getInstance().getContainer();
+                       };
+
+                       /**
+                        * Returns active page.
+                        * @method getActive
+                        * @return {?ns.widget.core.Page}
+                        * @member ns.router.route.page
+                        * @static
+                        */
+                       routePage.getActive = function () {
+                               return this.getContainer().getActivePage();
+                       };
+
+                       /**
+                        * Returns element of active page.
+                        * @method getActiveElement
+                        * @return {HTMLElement}
+                        * @member ns.router.route.page
+                        * @static
+                        */
+                       routePage.getActiveElement = function () {
+                               return this.getActive().element;
+                       };
+
+                       /**
+                        * Method returns ths first page.
+                        * @method getFirstElement
+                        * @return {HTMLElement} the first page
+                        * @member ns.router.route.page
+                        */
+                       routePage.getFirstElement = function () {
+                               return this.firstPage;
+                       };
+
+                       /**
+                        * Method sets ths first page.
+                        * @method setFirstElement
+                        * @param {HTMLElement} firstPage the first page
+                        * @member ns.router.route.page
+                        */
+                       routePage.setFirstElement = function (firstPage) {
+                               this.firstPage = firstPage;
+                       };
+
+                       ns.router.route.page = routePage;
+
+                       }(window.document));
+
+/*global ns, define, ns */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Route Main Tab
+ * Support class for router to control changing pages.
+ * @class ns.router.route.mainTab
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function () {
+       "use strict";
+                               var routeMainTab,
+                               object = ns.util.object,
+                               defaults = {
+                                       volatileRecord: true,
+                                       orderNumber: 2
+                               },
+                               pageRule = ns.router.route.page,
+                               prototype = pageRule,
+                               _option = pageRule.option,
+                               MainTabRoute = function () {
+                               };
+
+                       MainTabRoute.prototype = prototype;
+
+                       routeMainTab = new MainTabRoute();
+
+                       routeMainTab.option = function () {
+                               return object.merge({}, _option.call(pageRule), defaults);
+                       };
+                       ns.router.route.maintab = routeMainTab;
+
+                       }());
+
+/*global window, define, ns */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Route Popup
+ * Support class for router to control changing popups.
+ * @class ns.router.route.popup
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Damian Osipiuk <d.osipiuk@samsung.com>
+ */
+(function (window, document, ns) {
+       "use strict";
+                               var
+                               /**
+                                * @property {Object} Popup Alias for {@link ns.widget.Popup}
+                                * @member ns.router.route.popup
+                                * @private
+                                * @static
+                                */
+                               Popup = ns.widget.core.Popup,
+                               util = ns.util,
+                               routePopup = {
+                                       /**
+                                        * Object with default options
+                                        * @property {Object} defaults
+                                        * @property {string} [defaults.transition='none'] Sets the animation used during change
+                                        * of popup.
+                                        * @property {?HTMLElement} [defaults.container=null] Sets container of element.
+                                        * @property {boolean} [defaults.volatileRecord=true] Sets if the current history entry
+                                        * will be modified or a new one will be created.
+                                        * @member ns.router.route.popup
+                                        * @static
+                                        */
+                                       defaults: {
+                                               transition: "none",
+                                               container: null,
+                                               volatileRecord: true
+                                       },
+                                       /**
+                                        * Popup Element Selector
+                                        * @property {string} filter
+                                        * @member ns.router.route.popup
+                                        * @static
+                                        */
+                                       filter: "." + Popup.classes.popup,
+                                       /**
+                                        * Storage variable for active popup
+                                        * @property {?HTMLElement} activePopup
+                                        * @member ns.router.route.popup
+                                        * @static
+                                        */
+                                       activePopup: null,
+                                       /**
+                                        * Dictionary for popup related event types
+                                        * @property {Object} events
+                                        * @property {string} [events.POPUP_HIDE='popuphide']
+                                        * @member ns.router.route.popup
+                                        * @static
+                                        */
+                                       events: {
+                                               POPUP_HIDE: "popuphide"
+                                       },
+
+                                       /**
+                                        * Alias for {@link ns.util.path}
+                                        * @property {Object} path
+                                        * @member ns.router.route.popup
+                                        * @protected
+                                        * @static
+                                        */
+                                       _path: ns.util.path,
+                                       /**
+                                        * Alias for {@link ns.router.history}
+                                        * @property {Object} history
+                                        * @member ns.router.route.popup
+                                        * @protected
+                                        * @static
+                                        */
+                                       _history: ns.history
+                               },
+                               /**
+                                * Alias for {@link ns.engine}
+                                * @property {Object} engine
+                                * @member ns.router.route.popup
+                                * @private
+                                * @static
+                                */
+                               engine = ns.engine,
+                               /**
+                                * Alias for {@link ns.util.selectors}
+                                * @property {Object} utilSelector
+                                * @member ns.router.route.popup
+                                * @private
+                                * @static
+                                */
+                               utilSelector = ns.util.selectors,
+                               /**
+                                * Alias for {@link ns.util.DOM}
+                                * @property {Object} DOM
+                                * @member ns.router.route.popup
+                                * @private
+                                * @static
+                                */
+                               DOM = ns.util.DOM,
+                               /**
+                                * Alias for Object utils
+                                * @method slice
+                                * @member ns.router.route.popup
+                                * @private
+                                * @static
+                                */
+                               object = ns.util.object,
+                               /**
+                                * Popup's hash added to url
+                                * @property {string} popupHashKey
+                                * @member ns.router.route.popup
+                                * @private
+                                * @static
+                                */
+                               popupHashKey = "popup=true",
+                               /**
+                                * Regexp for popup's hash
+                                * @property {RegExp} popupHashKeyReg
+                                * @member ns.router.route.popup
+                                * @private
+                                * @static
+                                */
+                               popupHashKeyReg = /([&|\?]popup=true)/;
+
+                       /**
+                        * Tries to find a popup element matching id and filter (selector).
+                        * Adds data url attribute to found page, sets page = null when nothing found.
+                        * @method findPopupAndSetDataUrl
+                        * @param {string} id
+                        * @param {string} filter
+                        * @return {HTMLElement}
+                        * @member ns.router.route.popup
+                        * @private
+                        * @static
+                        */
+                       function findPopupAndSetDataUrl(id, filter) {
+                               var popup,
+                                       hashReg = /^#/;
+
+                               id = id.replace(hashReg, "");
+                               popup = document.getElementById(id);
+
+                               if (popup && utilSelector.matchesSelector(popup, filter)) {
+                                       DOM.setNSData(popup, "url", "#" + id);
+                               } else {
+                                       // if we matched any element, but it doesn't match our filter
+                                       // reset page to null
+                                       popup = null;
+                               }
+                               // probably there is a need for running onHashChange while going back to a history entry
+                               // without state, eg. manually entered #fragment. This may not be a problem on target device
+                               return popup;
+                       }
+
+                       routePopup.orderNumber = 100;
+                       /**
+                        * This method returns default options for popup router.
+                        * @method option
+                        * @return {Object}
+                        * @member ns.router.route.popup
+                        * @static
+                        */
+                       routePopup.option = function () {
+                               var defaults = object.merge({}, routePopup.defaults);
+
+                               defaults.transition = ns.getConfig("popupTransition", defaults.transition);
+                               return defaults;
+                       };
+
+                       /**
+                        * This method sets active popup and manages history.
+                        * @method setActive
+                        * @param {?ns.widget.core.popup} activePopup
+                        * @param {Object} options
+                        * @member ns.router.route.popup
+                        * @static
+                        */
+                       routePopup.setActive = function (activePopup, options) {
+                               var url,
+                                       pathLocation = routePopup._path.getLocation(),
+                                       documentUrl = pathLocation.replace(popupHashKeyReg, "");
+
+                               this.activePopup = activePopup;
+
+                               if (activePopup) {
+                                       // If popup is being opened, the new state is added to history.
+                                       if (options && !options.fromHashChange && options.history) {
+                                               url = routePopup._path.addHashSearchParams(documentUrl, popupHashKey);
+                                               routePopup._history.replace(options, "", url);
+                                               this.active = true;
+                                       }
+                               } else if (pathLocation !== documentUrl) {
+                                       // If popup is being closed, the history.back() is called
+                                       // but only if url has special hash.
+                                       // Url is changed after opening animation and in some cases,
+                                       // the popup is closed before this animation and then the history.back
+                                       // could cause undesirable change of page.
+                                       this.active = false;
+                                       routePopup._history.back();
+                               }
+                       };
+
+                       /**
+                        * This method opens popup if no other popup is opened.
+                        * It also changes history to show that popup is opened.
+                        * If there is already active popup, it will be closed.
+                        * @method open
+                        * @param {HTMLElement|string} toPopup
+                        * @param {Object} options
+                        * @param {"page"|"popup"|"external"} [options.rel = 'popup'] Represents kind of link as
+                        * 'page' or 'popup' or 'external' for linking to another domain.
+                        * @param {string} [options.transition = 'none'] Sets the animation used during change of
+                        * popup.
+                        * @param {boolean} [options.reverse = false] Sets the direction of change.
+                        * @param {boolean} [options.fromHashChange = false] Sets if will be changed after hashchange.
+                        * @param {boolean} [options.showLoadMsg = true] Sets if message will be shown during loading.
+                        * @param {number} [options.loadMsgDelay = 0] Sets delay time for the show message during
+                        * loading.
+                        * @param {boolean} [options.dataUrl] Sets if page has url attribute.
+                        * @param {string} [options.container = null] Selector for container.
+                        * @param {boolean} [options.volatileRecord=true] Sets if the current history entry will be
+                        * modified or a new one will be created.
+                        * @param {Event} event
+                        * @member ns.router.route.popup
+                        * @static
+                        */
+                       routePopup.open = function (toPopup, options, event) {
+                               var self = this,
+                                       popup,
+                                       router = ns.router.Router.getInstance(),
+                                       events = self.events,
+                                       removePopup = function () {
+                                               document.removeEventListener(events.POPUP_HIDE, removePopup, false);
+                                               toPopup.parentNode.removeChild(toPopup);
+                                               self.activePopup = null;
+                                       },
+                                       openPopup = function () {
+                                               var positionTo = options["position-to"],
+                                                       touch;
+                                               // add such option only if it exists
+
+                                               if (positionTo) {
+                                                       options.positionTo = positionTo;
+                                               }
+                                               if (event) {
+                                                       touch = event.touches ? event.touches[0] : event;
+                                                       options.x = touch.clientX;
+                                                       options.y = touch.clientY;
+                                               }
+
+                                               document.removeEventListener(events.POPUP_HIDE, openPopup, false);
+                                               popup = engine.instanceWidget(toPopup, "Popup", options);
+                                               popup.open(options);
+                                               self.activePopup = popup;
+                                               self.active = popup.options.history;
+                                       },
+                                       activePage = router.container.getActivePage(),
+                                       container;
+
+                               if (DOM.getNSData(toPopup, "external") === true) {
+                                       container = options.container ?
+                                               activePage.element.querySelector(options.container) : activePage.element;
+                                       if (toPopup.parentNode !== container) {
+                                               toPopup = util.importEvaluateAndAppendElement(toPopup, container);
+                                       }
+                                       document.addEventListener(routePopup.events.POPUP_HIDE, removePopup, false);
+                               }
+
+                               if (self.hasActive()) {
+                                       document.addEventListener(events.POPUP_HIDE, openPopup, false);
+                                       if (!self.close()) {
+                                               openPopup();
+                                       }
+                               } else {
+                                       openPopup();
+                               }
+                       };
+
+                       /**
+                        * This method closes active popup.
+                        * @method close
+                        * @param {ns.widget.core.Popup} [activePopup]
+                        * @param {Object} options
+                        * @param {string} [options.transition]
+                        * @param {string} [options.ext= in ui-pre-in] options.ext
+                        * @member ns.router.route.popup
+                        * @protected
+                        * @static
+                        */
+                       routePopup.close = function (activePopup, options) {
+                               var popupOptions,
+                                       pathLocation = routePopup._path.getLocation(),
+                                       documentUrl = pathLocation.replace(popupHashKeyReg, "");
+
+                               options = options || {};
+
+                               if (activePopup && !(activePopup instanceof Popup)) {
+                                       activePopup = engine.instanceWidget(activePopup, "Popup", options);
+                               }
+                               activePopup = activePopup || this.activePopup;
+
+                               // if popup is active
+                               if (activePopup) {
+                                       popupOptions = activePopup.options;
+                                       // we check if it changed the history
+                                       if (popupOptions.history && pathLocation !== documentUrl) {
+                                               // and then set new options for popup
+                                               popupOptions.transition = options.transition || popupOptions.transition;
+                                               popupOptions.ext = options.ext || popupOptions.ext;
+                                               // unlock the router if it was locked
+                                               if (!popupOptions.dismissible) {
+                                                       ns.router.Router.getInstance().unlock();
+                                               }
+                                               // and call history.back()
+                                               routePopup._history.back();
+                                       } else {
+                                               // if popup did not change the history, we close it normally
+                                               activePopup.close(options);
+                                       }
+                                       return true;
+                               }
+                               return false;
+                       };
+
+                       /**
+                        * This method handles hash change.
+                        * It closes opened popup.
+                        * @method onHashChange
+                        * @param {string} url
+                        * @param {Object} options
+                        * @return {boolean}
+                        * @member ns.router.route.popup
+                        * @static
+                        */
+                       routePopup.onHashChange = function (url, options) {
+                               var activePopup = this.activePopup;
+
+                               if (activePopup) {
+                                       activePopup.close(options);
+                                       // Default routing setting cause to rewrite further window history
+                                       // even if popup has been closed
+                                       // To prevent this onHashChange after closing popup we need to change
+                                       // disable volatile mode to allow pushing new history elements
+                                       if (this.active) {
+                                               this.active = false;
+                                               return true;
+                                       }
+                               }
+                               return false;
+                       };
+
+                       /**
+                        * On open fail, currently never used
+                        * @method onOpenFailed
+                        * @member ns.router.route.popup
+                        * @return {null}
+                        * @static
+                        */
+                       routePopup.onOpenFailed = function (/* options */) {
+                               return null;
+                       };
+
+                       /**
+                        * This method finds popup by data-url.
+                        * @method find
+                        * @param {string} absUrl Absolute path to opened popup
+                        * @return {HTMLElement} Element of popup
+                        * @member ns.router.route.popup
+                        */
+                       routePopup.find = function (absUrl) {
+                               var self = this,
+                                       dataUrl = self._createDataUrl(absUrl),
+                                       activePage = ns.router.Router.getInstance().getContainer().getActivePage(),
+                                       popup;
+
+                               popup = activePage.element.querySelector("[data-url='" + dataUrl + "']" + self.filter);
+
+                               if (!popup && dataUrl && !routePopup._path.isPath(dataUrl)) {
+                                       popup = findPopupAndSetDataUrl(dataUrl, self.filter);
+                               }
+
+                               return popup;
+                       };
+
+                       /**
+                        * This method parses HTML and runs scripts from parsed code.
+                        * Fetched external scripts if required.
+                        * @method parse
+                        * @param {string} html HTML code to parse
+                        * @param {string} absUrl Absolute url for parsed popup
+                        * @return {HTMLElement}
+                        * @member ns.router.route.popup
+                        */
+                       routePopup.parse = function (html, absUrl) {
+                               var self = this,
+                                       popup,
+                                       dataUrl = self._createDataUrl(absUrl);
+
+                               popup = html.querySelector(self.filter);
+
+                               if (popup) {
+                                       // TODO tagging a popup with external to make sure that embedded popups aren't
+                                       // removed by the various popup handling code is bad. Having popup handling code
+                                       // in many places is bad. Solutions post 1.0
+                                       DOM.setNSData(popup, "url", dataUrl);
+                                       DOM.setNSData(popup, "external", true);
+                               }
+
+                               return popup;
+                       };
+
+                       /**
+                        * Convert url to data-url
+                        * @method _createDataUrl
+                        * @param {string} absoluteUrl
+                        * @return {string}
+                        * @member ns.router.route.popup
+                        * @protected
+                        * @static
+                        */
+                       routePopup._createDataUrl = function (absoluteUrl) {
+                               return routePopup._path.convertUrlToDataUrl(absoluteUrl);
+                       };
+
+                       /**
+                        * Return true if active popup exists.
+                        * @method hasActive
+                        * @return {boolean}
+                        * @member ns.router.route.popup
+                        * @static
+                        */
+                       routePopup.hasActive = function () {
+                               return this.active;
+                       };
+
+                       /**
+                        * Returns active popup.
+                        * @method getActive
+                        * @return {?ns.widget.core.Popup}
+                        * @member ns.router.route.popup
+                        * @static
+                        */
+                       routePopup.getActive = function () {
+                               return this.activePopup;
+                       };
+
+                       /**
+                        * Returns element of active popup.
+                        * @method getActiveElement
+                        * @return {HTMLElement}
+                        * @member ns.router.route.popup
+                        * @static
+                        */
+                       routePopup.getActiveElement = function () {
+                               var active = this.getActive();
+
+                               return active && active.element;
+                       };
+
+                       ns.router.route.popup = routePopup;
+
+                       }(window, window.document, ns));
+
+/*global window, ns, define */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Route Drawer
+ * Support class for router to control drawer widget in profile Wearable.
+ * @class ns.router.route.drawer
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ */
+(function () {
+       "use strict";
+                               var CoreDrawer = ns.widget.core.Drawer,
+                               Router = ns.router.Router,
+                               path = ns.util.path,
+                               history = ns.history,
+                               engine = ns.engine,
+                               routeDrawer = {},
+                               drawerHashKey = "drawer=true",
+                               drawerHashKeyReg = /([&|\?]drawer=true)/;
+
+                       routeDrawer.orderNumber = 1000;
+                       /**
+                        * Property containing default properties
+                        * @property {Object} defaults
+                        * @property {string} defaults.transition="none"
+                        * @static
+                        * @member ns.router.route.drawer
+                        */
+                       routeDrawer.defaults = {
+                               transition: "none"
+                       };
+
+                       /**
+                        * Property defining selector for filtering only drawer elements
+                        * @property {string} filter
+                        * @member ns.router.route.drawer
+                        * @static
+                        */
+                       routeDrawer.filter = "." + CoreDrawer.classes.drawer;
+
+
+                       /**
+                        * Returns default route options used inside Router.
+                        * But, drawer router has not options.
+                        * @method option
+                        * @static
+                        * @member ns.router.route.drawer
+                        * @return {null}
+                        */
+                       routeDrawer.option = function () {
+                               return null;
+                       };
+
+                       /**
+                        * This method opens the drawer.
+                        * @method open
+                        * @param {HTMLElement} drawerElement
+                        * @member ns.router.route.drawer
+                        */
+                       routeDrawer.open = function (drawerElement) {
+                               var drawer = engine.instanceWidget(drawerElement, "Drawer");
+
+                               drawer.open();
+                       };
+
+                       /**
+                        * This method determines target drawer to open.
+                        * @method find
+                        * @param {string} absUrl Absolute path to opened drawer widget
+                        * @member ns.router.route.drawer
+                        * @return {?HTMLElement} drawerElement
+                        */
+                       routeDrawer.find = function (absUrl) {
+                               var dataUrl = path.convertUrlToDataUrl(absUrl),
+                                       activePage = Router.getInstance().getContainer().getActivePage(),
+                                       drawer;
+
+                               drawer = activePage.element.querySelector("#" + dataUrl);
+
+                               return drawer;
+                       };
+
+                       /**
+                        * This method parses HTML and runs scripts from parsed code.
+                        * But, drawer router doesn't need to that.
+                        * @method parse
+                        * @member ns.router.route.drawer
+                        */
+                       routeDrawer.parse = function () {
+                               return null;
+                       };
+
+                       /**
+                        * This method sets active drawer and manages history.
+                        * @method setActive
+                        * @param {Object} activeDrawer
+                        * @member ns.router.route.drawer
+                        * @static
+                        */
+                       routeDrawer.setActive = function (activeDrawer) {
+                               var url,
+                                       pathLocation = path.getLocation(),
+                                       documentUrl = pathLocation.replace(drawerHashKeyReg, "");
+
+                               this._activeDrawer = activeDrawer;
+
+                               if (activeDrawer) {
+                                       url = path.addHashSearchParams(documentUrl, drawerHashKey);
+                                       history.replace({}, "", url);
+                                       this.active = true;
+                               } else if (pathLocation !== documentUrl) {
+                                       history.back();
+                               }
+                       };
+
+                       /**
+                        * This method handles hash change.
+                        * @method onHashChange
+                        * @param {string} url
+                        * @param {Object} options
+                        * @param {string} prev Previous url string
+                        * @static
+                        * @member ns.router.route.drawer
+                        * @return {null}
+                        */
+                       routeDrawer.onHashChange = function (url, options, prev) {
+                               var self = this,
+                                       activeDrawer = self._activeDrawer,
+                                       stateUrl = prev.stateUrl;
+
+                               if (activeDrawer && stateUrl.search(drawerHashKey) > 0 && url.search(drawerHashKey) < 0) {
+                                       activeDrawer.close(options);
+                                       this.active = false;
+                                       return true;
+                               }
+                               return false;
+                       };
+
+                       ns.router.route.drawer = routeDrawer;
+
+                       }());
+
+/*global ns, define, ns */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Route panel
+ * Support class for router to control panel widget in profile Wearable.
+ * @class ns.router.route.panel
+ * @author Hyeoncheol Choi <hc7.choi@samsung.com>
+ */
+(function (document, ns) {
+       "use strict";
+                               var panelChanger = ns.widget.core.PanelChanger,
+                               selectors = ns.util.selectors,
+                               cookie = ns.util.cookie,
+                               history = ns.history,
+                               engine = ns.engine,
+                               classes = {
+                                       PANEL_CHANGER: panelChanger.classes.PANEL_CHANGER
+                               },
+                               CONST = {
+                                       REVERSE: "slide-reverse"
+                               },
+                               routePanel = {};
+
+                       routePanel.orderNumber = 10;
+
+                       /**
+                        * Returns default route options used inside Router.
+                        * But, panel router has not options.
+                        * @method option
+                        * @static
+                        * @member ns.router.route.panel
+                        * @return {null}
+                        */
+                       routePanel.option = function () {
+                               return null;
+                       };
+
+                       /**
+                        * This method sets active panel and manages history.
+                        * @method setActive
+                        * @param {HTMLElement} element
+                        * @member ns.router.route.panel
+                        * @static
+                        */
+                       routePanel.setActive = function (element) {
+                               var self = this,
+                                       panelChangerElement = selectors.getClosestByClass(element, classes.PANEL_CHANGER),
+                                       panelChangerComponent = engine.instanceWidget(panelChangerElement, "PanelChanger");
+
+                               self.active = true;
+                               self._panelChangerElement = panelChangerElement;
+                               self._panelChangerComponent = panelChangerComponent;
+                       };
+
+                       /**
+                        * This method handles hash change.
+                        * @method onHashChange
+                        * @param {string} url
+                        * @param {Object} options
+                        * @param {string} prev
+                        * @static
+                        * @member ns.router.route.panel
+                        * @return {boolean}
+                        */
+                       routePanel.onHashChange = function (url, options, prev) {
+                               var self = this,
+                                       storageName = panelChanger.default.STORAGE_NAME,
+                                       panelHistory = JSON.parse(cookie.readFromCookie(storageName) || "[]"),
+                                       panelChangerComponent = self._panelChangerComponent,
+                                       activePanel = panelHistory[panelHistory.length - 1];
+
+                               if (!self.active || !panelChangerComponent) {
+                                       return false;
+                               }
+                               if (self._panelChangerElement.querySelector("#" + activePanel).classList.contains(panelChanger.classes.PRE_IN) ||
+                                               panelHistory.length === 0) {
+                                       history.replace(prev, prev.stateTitle, prev.stateUrl);
+                                       return true;
+                               }
+                               panelHistory.pop();
+                               if (panelChangerComponent.options.manageHistory && panelHistory.length > 0) {
+                                       history.replace(prev, prev.stateTitle, prev.stateUrl);
+                                       cookie.writeToCookie(storageName, JSON.stringify(panelHistory));
+                                       panelChangerComponent.changePanel("#" + panelHistory.pop(), CONST.REVERSE, "back");
+                                       return true;
+                               }
+                               self.active = false;
+                               return false;
+                       };
+
+                       /**
+                        * This method handles tauback event
+                        * @method tauback
+                        * @param {event} event
+                        */
+                       routePanel.tauback = function (event) {
+                               var self = this,
+                                       storageName = panelChanger.default.STORAGE_NAME,
+                                       panelHistory = JSON.parse(cookie.readFromCookie(storageName) || "[]"),
+                                       panelChangerComponent = self._panelChangerComponent;
+
+                               if (panelChangerComponent) {
+                                       panelHistory.pop();
+                                       if (panelChangerComponent.options && panelChangerComponent.options.manageHistory && panelHistory.length > 0) {
+                                               cookie.writeToCookie(storageName, JSON.stringify(panelHistory));
+                                               panelChangerComponent.changePanel("#" + panelHistory.pop(), CONST.REVERSE, "back");
+                                               event.stopPropagation();
+                                       }
+                               }
+                       }
+
+                       window.addEventListener("tauback", routePanel.tauback.bind(routePanel), false);
+
+                       ns.router.route.panel = routePanel;
+
+                       }(window.document, ns));
+
+/*global ns, define, ns */
+/*jslint nomen: true */
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * #Route Card
+ * Support class for router to fill content of card.
+ * @class ns.router.route.card
+ * @author Tomasz Lukawski <t.lukawski@samsung.com>
+ */
+(function () {
+       "use strict";
+                               var routeCard,
+                               objectUtil = ns.util.object,
+                               path = ns.util.path,
+                               DOM = ns.util.DOM,
+                               defaults = {
+                                       volatileRecord: true,
+                                       orderNumber: 2
+                               },
+                               CardRoute = function () {
+                                       this.filter = ".ui-card";
+                                       this.options = defaults;
+                               },
+                               prototype = CardRoute.prototype;
+
+                       CardRoute.prototype = prototype;
+
+                       prototype.option = function () {
+                               return objectUtil.merge({}, defaults);
+                       };
+
+                       prototype.find = function () {
+                               return null;
+                       };
+
+                       /**
+                        * This method creates data url from absolute url given as argument.
+                        * @method _createDataUrl
+                        * @param {string} absoluteUrl
+                        * @protected
+                        * @static
+                        * @member ns.router.route.card
+                        * @return {string}
+                        */
+                       prototype._createDataUrl = function (absoluteUrl) {
+                               return path.convertUrlToDataUrl(absoluteUrl, true);
+                       };
+
+                       /**
+                        * This method parses HTML and runs scripts from parsed code.
+                        * Fetched external scripts if required.
+                        * @method parse
+                        * @param {string} html HTML code to parse
+                        * @param {string} absUrl Absolute url for parsed card content
+                        * @member ns.router.route.card
+                        * @return {?HTMLElement} Element of content in parsed document.
+                        */
+                       prototype.parse = function (html, absUrl) {
+                               var self = this,
+                                       card,
+                                       dataUrl = self._createDataUrl(absUrl);
+
+                               // Finding matching page inside created element
+                               card = html.querySelector(self.filter);
+
+                               // If a card exists...
+                               if (card) {
+                                       DOM.setNSData(card, "url", dataUrl);
+                                       DOM.setNSData(card, "external", true);
+                               }
+                               return card;
+                       };
+
+
+                       /**
+                        * This method changes card content.
+                        * @method open
+                        * @param {HTMLElement|string} content The content which will be attached
+                        * @param {Object} [options]
+                        * @param {string} [options.dataUrl] Sets if card has url attribute.
+                        * @member ns.router.route.card
+                        */
+                       prototype.open = function (content, options) {
+                               var url = DOM.getNSData(content, "url"),
+                                       card = options.card;
+
+                               // if no url is set, apply the address of chosen card to data-url attribute
+                               if (!url && options.href) {
+                                       url = options.href;
+                                       DOM.setNSData(content, "url", url);
+                               }
+
+                               if (url && !options.fromHashChange) {
+                                       if (!path.isPath(url) && url.indexOf("#") < 0) {
+                                               url = path.makeUrlAbsolute("#" + url, path.documentUrl.hrefNoHash);
+                                       }
+                               }
+
+                               if (card) {
+                                       card.changeContent(content, options);
+                               }
+
+                       };
+
+                       routeCard = new CardRoute();
+
+                       ns.router.route.card = routeCard;
+
+                       }());
+
+/*global define, XMLHttpRequest, ns*/
+/**
+ * #HTML template engine
+ *
+ * Parser for HTML files.
+ *
+ * This class hasn't public interface. This class is registered as template engine
+ * in template manager.
+ *
+ * This engine give support of load HTML files for give URL.
+ *
+ * @class ns.template.html
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ */
+(function () {
+       "use strict";
+                               var template = ns.template,
+                               util = ns.util,
+                               utilPath = util.path;
+
+                       /**
+                        * Callback for event load and error on  XMLHttpRequest
+                        * @param {Function} callback Function called after parse response
+                        * @param {Object} data Data passed to render function
+                        * @param {Event} event event object
+                        */
+                       function callbackFunction(callback, data, event) {
+                               var request = event.target,
+                                       status = {},
+                                       element;
+
+                               if (request.readyState === 4) {
+                                       status.success = (request.status === 200 || (request.status === 0 && request.responseXML));
+                                       element = request.responseXML;
+                                       // if option fullDocument is set then return document element
+                                       // Router require full document
+                                       if (!data.fullDocument) {
+                                               // otherwise return first child of body
+                                               // controller require only element
+                                               element = element.body.firstChild;
+                                       }
+                                       callback(status, element);
+                               }
+                       }
+
+                       /**
+                        * Function process given path, get file by XMLHttpRequest and return
+                        * HTML element.
+                        * @param {Object} globalOptions
+                        * @param {string} path
+                        * @param {Object} data
+                        * @param {Function} callback
+                        */
+                       function htmlTemplate(globalOptions, path, data, callback) {
+                               var absUrl = path,
+                                       request,
+                                       eventCallback = callbackFunction.bind(null, callback, data);
+
+                               // If the caller provided data append the data to the URL.
+                               if (data) {
+                                       absUrl = utilPath.addSearchParams(path, data);
+                               }
+
+                               // Load the new content.
+                               request = new XMLHttpRequest();
+                               request.responseType = "document";
+                               request.overrideMimeType("text/html");
+                               request.open("GET", absUrl);
+                               request.addEventListener("error", eventCallback);
+                               request.addEventListener("load", eventCallback);
+                               request.send();
+                       }
+
+                       template.register("html", htmlTemplate);
+                       }());
+
+/*global define, ns, window */
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/*
+ * @author Maciej Urbanski <m.urbanski@samsung.com>
+ * @author Krzysztof Antoszek <k.antoszek@samsung.com>
+ */
+(function (ns) {
+       "use strict";
+                               if (ns.getConfig("autorun", true) === true) {
+                               ns.engine.run();
+                       }
+                       }(ns));
+
+/*global window, ns, define */
+/*
+* Copyright (c) 2019 Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.1 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+ *
+ * Class for managing application theme
+ * @class ns.theme
+ */
+(function (document, ns) {
+       "use strict";
+    
+                       var THEME_CLASS_PREFIX = "ui-theme-",
+                               DEFAULT_THEME = "light",
+                               themeManager = {
+                    /**
+                     * A function used to set newtheme for application
+                     * @param {string?} newTheme - new theme to set. If it is undefined or empty string default theme will be set.
+                     */
+                                       setTheme: function (newTheme) {
+                                               var classList = document.body.classList,
+                                                       classArray = [].slice.call(classList);
+
+                        //Remove current theme if exists
+                                               classArray.forEach(function (className) {
+                                                       if (className.startsWith(THEME_CLASS_PREFIX)) {
+                                                               classList.remove(className);
+                                                       }
+                                               });
+                                               if (newTheme) {
+                                                       classList.add(THEME_CLASS_PREFIX + newTheme);
+                                                       ns.event.trigger(document, "themechange", {theme: newTheme});
+                                               }
+                                       },
+                                       getTheme: function () {
+                                               var classList = document.body.classList,
+                                                       classArray = [].slice.call(classList);
+
+
+                                               classArray = classArray.filter(function (className) {
+                                                       return className.startsWith(THEME_CLASS_PREFIX);
+                                               });
+
+                                               if (classArray.length) {
+                                                       return classArray[0].replace(THEME_CLASS_PREFIX, "");
+                                               }
+                                               return "" || DEFAULT_THEME;
+                                       }
+                               };
+
+                       ns.theme = themeManager;
+            }(window.document, ns));
+/*global define, ns */
+/**
+ * #Tizen Advanced UI Framework
+ *
+ * Tizen Advanced UI Framework(TAU) is new name of Tizen Web UI framework. It provides tools, such as widgets, events, effects, and animations, for Web application development. You can leverage these tools by just selecting the required screen elements and creating applications.
+ *
+ * TAU service is based on a template and works on a Web browser, which runs on the WebKit engine. You can code Web applications using the TAU, standard HTML5, and Tizen device APIs. You can also use different widgets with CSS animations and rendering optimized for Tizen Web browsers.
+ *
+ * For more information about the basic structure of a page in the Web application using the TAU, see [Application Page Structure](page/app_page_layout.htm).
+ *
+ * ##Framework Services
+ *
+ * The Web UI framework consists of the following services:
+ *
+ *  - Page navigation
+ *
+ *    Navigation JavaScript library is provided to allow smooth navigation between TAU based application [pages](page/layout.htm).
+ *  - Web widgets and themes
+ *
+ *    We support APIs and CSS themes for Tizen web [widgets](widget/widget_reference.htm)
+ *  - Element Events
+ *
+ *    Some special [events](event/event_reference.htm) are available with TAU that optimized for the Web applications.
+ *  - Useful utility
+ *
+ *    Some special [utility](util/util_reference.htm) are available with TAU that supporting easy DOM methods for the Web applications.
+ *
+ * !!!The framework runs only on browsers supporting the HTML5/CSS standards. The draft version of the W3C specification is not fully supported.!!!
+ * @class ns.mobile
+ * @title Tizen Advanced UI Framework
+ */
+                       ns.info.profile = "mobile";
+                       
+}(window, window.document));
diff --git a/d2d_app/client/lib/tau/mobile/js/tau.min.js b/d2d_app/client/lib/tau/mobile/js/tau.min.js
new file mode 100644 (file)
index 0000000..f6e0f2d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+!function(a,b,c){"use strict";var d=a.tau=a.tau||{},e=a.tauConfig=a.tauConfig||{};e.rootNamespace="tau",e.fileName="tau",d.version="1.2.7",function(b,d){var e=0,f=+new Date,g=[].slice,h="",i="",j=function(a){var b=new Date;a.unshift("["+h+"]["+b.toLocaleString()+"]")},k=a.ns||a.tau||{},l=a.nsConfig||a.tauConfig||{},m=function(a){this.message=a};k.info=k.info||{profile:"custom"},k.tauPerf=k.tauPerf||{},a.ns=k,a.nsConfig=l,a.tau=k,a.tauConfig=l,h=l.rootNamespace,i=l.fileName,m.prototype.toString=function(){return this.message},k.getUniqueId=function(){return h+"-"+k.getNumberUniqueId()+"-"+f},k.getNumberUniqueId=function(){return e++},k.log=function(){var a=g.call(arguments);j(a),d&&d.log.apply(d,a)},k.warn=function(){var a=g.call(arguments);j(a),d&&d.warn.apply(d,a)},k.error=function(){var a=g.call(arguments);j(a),d&&d.error.apply(d,a)},k.getConfig=function(a,b){return l[a]===c?b:l[a]},k.setConfig=function(a,b,d){d&&l[a]!==c||(l[a]=b)},k.getFrameworkPath=function(){var a,c,d,e,f=b.getElementsByTagName("script"),g=f.length;for(a=0;g>a;a++)if(c=f[a].src,d=c.split("/"),e=d.length,d[e-1]===i+".js"||d[e-1]===i+".min.js")return d.slice(0,e-1).join("/");return null},k._TAUException=m,k["throws"]=function(a){throw"string"!=typeof a&&k["throws"]("Wrong parameter type. Message must be a string!"),new k._TAUException(a)}}(a.document,a.console),function(){d.setConfig("autoBuildOnPageChange",!0,!0),d.setConfig("loader",!1,!0),d.setConfig("pageContainerBody",!0,!0),d.setConfig("popupTransition","slideup",!0),d.setConfig("pageTransition","none",!0),d.setConfig("enablePageScroll",!1,!0)}(),function(){d.setConfig("rootDir",d.getFrameworkPath(),!0),d.setConfig("version","",!0),d.setConfig("allowCrossDomainPages",!1,!0),d.setConfig("domCache",!1,!0),d.setConfig("autoBuildOnPageChange",!0,!0),d.setConfig("autoInitializePage",!0,!0),d.setConfig("dynamicBaseEnabled",!0,!0),d.setConfig("pageTransition","none",!0),d.setConfig("popupTransition","none",!0),d.setConfig("popupFullSize",!1,!0),d.setConfig("scrollEndEffectArea","content",!0),d.setConfig("enablePopupScroll",!1,!0),d.setConfig("pageContainer",b.body,!0),d.setConfig("findProfileFile",!1,!0),d.setConfig("keyboardSupport",!1)}(),function(){function a(a){Object.defineProperty(d.defaults,a,{get:function(){return d.warn("tau.defaults are deprecated from Tizen 3.0, please use tau.getConfig."),d.getConfig(a)},set:function(b){return d.warn("tau.defaults are deprecated from Tizen 3.0, please use tau.setConfig."),d.setConfig(a,b)}})}var b={};d.defaults=b,a("autoInitializePage"),a("dynamicBaseEnabled"),a("pageTransition"),a("popupTransition"),a("popupFullSize"),a("enablePageScroll"),a("goToTopButton"),a("scrollEndEffectArea"),a("enablePopupScroll")}(),function(a,b){function e(d){var e=b.createElement("style"),f="@media "+d+" { #jquery-mediatest { position:absolute; } }";return d.cacheMedia===c&&(e.type="text/css",e.styleSheet?e.styleSheet.cssText=f:e.appendChild(b.createTextNode(f)),s.firstChild?s.insertBefore(q,s.firstChild):s.appendChild(q),s.insertBefore(e,q),l=a.getComputedStyle(p),o[d]="absolute"===l.position,e.parentNode.removeChild(e),q.parentNode.removeChild(q)),o[d]}function f(a,c,d){var e,f,g=b.createElement("div"),h=function(a){return a.charAt(0).toUpperCase()+a.substr(1)},i=function(a){return"-"+a.charAt(0).toLowerCase()+a.substr(1)+"-"},j=function(b){var d=i(b)+a+": "+c+";",f=h(b),j=f+h(a);g.setAttribute("style",d),g.style[j]&&(e=!0)},k=d?[d]:t,l=k.length;for(f=0;l>f;f++)j(k[f]);return!!e}function g(a){var b,d=a.charAt(0).toUpperCase()+a.substr(1),e=(a+" "+t.join(d+" ")+d).split(" ");for(b=0;b<e.length;b++)if(e.hasOwnProperty(b)&&r[e[b]]!==c)return!0;return!1}function h(){var a="transform-3d";return f("perspective","10px","moz")||e("(-"+t.join("-"+a+"),(-")+"-"+a+"),("+a+")")}function i(){var a,c,d=location.protocol+"//"+location.host+location.pathname+"ui-dir/",e=b.head,f=e.querySelector("base"),g=null,h=!1,i="";return f?(i=f.getAttribute("href"),f.setAttribute("href",d),h=!0):(f=g=b.createElement("base"),f.setAttribute("href",d),e.appendChild(f)),a=b.createElement("a"),a.href="testurl",q.firstChild?q.insertBefore(a,q.firstChild):q.appendChild(a),c=a.href,f.href=i||location.pathname,g&&e.removeChild(g),h&&f.setAttribute("href",i),"#build"===location.hash?!1:0===c.indexOf(d)}function j(){var d,e=b.createElement("x"),f=b.documentElement,g=a.getComputedStyle,h=e.style;return h.pointerEvents===c?!1:(h.pointerEvents="x",f.appendChild(e),d=g&&"auto"===g(e,"").pointerEvents,f.removeChild(e),!!d)}function k(){var a=b.createElement("div");return a.getBoundingClientRect!==c}var l,m,n,o={},p=b.createElement("div"),q=b.createElement("body"),r=q.style,s=b.getElementsByTagName("html")[0],t=["Webkit","Moz","O"],u=a.palmGetResource,v=a.opera,w=a.operamini&&"[object OperaMini]"==={}.toString.call(a.operamini),x=p.style;p.id="jquery-mediatest",q.appendChild(p),m=a.blackberry&&!g("-webkit-transform"),n=function(){var a=3,c=b.createElement("div"),d=c.all||[];do c.innerHTML="<!--[if gt IE "+ ++a+"]><br><![endif]-->";while(d[0]);return a}(),d.support={media:e,cssTransitions:(a.WebKitTransitionEvent!==c||f("transition","height 100ms linear"))&&!v,pushState:a.history.pushState&&a.history.replaceState&&!0,mediaquery:e("only all"),cssPseudoElement:!!g("content"),touchOverflow:!!g("overflowScrolling"),cssTransform3d:h(),boxShadow:!!g("boxShadow")&&!m,scrollTop:(a.pageXOffset||b.documentElement.scrollTop||q.scrollTop)===c||u||w?!1:!0,dynamicBaseTag:i(),cssPointerEvents:j(),cssAnimationPrefix:x.hasOwnProperty("webkitAnimation")?"-webkit-":x.hasOwnProperty("mozAnimation")?"-moz-":x.hasOwnProperty("oAnimation")?"-o-":"",boundingRect:k(),browser:{ie:n>4},gradeA:function(){return(this.mediaquery||this.browser.ie&&n>=7)&&(this.boundingRect||null!==(a.jQuery&&a.jQuery.fn&&a.jQuery.fn.jquery.match(/1\.[0-7+]\.[0-9+]?/)))},touch:b.ontouchend!==c,orientation:a.orientation!==c&&a.onorientationchange!==c},p=null,q=null}(a,a.document),function(a,b,c){function d(a,b){var c,d=new XMLHttpRequest;return d.open("get",a,!1),b&&d.overrideMimeType(b),d.send(),4===d.readyState&&(c=d.status,200===c||0===c&&d.responseText)?d.responseText:null}function e(a){for(var b,c=m.call(a.querySelectorAll("script[src]")),d=c.length;--d>=0;)b=c[d],b.parentNode.removeChild(b);return c}function f(b){return function(){try{a.eval(b)}catch(d){d.stack?c.error(d.stack):d.name&&d.message?c.error(d.name,d.message):c.error(d)}}}function g(a){var b,c=a.length;for(b=0;c>b;++b)a[b]()}function h(a,c){var d,e,f,g,h=[];for(f=0,g=a.length;g>f;++f)e=k.fetchSync(a[f].src,"text/plain"),e&&(d=b.adoptNode(a[f]),d.setAttribute("data-src",a[f].src),d.removeAttribute("src"),h.push(k.safeEvalWrap(e)),c&&c.appendChild(d));return h}function i(a){var c,d=[];return m.call(a.querySelectorAll("script:not([data-src]):not([type]):not([id]):not([src])")).forEach(function(a){c=b.createElement("script"),c.innerText=a.textContent,m.call(a.attributes).forEach(function(b){c.setAttribute(b.name,a.getAttribute(b.name))}),a.parentNode.removeChild(a),d.push(c)}),d}var j=null,k=c.util||{},l=[],m=[].slice,n=!1;k._requestAnimationFrameOnSetTimeout=function(b){"function"!=typeof b&&c["throws"]("Parameter is not a function!"),j=a.setTimeout(b.bind(b,+new Date),1e3/60)},k._loop=function(){var a=m.call(l),b=a.shift(),c=performance.now();for(l=[];b;)b(c),b=performance.now()-c<15?a.shift():null;a.length||l.length?(l.unshift.apply(l,a),k.windowRequestAnimationFrame(k._loop)):n=!1},k._getRequestAnimationFrame=function(){return(a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||k._requestAnimationFrameOnSetTimeout).bind(a)},k.windowRequestAnimationFrame=k._getRequestAnimationFrame(),k.requestAnimationFrame=function(a){l.push(a),n||(k.windowRequestAnimationFrame(k._loop),n=!0)},k._cancelAnimationFrameOnSetTimeout=function(){a.clearTimeout(j)},k.cancelAnimationFrames=function(a){var b=0,d=l.length,e=0;if(a)for(;d>0&&b>-1;){for(b=-1;d>e;e++)if(l[e].animationId===a){b=e;break}b>-1&&(l.splice(b,1),d--)}else c.warn("cancelAnimationFrames() require one parameter for request identify")},k._getCancelAnimationFrame=function(){return(a.cancelAnimationFrame||a.webkitCancelAnimationFrame||a.mozCancelAnimationFrame||a.oCancelAnimationFrame||a.msCancelAnimationFrame||k._cancelAnimationFrameOnSetTimeout).bind(a)},k.cancelAnimationFrame=k._getCancelAnimationFrame(),k.fetchSync=d,k._removeExternalScripts=e,k.safeEvalWrap=f,k.batchCall=g,k._createScriptsSync=h,k._removeInlineScripts=i,k.async=k.requestAnimationFrame,k.importEvaluateAndAppendElement=function(a,c){var d=k._createScriptsSync(k._removeExternalScripts(a),a),e=k._removeInlineScripts(a),f=b.importNode(a,!0);return c.appendChild(f),e.forEach(function(a){c.appendChild(a)}),k.batchCall(d),f},k.isNumber=function(a){var b=parseFloat(a);return!isNaN(b)&&isFinite(b)},k.runScript=function(c,d){var e,f,g,h=b.createElement("script"),i=m.call(d.attributes),j=d.getAttribute("src");for(null!==j&&(j=k.path.makeUrlAbsolute(j,c)),f=i.length;--f>=0;)g=i[f],"src"!==g.name?h.setAttribute(g.name,g.value):h.setAttribute("data-src",g.value);e=j?k.fetchSync(j,"text/plain"):d.textContent,e&&(h.src=a.URL.createObjectURL(new Blob([e],{type:"text/javascript"})),h.textContent=e),d.parentNode.replaceChild(h,d)},c.util=k}(a,a.document,d),function(a){function b(a,b){var c,d,e=!1;return isNaN(a)&&isNaN(b)?(e=!0,c=a.charCodeAt(0),d=b.charCodeAt(0)):(c=isNaN(a)?0:a,d=isNaN(b)?0:b),{inival:c,endval:d,chars:e}}function d(a,c,d){var e,f,g,h,i,j=[],k=d||1;if(i=b(a,c),e=i.inival,f=i.endval,h=i.chars,g=f>=e)for(;f>=e;)j.push(h?String.fromCharCode(e):e),e+=k;else for(;e>=f;)j.push(h?String.fromCharCode(e):e),e-=k;return j}function e(a){return Array.isArray(a)||a instanceof NodeList||"function"==typeof a}function f(a){var b=a.length;return 0===b||"number"==typeof b&&b>0&&b-1 in a}function g(a){return a&&a!==a.window?e(a)&&f(a):!1}function h(a,b){var c,d,e=a;for(a instanceof Array||(e=[].slice.call(a)),d=e.length,c=0;d>c;c++)b(e[c],c,e)}function i(a,b){var c,d,e,f=[],g=a;for(a instanceof Array||(g=[].slice.call(a)),d=g.length,c=0;d>c;c++)e=g[c],b(e,c,g)&&f.push(e);return f}function j(a,b){var c,d,e=[],f=a;for(a instanceof Array||(f=[].slice.call(a)),d=f.length,c=0;d>c;c++)e.push(b(f[c],c,f));return e}function k(a,b,d){var e,f,g,h=d,i=a;for(a instanceof Array||(i=[].slice.call(a)),f=i.length,e=0;f>e;e++)g=i[e],h=h===c&&0===e?g:b(h,g,e,i);return h}a.util.array={range:d,isArrayLike:g,forEach:h,filter:i,map:j,reduce:k}}(d),function(a,d){function e(a){var b;return g.forEach(function(c){c.element===a&&(b=c.instance)}),b}function f(a){g.forEach(function(b,c){b.element===a&&g.splice(c,1)})}var g=[],h=Array.isArray,i=d.util.array.isArrayLike,j=/\s+/g,k=function(a){return a.trim()},l=function(a,b){var c,d,e=[];if("string"==typeof a&&(a=a.split(j).map(k)),h(a))for(d=0;d<a.length;d++)e.push({type:a[d],callback:b});else for(c in a)a.hasOwnProperty(c)&&e.push({type:c,callback:a[c]});return e};d.event={trigger:function(a,b,c,d,e){var f=new CustomEvent(b,{detail:c,bubbles:"boolean"==typeof d?d:!0,cancelable:"boolean"==typeof e?e:!0});return a.dispatchEvent(f)},preventDefault:function(a){var b=a._originalEvent;b&&b.preventDefault&&b.preventDefault(),a.preventDefault()},stopPropagation:function(a){var b=a._originalEvent;b&&b.stopPropagation&&b.stopPropagation(),a.stopPropagation()},stopImmediatePropagation:function(a){var b=a._originalEvent;b&&b.stopImmediatePropagation&&b.stopImmediatePropagation(),a.stopImmediatePropagation()},documentRelativeCoordsFromEvent:function(c){var d,e=c?c:a.event,f={x:e.clientX,y:e.clientY},g={x:e.pageX,y:e.pageY},h=0,i=0,j=b.body,k=b.documentElement;return c.type.match(/^touch/)&&(d=e.targetTouches[0]||e.originalEvent.targetTouches[0],g={x:d.pageX,y:d.pageY},f={x:d.clientX,y:d.clientY}),g.x||g.y?(h=g.x,i=g.y):(f.x||f.y)&&(h=f.x+j.scrollLeft+k.scrollLeft,i=f.y+j.scrollTop+k.scrollTop),{x:h,y:i}},targetRelativeCoordsFromEvent:function(a){var b=a.target,e={x:a.offsetX,y:a.offsetY};return(e.x===c||isNaN(e.x)||e.y===c||isNaN(e.y))&&(e=d.event.documentRelativeCoordsFromEvent(a),e.x-=b.offsetLeft,e.y-=b.offsetTop),e},fastOn:function(a,b,c,d){a.addEventListener(b,c,d||!1)},fastOff:function(a,b,c,d){a.removeEventListener(b,c,d||!1)},prefixedFastOn:function(a,b,c,d){var e=b.charAt(0).toLocaleUpperCase()+b.substring(1);a.addEventListener(b.toLowerCase(),c,d||!1),a.addEventListener("webkit"+e,c,d||!1),a.addEventListener("moz"+e,c,d||!1),a.addEventListener("ms"+e,c,d||!1),a.addEventListener("o"+e.toLowerCase(),c,d||!1)},prefixedFastOff:function(a,b,c,d){var e=b.charAt(0).toLocaleUpperCase()+b.substring(1);a.removeEventListener(b.toLowerCase(),c,d||!1),a.removeEventListener("webkit"+e,c,d||!1),a.removeEventListener("moz"+e,c,d||!1),a.removeEventListener("ms"+e,c,d||!1),a.removeEventListener("o"+e.toLowerCase(),c,d||!1)},on:function(a,b,c,e){var f,g,h,j,k,m;for(k=i(a)?a:[a],h=k.length,m=l(b,c),j=m.length,f=0;h>f;f++)if("function"==typeof k[f].addEventListener)for(g=0;j>g;g++)d.event.fastOn(k[f],m[g].type,m[g].callback,e)},off:function(a,b,c,e){var f,g,h,j,k,m;for(k=i(a)?a:[a],h=k.length,m=l(b,c),j=m.length,f=0;h>f;f++)if("function"==typeof k[f].addEventListener)for(g=0;j>g;g++)d.event.fastOff(k[f],m[g].type,m[g].callback,e)},one:function(a,b,c,e){var f,g,h,j,k,m,n=[].slice,o=[];for(k=i(a)?n.call(a):[a],h=k.length,m=l(b,c),j=m.length,f=0;h>f;f++)if("function"==typeof k[f].addEventListener)for(o[f]=[],g=0;j>g;g++)o[f][g]=function(a,b){var c=n.call(arguments);d.event.fastOff(k[a],m[b].type,o[a][b],e),c.shift(),c.shift(),m[b].callback.apply(this,c)}.bind(null,f,g),d.event.fastOn(k[f],m[g].type,o[f][g],e)},enableGesture:function(a){var b=e(a),c=arguments.length,f=1;for(b||(b=new d.event.gesture.Instance(a),g.push({element:a,instance:b}));c>f;f++)b.addDetector(arguments[f])},disableGesture:function(a){var b=e(a),c=arguments.length,d=1;b&&(c>1?b.removeDetector(arguments[d]):(b.destroy(),f(a)))}}}(a,d),function(a,b){var c=d.event,e={profile:"default",theme:"default",version:d.version,refreshTheme:function(d){var e,f=b.createElement("span"),g=b.body;return"interactive"!==b.readyState&&"complete"!==b.readyState?(c.fastOn(b,"DOMContentLoaded",this.refreshTheme.bind(this,d)),null):(f.classList.add("tau-info-theme"),g.appendChild(f),e=a.getComputedStyle(f,":after").content,e&&(e=e.replace(/\"/g,"")),g.removeChild(f),e&&e.length>0&&(this.theme=e),e=e||null,d&&d(e),e)}};e.refreshTheme(),d.info=e}(a,a.document),function(b,c){function d(a){var b=c.getConfig("namespace");return"[data-"+(b?b+"-":"")+a+"]"}function e(a,b){return l&&a[l]?a[l](b):!1}function f(a){for(var c=[],d=a.parentNode;d&&d!==b;)c.push(d),d=d.parentNode;return c}function g(a,c){for(var d=a;d&&d!==b;){if(c(d))return d;d=d.parentNode}return null}function h(a,b){return e(b,a)}function i(a,b){return b&&b.classList&&b.classList.contains(a)}function j(a,b){return b.tagName.toLowerCase()===a}var k=[].slice,l=function(){var a=b.createElement("div");return"function"==typeof a.webkitMatchesSelector?"webkitMatchesSelector":"function"==typeof a.mozMatchesSelector?"mozMatchesSelector":"function"==typeof a.msMatchesSelector?"msMatchesSelector":"function"==typeof a.matchesSelector?"matchesSelector":"function"==typeof a.matches?"matches":""}();c.util.selectors={matchesSelector:e,getChildrenBySelector:function(a,b){return k.call(a.children).filter(h.bind(null,b))},getChildrenByDataNS:function(a,b){return k.call(a.children).filter(h.bind(null,d(b)))},getChildrenByClass:function(a,b){return k.call(a.children).filter(i.bind(null,b))},getChildrenByTag:function(a,b){return k.call(a.children).filter(j.bind(null,b))},getParents:f,getParentsBySelector:function(a,b){return f(a).filter(h.bind(null,b))},getParentsBySelectorNS:function(a,b){return f(a).filter(h.bind(null,d(b)))},getParentsByClass:function(a,b){return f(a).filter(i.bind(null,b))},getParentsByTag:function(a,b){return f(a).filter(j.bind(null,b))},getClosestBySelector:function(a,b){return g(a,h.bind(null,b))},getClosestBySelectorNS:function(a,b){return g(a,h.bind(null,d(b)))},getClosestByClass:function(a,b){return g(a,i.bind(null,b))},getClosestByTag:function(a,b){return g(a,j.bind(null,b))},getAllByDataNS:function(a,b){return k.call(a.querySelectorAll(d(b)))},getScrollableParent:function(c){for(var d,e;c&&c!==b.body;){if(e=a.getComputedStyle(c),e&&(d=e.getPropertyValue("overflow-y"),"scroll"===d||"auto"===d&&c.scrollHeight>c.clientHeight))return c;c=c.parentNode}return null}}}(a.document,d),function(){var a={copy:function(b){return a.merge({},b)},fastMerge:function(a,b){var d,e;for(d in b)b.hasOwnProperty(d)&&(e=Object.getOwnPropertyDescriptor(a,d),e&&e.writable!==!0&&e.set==c||(a[d]=b[d]));return a},merge:function(){var a,b,d,e,f,g,h=[].slice.call(arguments),i=h.length;for(a=h.shift(),d=!0,"boolean"==typeof arguments[i-1]&&(d=arguments[i-1],i--),f=0;i>f;f++)if(b=h.shift(),null!==b)for(e in b)b.hasOwnProperty(e)&&(g=Object.getOwnPropertyDescriptor(a,e),(!g||d&&(g.writable===!0||g.set!=c))&&(a[e]=b[e]));return a},inherit:function(a,b,c){var d,e,f=new b;for(d in c)c.hasOwnProperty(d)&&(e=c[d],"function"==typeof e?f[d]=function(a,b,c){var d=function(){var c=a.prototype[b];return c?c.apply(this,arguments):null};return function(){var a,b=this._super;return this._super=d,a=c.apply(this,arguments),this._super=b,a}}(b,d,e):f[d]=e);a.prototype=f,a.prototype.constructor=a},hasPropertiesOfValue:function(a,b){var c=Object.keys(a),d=c.length;if(0===d)return!1;for(;--d>=0;)if(a[c[d]]!==b)return!1;return!0},removeProperties:function(a,b){var c,d,e=b.length;for(d=0;e>d;d++)c=b[d],a.hasOwnProperty(c)&&delete a[c];return a}};d.util.object=a}(),function(a,b){function e(a){return a.match(/\[data-role=/)&&!a.match(/:not\(\[data-role=/)?a.trim():a.trim()+":not([data-role='none'])"}function f(a,f,g,h,i,j,k,l,m){var n;if(m=m||{},a){if(!R[a]||j)return g=g||[],g.push("destroy","disable","enable","option","refresh","value"),n={name:a,methods:g,selector:f||"",selectors:f?f.split(",").map(e):[],widgetClass:h||null,namespace:i||"",widgetNameToLowercase:k===c?!0:!!k,BaseElement:l,buildOptions:m},R[a]=n,i&&(R[i+"."+a]=n),M.trigger(b,"widgetdefined",n,!1),!0}else d.error("Widget with selector ["+f+"] defined without a name, aborting!");return!1}function g(a,b,c){var d,e,f=c?c.split("."):[],g=f.pop(),h=f.pop();return g?d=a.instances[g]:(e=Object.keys(a.instances),d=a.instances[e[0]]),h&&d&&d.namespace!==h&&(d=null),d&&d.element===b?d:null}function h(a){return a.hasAttribute(X)}function i(a,c){var d,e,f=a&&typeof a!==V?a.id:a;if(typeof a===V&&(a=b.getElementById(f)),a){if(d=S[f],d&&"object"==typeof d)return g(d,a,c);if(typeof a.hasAttribute===W&&a.hasAttribute($)&&(e=L.call(a.children).filter(h)[0]))return i(e,c)}return null}function j(a){var b=a.element.id,c=a.name,d=S[b];d||(d={elementId:b,element:a.element,instances:{}}),d.instances[c]=a,S[b]=d}function k(a){var b=a&&typeof a!==V?a.id:a;return S[b]&&S[b].instances||null}function l(a,b){var c,d;return c=b.split(_),d=c.indexOf(a),d>-1&&(c.splice(d,1),b=c.join(_)),b}function m(a){a.removeAttribute(X),a.removeAttribute(Z),a.removeAttribute(Y)}function n(a,b){var c,d,e;b?(c=l(b,a.getAttribute(X)||""),d=l(b,a.getAttribute(Z)||""),e=l(b,a.getAttribute(Y)||""),c&&d&&e?(a.setAttribute(X,c),a.setAttribute(Z,d),a.setAttribute(Y,e)):m(a)):m(a)}function o(a,b){var c=a[b];return c?(c.element&&typeof c.element.setAttribute===W&&n(c.element,b),delete a[b],!0):!1}function p(a,b){var c,d,e=!0;for(d in a)a.hasOwnProperty(d)&&(c=o(a,d),a[d]=null,e=e&&c);return O.hasPropertiesOfValue(a,null)&&(S[b]=null),e}function q(a,b,c){var d;return b?(d=o(a,b),O.hasPropertiesOfValue(a,null)&&(S[c]=null)):d=p(a,c),d}function r(a,b){var c,d=typeof a===V?a:a.id,e=S[d];if(e){if(typeof a===V&&(a=e.element),a&&n(a,b),c=S[d]&&S[d].instances)return q(c,b,d);S[d].instances&&0===Object.keys(S[d].instances).length&&(S[d]=null)}return!1}function s(a){return r(a)}function t(a,c){return a&&a instanceof HTMLElement||(a=typeof c.createEmptyElement===W?c.createEmptyElement():b.createElement("div")),a}function u(a,c,d,e){var f,g=e||{},h=g.create;a=c.configure(d,a,e),typeof h===W&&M.one(a,d.name.toLowerCase()+"create",h),a.id&&(c.id=a.id),f=a.getAttribute(X),f&&-1!==f.split(_).indexOf(c.name)||(a=c.build(a)),a&&(c.element=a,j(c),c.trigger(ca.WIDGET_BUILT,c,!1),U||c.init(a),c.bindEvents(a,U),c.trigger(c.widgetEventPrefix+ca.WIDGET_INIT),c.trigger(ca.WIDGET_BOUND,c,!1),M.trigger(b,ca.WIDGET_BOUND,c))}function v(a,b,c){var d,e,f,g=b.widgetClass;return a=t(a,g),d=g?new g(a,c):!1,e=P.getParentsBySelectorNS(a,"enhance=false"),f=i(a,b.name),f&&f.element===a?a:d?(e.length||u(a,d,b,c),d.element):null}function w(a,c){var d;typeof a===V&&(a=b.getElementById(a)),d=i(a,c),d&&(d.destroy(),d.trigger("widgetdestroyed"),r(a,c))}function x(a){var b,c,d;d=k(a);for(b in d)d.hasOwnProperty(b)&&(c=d[b],c&&(c.destroy(),c.trigger("widgetdestroyed")))}function y(a,c){var d,e;for(typeof a===V&&(a=b.getElementById(a)),c||x(a),d=L.call(a.querySelectorAll("["+Z+"]")),e=d.length-1;e>=0;e-=1)d[e]&&y(d[e],!1);s(a)}function z(a,b,c){var d=a&&a.getAttribute(Y)||b&&b.name;return b=b||d&&R[d]||{name:d},v(a,b,c)}function A(a,b){var c=Node.DOCUMENT_POSITION_CONTAINS|Node.DOCUMENT_POSITION_PRECEDING;return a.element===b.element?0:a.element.compareDocumentPosition(b.element)&c?1:-1}function B(a){z(a.element||a,R[a.widgetName])}function C(a){var c,d,e,f,g,h,i,j=L.call(a.querySelectorAll(aa)),k=[],l=Object.keys(R),m=l.length;for(j.forEach(B),e=0;m>e;++e)if(h=l[e],-1===h.indexOf(".")&&(g=R[h],i=g.selectors,i.length))for(d=ba(h),c=L.call(a.querySelectorAll(i.join(d+",")+d)),f=c.length;--f>=0;)k.push({element:c[f],widgetName:h});k.sort(A),k.forEach(B),M.trigger(b,"built"),M.trigger(b,ca.BOUND)}function D(a){C(a.target)}function E(){var a,c,d,e,f=b.head;if(c=f.querySelectorAll('[name="viewport"]'),a=c.length,a>0)for(--a,e=0;a>e;++e)f.removeChild(c[e]);else d=b.createElement("meta"),d.setAttribute("name","viewport"),d.setAttribute("content","width=device-width, user-scalable=no"),f.firstChild?f.insertBefore(d,f.firstChild):f.appendChild(d)}function F(){M.trigger(b,ca.READY),E()}function G(){M.trigger(b,ca.STOP_ROUTING)}function H(){G(),M.fastOff(b,"create",D),y(b,!0),M.trigger(b,ca.DESTROY)}function I(a,b){var c=b instanceof HTMLElement?"HTMLElement":typeof b;return a[c]=b,a}function J(a){return Q.reduce(a,I,{})}var K,L=[].slice,M=d.event,N=d.util,O=N.object,P=N.selectors,Q=d.util.array,R={},S={},T=a.location,U="#build"===T.hash,V="string",W="function",X="data-tau-built",Y="data-tau-name",Z="data-tau-bound",$="data-tau-wrapper",_=",",aa="*["+X+"]["+Y+"]:not(["+Z+"])",ba=function(a){return":not(["+X+"*='"+a+"']):not(["+Z+"*='"+a+"'])"},ca={INIT:"tauinit",READY:"tauready",WIDGET_BOUND:"widgetbound",WIDGET_DEFINED:"widgetdefined",WIDGET_BUILT:"widgetbuilt",DESTROY:"taudestroy",BOUND:"bound",WIDGET_INIT:"init",STOP_ROUTING:"tauroutingstop"};d.widgetDefinitions={},K={justBuild:"#build"===T.hash,dataTau:{built:X,name:Y,bound:Z,separator:_,widgetWrapper:$},destroyWidget:w,destroyAllWidgets:y,createWidgets:C,getDefinitions:function(){return R},getWidgetDefinition:function(a){return R[a]},defineWidget:f,getBinding:i,getAllBindings:k,setBinding:j,removeBinding:r,removeAllBindings:s,_clearBindings:function(){S={}},build:F,run:function(){switch(G(),M.fastOn(b,"create",D),M.trigger(b,ca.INIT,{tau:d}),b.readyState){case"interactive":case"complete":F();break;default:M.one(b,"DOMContentLoaded",F.bind(K))}},instanceWidget:function(a,b,c){var e,f,g=J(arguments);if(a=g.HTMLElement,b=g.string,c=g.object,a&&(e=i(a,b)),!e&&R[b]){if(f=R[b],f.buildOptions.requireMatchSelector&&!d.util.selectors.matchesSelector(a,f.selector))return null;a=z(a,f,c),e=i(a,b)}else e&&e.option(c);return e},stop:G,destroy:H,setJustBuild:function(a){a?T.hash="build":T.hash="",U=a},getJustBuild:function(){return U},_createEventHandler:D},K.eventType=ca,d.engine=K}(a,a.document),function(a,c){function d(){a.event.trigger(b,"mobileinit")}function e(){b.removeEventListener(f.INIT,d,!1),b.removeEventListener(f.DESTROY,e,!1)}var f=a.engine.eventType;a.jqm={jQuery:a.getConfig("jQuery")||c.jQuery},b.addEventListener(f.INIT,d,!1),b.addEventListener(f.DESTROY,e,!1)}(d,a),function(a,b){var c=d.engine.eventType,e=d.jqm.jQuery,f={INIT:c.INIT,DESTROY:c.DESTROY},g={init:function(){e&&(e.mobile=e.mobile||{},e.mobile.ns="",e.mobile.subPageUrlKey="ui-page",e.mobile.activePageClass="ui-page-active",e.mobile.activeBtnClass="ui-btn-active",e.mobile.focusClass="ui-focus",e.mobile.ajaxEnabled=!0,e.mobile.hashListeningEnabled=!0,e.mobile.linkBindingEnabled=!0,e.mobile.defaultPageTransition="fade",e.mobile.maxTransitionWidth=!1,e.mobile.minScrollBack=250,e.mobile.touchOverflowEnabled=!1,e.mobile.defaultDialogTransition="pop",e.mobile.pageLoadErrorMessage="Error Loading Page",e.mobile.phonegapNavigationEnabled=!1,e.mobile.autoInitializePage=!0,e.mobile.pushStateEnabled=!0,e.mobile.ignoreContentEnabled=!1,e.mobile.orientationChangeEnabled=!0,e.mobile.tizen=e.mobile.tizen||{},e.mobile.tizen.enableHWKeyHandler=!0)},destroy:function(){b.removeEventListener(f.INIT,g.init,!1),b.removeEventListener(f.DESTROY,g.destroy,!1),e=null}};b.addEventListener(f.INIT,g.init,!1),b.addEventListener(f.DESTROY,g.destroy,!1)}(a,a.document),function(){function a(a,b){return b.toLocaleUpperCase()}function b(a,b){return"-"+b.toLowerCase()}function c(b){return b.replace(j,a)}function e(a){return a.replace(k,b)}function f(a){return a.charAt(0).toLocaleUpperCase()+a.substring(1)}function g(a){var b;return a&&-1===(a+"").indexOf("%")?(b=parseInt(a,10),isNaN(b)&&(b=null),b):a}function h(a){var b;return b="string"==typeof a?a.split(","):a||[],l.map(b,g)}function i(a){var b=[];return[].slice.call(arguments).slice(1).forEach(function(a){a.split(" ").forEach(function(a){b.push(a.trim())})}),a.split(" ").filter(function(a){return-1===b.indexOf(a)}).join(" ")}var j=/-([a-z])/gi,k=/([A-Z])/g,l=d.util.array;d.util.string={dashesToCamelCase:c,camelCaseToDashes:e,firstToUpperCase:f,parseProperty:h,removeExactTags:i}}(),function(){d.util.DOM=d.util.DOM||{}}(),function(){function a(a,b){var c=d.getConfig(g),e="";return b||(e="data-"),e+(c?c+"-":"")+a}function b(a,b,c){a[b]=c,a.setAttribute(b,c)}var e=d.util.selectors,f=d.util.DOM,g="namespace";f.inheritAttr=function(a,b,c){var d,f=a.getAttribute(b);return!f&&(d=e.getClosestBySelector(a,c))?d.getAttribute(b):f},f.getNumberFromAttribute=function(a,b,c,d){var e=a.getAttribute(b),f=d;return isNaN(e)||("float"===c?(e=parseFloat(e),isNaN(e)||(f=e)):(e=parseInt(e,10),isNaN(e)||(f=e))),f},f.setNSData=function(b,c,d){b.setAttribute(a(c),d)},f.getNSData=function(b,c,d){var e=b.getAttribute(a(c,d));return"true"===e?!0:"false"===e?!1:e},f.hasNSData=function(b,c){return b.hasAttribute(a(c))},f.nsData=function(a,b,d){return d===c?f.getNSData(a,b):f.setNSData(a,b,d)},f.removeNSData=function(b,c){b.removeAttribute(a(c))},f.getData=function(a){var b,c,d,e,f,g="data-",h={},i=a.attributes,j=i.length;for(e=0;j>e;e++)b=i.item(e),c=b.nodeName,c.indexOf(g)>-1&&(d=b.value,f=d.toLowerCase(),"true"===f?d=!0:"false"===f&&(d=!1),h[c.replace(g,"")]=d);return h},f.removeAttribute=function(a,b){a.removeAttribute(b),a[b]=!1},f.setAttribute=b,f.setAttributes=function(a,c){var d,e,f,g=Object.keys(c);for(d=0,f=g.length;f>d;d++)e=g[d],b(a,e,c[e])}}(),function(a,c){function d(b,c,d,e){var f,g=a.getComputedStyle(b),h=d;if(g&&(f=g.getPropertyValue(c)))switch(e){case"integer":f=parseInt(f,10),isNaN(f)||(h=f);break;case"float":f=parseFloat(f),isNaN(f)||(h=f);break;default:h=f}return h}function e(a){return(a+"").indexOf(".")>-1?parseFloat(a):parseInt(a,10)}function f(b,c,d,f){var g,h,i,j=a.getComputedStyle(b,d);for(g in c)c.hasOwnProperty(g)&&(h=j.getPropertyValue(g),i=e(h),isNaN(i)&&f||(h=i),c[g]=h)}function g(a,b,c,d,e){var g,h,i,j,k=a.style;return"none"!==k.display?(f(a,b,c,!0),j=a[e]):d&&(g=k.display,h=k.visibility,i=k.position,k.display="block",k.visibility="hidden",k.position="relative",f(a,b,c,!0),j=a[e],k.display=g,k.visibility=h,k.position=i),j}function h(a,b,c,d,f,h){var i,j,k=0,l=b&&"outer"===b||!1,m={height:0,"margin-top":0,"margin-bottom":0,"padding-top":0,"padding-bottom":0,"border-top-width":0,"border-bottom-width":0,"box-sizing":""};if(a){i=g(a,m,f,h,"offsetHeight");for(j in m)m.hasOwnProperty(j)&&"box-sizing"!==j&&(m[j]=e(m[j]));k+=m.height,"border-box"!==m["box-sizing"]&&(k+=m["padding-top"]+m["padding-bottom"]),c?k=i:l&&"border-box"!==m["box-sizing"]&&(k+=m["border-top-width"]+m["border-bottom-width"]),d&&(k+=Math.max(0,m["margin-top"])+Math.max(0,m["margin-bottom"]))}return k}function i(a,b,c,d,e,f){var h,i,j,k=0,l=b&&"outer"===b||!1,m={width:0,"margin-left":0,"margin-right":0,"padding-left":0,"padding-right":0,"border-left-width":0,"border-right-width":0,"box-sizing":""};if(a){i=g(a,m,e,f,"offsetWidth");for(j in m)m.hasOwnProperty(j)&&"box-sizing"!==j&&(h=parseFloat(m[j]),m[j]=h);k+=m.width,"border-box"!==m["box-sizing"]&&(k+=m["padding-left"]+m["padding-right"]),c?k=i:l&&"border-box"!==m["box-sizing"]&&(k+=m["border-left-width"]+m["border-right-width"]),d&&(k+=Math.max(0,m["margin-left"])+Math.max(0,m["margin-right"]))}return k}function j(a){var b=0,c=0,d=a;do c+=d.offsetTop,b+=d.offsetLeft,d=d.offsetParent;while(null!==d);return{top:c,left:b}}function k(a){return!(a.offsetWidth<=0&&a.offsetHeight<=0)}function l(a,b,c){var d=a.style,e=b,f="object"!=typeof c?{webkit:c,moz:c,o:c,ms:c,normal:c}:c;d.setProperty(b,f.normal),d.setProperty("-webkit-"+e,f.webkit),d.setProperty("-moz-"+e,f.moz),d.setProperty("-o-"+e,f.o),d.setProperty("-ms-"+e,f.ms)}function m(a){return{webkit:"-webkit-"+a,moz:"-moz-"+a,o:"-ms-"+a,ms:"-o-"+a,normal:a}}function n(a,b){var c,d,e=m(b);for(d in e)if(e.hasOwnProperty(d)&&(c=a[e[d]],c&&"none"!==c))break;return c}function o(a){var b="",c=t.parseProperty(a);return c&&2===c.length&&(b="width: "+c[0]+"px; height: "+c[1]+"px;"),b}function p(a,c,d){var e,f,g,h=[];r||(e=b.head||b.getElementsByTagName("head")[0],f=b.createElement("style"),f.type="text/css",e.appendChild(f),r=f.sheet);for(g in d)d.hasOwnProperty(g)&&h.push(g+": "+d[g]);return h.length?r.addRule(a+"::"+c,h.join("; ")):null}function q(a){r&&r.deleteRule(a)}var r,s=c.util.DOM,t=c.util.string;s.getCSSProperty=d,s.extractCSSProperties=f,s.getElementHeight=h,s.getElementWidth=i,s.getElementOffset=j,s.isOccupiedPlace=k,s.setPrefixedStyle=l,s.getPrefixedValue=m,s.getPrefixedStyleValue=n,s.toCSSSize=o,s.setStylesForPseudoClass=p,s.removeCSSRule=q}(a,d),function(a,b){var c=function(){this._data=[]};c.prototype={add:function(){var a=this._data;this._data=a.concat.apply(a,[].slice.call(arguments)).filter(function(a,b,c){return c.indexOf(a)===b})},clear:function(){this._data=[]},"delete":function(a){var b=this._data,c=b.indexOf(a);c>-1&&b.splice(c,1)},has:function(a){return this._data.indexOf(a)>-1},forEach:function(a){this._data.forEach(a)}},b.util._Set=c,b.util.Set=a.Set||c}(a,d),function(a){function b(a,b,c){var d={name:a,element:b,options:c};return d}function c(a,c,d){var e=b(a,c,d);return g.instanceWidget(e.element,e.name,e.options)}function e(a){var b=a.detail,e=b.name;d.widget[e]=c.bind(null,e)}function f(){a.removeEventListener(h.WIDGET_DEFINED,e,!0),a.removeEventListener(h.DESTROY,f,!1)}var g=d.engine,h=g.eventType,i={getInstance:g.getBinding,getAllInstances:g.getAllBindings};a.addEventListener(h.WIDGET_DEFINED,e,!0),a.addEventListener(h.DESTROY,f,!1),d.widget=i}(a.document),function(a,b){function d(a){return!a.toRemove}function e(a){a.object[a.property]===a.value&&(n.requestAnimationFrame(a.callback.bind(a.object)),a.toRemove=!0)}function f(){j.forEach(e),j=j.filter(d),j.length&&n.requestAnimationFrame(f)}function g(a,b){var d=b.classList;d!==c&&(d instanceof t?d.clear():(d=new t,b.classList=d),a.classList.length&&k.call(a.classList).forEach(function(a){d.add(a)}))}function h(a,b){g(a,b),b.offsetWidth!==c&&(b.offsetWidth=a.offsetWidth),b.style!==c&&p.extractCSSProperties(a,b.style,null,!0),b.children!==c&&b.children.forEach(function(b,c){h(a.children[c],b)})}function i(a,b,d){var e=!1;
+a.classList!==c&&(k.call(b.classList).forEach(function(c){a.classList.has(c)||(b.classList.remove(c),e=!0)}),a.classList.forEach(function(a){b.classList.contains(a)||(b.classList.add(a),e=!0)})),a.style!==c&&Object.keys(a.style).forEach(function(c){b.style[c]=a.style[c]}),a.children!==c&&a.children.forEach(function(a,c){i(a,b.children[c],!0)}),e&&!d&&n.requestAnimationFrame(h.bind(null,b,a))}var j,k=[].slice,l=b.engine,m=l.dataTau,n=b.util,o=b.event,p=n.DOM,q=n.string,r=n.object,s=n.selectors,t=n.Set,u=function(){return this.flowState="created",this},v=p.getNSData,w={},x="function",y="string",z=",",A="ui-state-disabled",B="aria-disabled",C={INLINE:"ui-inline"};u.classes={disable:A},w._configureDefinition=function(a){var c,d,e=this;a&&(c=a.name,d=a.namespace,e.name=c,e.widgetName=c,e.widgetEventPrefix=c.toLowerCase(),e.namespace=d,e.widgetFullName=((d?d+"-":"")+c).toLowerCase(),e.id=b.getUniqueId(),e.selector=a.selector)},w.configure=function(a,b,c){var d=this;return d.flowState="configuring",d.options=d.options||{},d.element=d.element||null,d._configureDefinition(a),typeof d._configure===x&&(b=d._configure(b)||b),d.isCustomElement=!!b.createdCallback,d._getCreateOptions(b),r.fastMerge(d.options,c),b.style.cssText&&(b.dataset.originalStyle=b.style.cssText),d.flowState="configured",b},w._getCreateOptions=function(a){var b,c=this,d=c.options,e=a.localName.toLowerCase();return d&&Object.keys(d).forEach(function(f){var g=q.camelCaseToDashes(f),h=v(a,g,!0),i=v(a,g);null!==i?("number"==typeof d[f]?i=parseFloat(i):"object"==typeof d[f]&&"string"==typeof i&&Array.isArray(d[f])&&(b=a.dataset.delimiter||z,i=i.split(b)),d[f]=i):"boolean"==typeof d[f]&&(c._readCommonOptionFromElementClassname(a,f)||c._readPrefixedOptionFromElementClassname(a,f)||(typeof c._readWidgetSpecyficOptionFromElementClassname!==x||typeof c._readWidgetSpecyficOptionFromElementClassname===x&&!c._readWidgetSpecyficOptionFromElementClassname(a,f))&&typeof c._getDefaultOption===x&&(d[f]=c._getDefaultOption(f))),"type"===f&&"input"===e||"style"===f||null!==h&&("number"==typeof d[f]&&(h=parseFloat(h)),d[f]=h)}),d},w.build=function(a){var b,c,d=this,e=a.getAttribute(m.built),f=a.getAttribute(m.name);return o.trigger(a,d.widgetEventPrefix+"beforecreate"),d.flowState="building",b=a.id,b?d.id=b:a.id=d.id,c=typeof d._build===x?d._build(a):a,d._setBooleanOptions(a),e=e?e+m.separator+d.name:d.name,f=f?f+m.separator+d.name:d.name,a.setAttribute(m.built,e),a.setAttribute(m.name,f),d.flowState="built",c},w.init=function(a){var b,c,d=this;return d.id=a.id,d.flowState="initiating",a.dataset.originalStyle&&(b=d.getContainer(),b!=a&&(c=a.dataset.originalStyle,c.split(";").forEach(function(c){var d,e,f;f=c.split(":"),2===f.length&&(d=f[0].trim(),e=f[1].trim(),b.style[d]=a.style[d],a.style[d]===e&&(a.style[d]=""))}))),typeof d._init===x&&d._init(a),a.hasAttribute("disabled")&&"false"!==a.getAttribute("disabled")||d.options.disabled===!0?d.disable():d.enable(),d.flowState="initiated",d},w.getContainer=function(){var a=this;return typeof a._getContainer===x?a._getContainer():a.element},w.bindEvents=function(a,b){var c=this,d=a.getAttribute(m.bound);return b||(d=d?d+m.separator+c.name:c.name,a.setAttribute(m.bound,d)),typeof c._buildBindEvents===x&&c._buildBindEvents(a),b||typeof c._bindEvents!==x||c._bindEvents(a),c.trigger(c.widgetEventPrefix+"create",c),c},w.focus=function(b){var c,d,e,f,g=this,h=g.element;return b=b||{},c=b.previousElement,c&&(f=l.getBinding(c),f?(b=r.merge({},b,{element:c}),f.blur(b)):c.blur()),b=r.merge({},b,{element:h}),e=s.getClosestBySelector(h,"[data-tau-name='Scrollview']"),e&&(d=l.getBinding(e)),o.trigger(a,"taufocus",b),typeof g._focus===x?(b.event&&d&&d.ensureElementIsVisible(h),g._focus(h)):h.focus(),!0},w.blur=function(b){var c=this,d=c.element;return b=r.merge({},b,{element:d}),o.trigger(a,"taublur",b),typeof c._blur===x?c._blur(d):d.blur(),!0},w.destroy=function(a){var b=this;a=a||b.element,b.flowState="destroying",typeof b._destroy===x&&b._destroy(a),b.element&&(b.trigger(b.widgetEventPrefix+"destroy"),b.element.dataset.originalStyle&&(b.element.style.cssText=b.element.dataset.originalStyle,delete b.element.dataset.originalStyle)),a&&l.removeBinding(a,b.name),b.flowState="destroyed"},w.disable=function(){var a=this,b=k.call(arguments),c=a.element;return c.classList.add(A),c.setAttribute(B,!0),typeof a._disable===x&&(b.unshift(c),a._disable.apply(a,b)),this},w.isDisabled=function(){var a=this;return a.element.getAttribute("disabled")||a.options.disabled===!0},w.enable=function(){var a=this,b=k.call(arguments),c=a.element;return c.classList.remove(A),c.setAttribute(B,!1),typeof a._enable===x&&(b.unshift(c),a._enable.apply(a,b)),this},w.refresh=function(){var a=this,b=a.element;return a._getCreateOptions(b),typeof a._refresh===x&&a._refresh.apply(a,arguments),a},w._readPrefixedOptionFromElementClassname=function(a,b){var c,d=this._classesPrefix;return d&&(c=d+q.camelCaseToDashes(b),a.classList.contains(c))?(this.options[b]=a.classList.contains(c),!0):!1},w._readCommonOptionFromElementClassname=function(a,b){var c=this.options,d=a.classList;switch(b){case"inline":if(d.contains(C.INLINE))return c.inline=!0,!0}return!1},w._setBooleanOption=function(a,b,c){var d,e=this._classesPrefix;return e&&(d=e+q.camelCaseToDashes(b),a.classList.toggle(d,c)),!1},w._setBooleanOptions=function(a){var b=this,d=b._classesPrefix,e=b.options;return d&&e!==c&&Object.keys(e).forEach(function(c){"boolean"==typeof e[c]&&(e[c]=b._setBooleanOption(a,c,e[c]))}),e},w._processOptionObject=function(a){var b,d,e=this,f=!1;for(b in a)a.hasOwnProperty(b)&&(d=e._oneOption(b,a[b]),b!==c&&a[b]!==c&&(f=f||d));return f},w.option=function(a,b){var d=this,e=a,f=b,g=null,h=!1;return"string"==typeof e?(g=d._oneOption(e,f),f!==c&&(h=g,g=null)):"object"==typeof e&&(h=d._processOptionObject(e)),h&&d.refresh(),g},w._oneOption=function(a,b){var d,e=this,f=!1;return b===c?(d="_get"+(a[0].toUpperCase()+a.slice(1)),typeof e[d]===x?e[d]():e.options[a]):(d="_set"+(a[0].toUpperCase()+a.slice(1)),typeof e[d]===x?(f=e[d](e.element,b),e.element&&("object"!=typeof b||Array.isArray(b))&&e.element.setAttribute("data-"+a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()}),b)):"boolean"==typeof b?f=e._setBooleanOption(e.element,a,b):(e.options[a]=b,e.element&&("object"!=typeof b||Array.isArray(b))&&(e.element.setAttribute("data-"+a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()}),b),f=!0)),""===b&&e.element&&e.element.removeAttribute("data-"+a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()})),f)},w.isBound=function(a){var b=this.element;return a=a||this.name,b&&b.hasAttribute(m.bound)&&b.getAttribute(m.bound).indexOf(a)>-1},w.isBuilt=function(a){var b=this.element;return a=a||this.name,b&&b.hasAttribute(m.built)&&b.getAttribute(m.built).indexOf(a)>-1},w.value=function(a){var b=this;return a!==c?typeof b._setValue===x?b._setValue(a):b:typeof b._getValue===x?b._getValue():b},w.trigger=function(a,b,c,d){return this.element?o.trigger(this.element,a,b,c,d):!1},w.on=function(a,b,c){o.on(this.element,a,b,c)},w.off=function(a,b,c){o.off(this.element,a,b,c)},w._framesFlow=function(){var a=this,b=k.call(arguments),d=b.shift();"function"==typeof d&&d(),d!==c&&n.requestAnimationFrame(function(){a._framesFlow.apply(a,b)})},w._waitFor=function(a,b,c){var d=this;d[a]===b?c.call(d):(j=j||[],j.push({object:d,property:a,value:b,callback:c})),f()},w._render=function(a){var b=this,c=b._stateDOM,d=b.element;a===!0?i(c,d,!1):n.requestAnimationFrame(i.bind(null,c,d,!1))},w._initDOMstate=function(){h(this.element,this._stateDOM)},w._togglePrefixedClass=function(a,b,c){var d=!1,e=b+c;return a.classList.forEach(function(c){0===c.indexOf(b)&&e!==c&&(a.classList["delete"](c),d=!0)}),a.classList.has(e)||(a.classList.add(e),d=!0),d},w._createWrapper=function(b){var c;return b=typeof b===y?b:"div",c=a.createElement(b),c.setAttribute(m.widgetWrapper,!0),c},u.prototype=w,b.widget.BaseWidget=u}(a.document,d),function(a,b){function e(b,d,e,f){var g=null;return function(){var h,j,l,m,n,o,p=i.call(arguments),q={};for(o=0;o<this.length;o++){switch(h=this.get(o),d){case"slider":g=b.getBinding(h,"Slider")||b.getBinding(h,"TizenSlider");break;default:g=b.getBinding(h,f)}if(j=g&&g.isBuilt(),n=p.shift(),n===c||"object"==typeof n)"object"==typeof n&&(q=n),g&&j?g.option(q):b.instanceWidget(h,f,q);else{if(null===g)return this;if(l=n,"destroy"===l)return g.destroy(),this;if(e.indexOf(l)<0)throw"Method "+l+" does not exist!";if("listview"===d&&"option"===l&&"autodividersSelector"===p[0]&&"function"==typeof p[1]&&(p[1]=k(p[1])),"popup"===d&&"open"===l&&(p[1]=a.event),m=g[l].apply(g,p),m!==c&&m!==g)return m}}return this}}function f(a){n.init(l,a.detail)}function g(){b.removeEventListener(o.WIDGET_DEFINED,f,!1),b.removeEventListener(o.INIT,h,!1),b.removeEventListener(o.DESTROY,g,!1)}function h(){l.defineWidget("FixedToolbar","",[],d.widget.Page,"mobile"),l.defineWidget("pagelayout","",[],d.widget.Page,"mobile"),l.defineWidget("popupwindow","",[],d.widget.Popup,"tizen"),l.defineWidget("ctxpopup","",[],d.widget.Popup,"tizen")}var i=[].slice,j=d.jqm.jQuery,k=function(a){return function(b){return a(j(b))}},l=d.engine,m=d.util.object,n={init:function(a,c){var d=c.widgetNameToLowercase?c.name.toLowerCase():c.name;j&&(b.addEventListener(d+"create",function(a){var b=a.target,c=a.detail,e=j(b).data(d);c&&(c.bindings={},c.hoverable={},c.focusable={},c.document=j(b.style?b.ownerDocument:b.document||b),c.window=j(c.document[0].defaultView||c.document[0].parentWindow),m.merge(c,e),j(b).data(d,c))},!0),this.processDefinition(c,a))},processDefinition:function(a,b){var c=a.widgetNameToLowercase?a.name.toLowerCase():a.name,d=a.methods;j.fn[c]=e(b,c,d,a.name),a.namespace&&(j[a.namespace]=j[a.namespace]||{},j[a.namespace][a.name.toLowerCase()]=a.widgetClass),a=null}},o=l.eventType;b.addEventListener(o.WIDGET_DEFINED,f,!1),b.addEventListener(o.INIT,h,!1),b.addEventListener(o.DESTROY,g,!1),d.jqm.widget=n}(a,a.document),function(a,b,d){d.util.callbacks=function(a){var b,e,f,g,h,i,j,k,l=d.util.object,m=l.copy(a),n=[].slice,o=[],p=!m.once&&[],q={add:function(){var a;return o&&(a=o.length,k(arguments),f?h=o.length:b&&(g=a,j(b))),this},remove:function(){return o&&n.call(arguments).forEach(function(a){for(var b=o.indexOf(a);b>-1;)o.splice(b,1),f&&(h>=b&&h--,i>=b&&i--),b=o.indexOf(a,b)}),this},has:function(a){return a?!!o&&o.indexOf(a)>-1:!(!o||!o.length)},empty:function(){return o=[],h=0,this},disable:function(){return o=p=b=c,this},disabled:function(){return!o},lock:function(){return p=c,b||q.disable(),this},locked:function(){return!p},fireWith:function(a,b){return!o||e&&!p||(b=b||[],b=[a,b.slice?b.slice():b],f?p.push(b):j(b)),this},fire:function(){return q.fireWith(this,arguments),this},fired:function(){return!!e}};return k=function(a){n.call(a).forEach(function(a){var b=typeof a;"function"===b?m.unique&&q.has(a)||o.push(a):a&&a.length&&"string"!==b&&k(a)})},j=function(a){for(b=m.memory&&a,e=!0,i=g||0,g=0,h=o.length,f=!0;o&&h>i;){if(o[i].apply(a[0],a[1])===!1&&m.stopOnFalse){b=!1;break}i++}f=!1,o&&(p?p.length&&j(p.shift()):b?o=[]:q.disable())},q}}(a,a.document,d),function(a,b,c){var d=function(a){var b=c.util.callbacks,e=c.util.object,f=[["resolve","done",b({once:!0,memory:!0}),"resolved"],["reject","fail",b({once:!0,memory:!0}),"rejected"],["notify","progress",b({memory:!0})]],g="pending",h={},i={state:function(){return g},always:function(){return h.done(arguments).fail(arguments),this},then:function(){var a=arguments;return new d(function(b){f.forEach(function(c,d){var e="function"==typeof a[d]&&a[d];h[c[1]](function(){var a=e&&e.apply(this,arguments);a&&"function"==typeof a.promise?a.promise().done(b.resolve).fail(b.reject).progress(b.notify):b[c[0]+"With"](this===i?b.promise():this,e?[a]:arguments)})}),a=null}).promise()},promise:function(a){return a?e.merge(a,i):i}};return i.pipe=i.then,f.forEach(function(a,b){var c=a[2],d=a[3];i[a[1]]=c.add,d&&c.add(function(){g=d},f[1^b][2].disable,f[2][2].lock),h[a[0]]=function(){return h[a[0]+"With"](this===h?i:this,arguments),this},h[a[0]+"With"]=c.fireWith}),i.promise(h),a&&a.call(h,h),h};c.util.deferred=d}(a,a.document,d),function(a,b,c,d){function e(a){return a.filter(function(a){return a}).join("/")}function f(c){var d,e=c||b.getElementsByTagName("html")[0].getAttribute("lang")||a.navigator.language.split(".")[0]||"en",f=e.lastIndexOf("-"),h=["Cyrl","Latn","Mong"];return-1!==f&&(d=e.substr(f+1),h.join("-").indexOf(d)<0&&(e=[e.substr(0,f),d.toUpperCase()].join("-"))),e=g(e)}function g(a){var b,c=a.lastIndexOf("-");return b=-1!==c?a.substr(0,c):a}function h(a,b,c){var d;return b="supplemental"===a?null:b,d=[C,B,a,b,c+A],e(d)}function i(a){return e([D,a+A])}function j(a){var b,c,d,e=new x;if(a)try{b=new XMLHttpRequest,b.onreadystatechange=function(){if(4===b.readyState)switch(b.status){case 0:case 200:c=JSON.parse(b.responseText),d={state:b.status,path:a,data:c},e.resolve(d);break;case 404:d={state:b.status,path:a,data:null},e.reject(d);break;default:c=JSON.parse(b.responseText),d={state:b.status,path:a,data:c},e.reject(d)}},b.open("GET",a,!0),b.send("")}catch(f){d={state:-1,path:a,data:null},e.reject(d)}else d={state:-2,path:a,data:null},e.reject(d);return e}function k(a,b){var c,e=w[b].length,f=null,g=new x;return f=a?u[b].hasOwnProperty(a)?u[b][a]:u[b][a]={}:u[b],w[b].forEach(function(i){c=h(b,a,i),f[c]?g.resolve(a):j(c).then(function(b){var c=b.data,h=b.path;f[h]=c,d.load(c),Object.keys(f).length===e&&g.resolve(a)},g.reject)}),g}function l(a){var b=null,c=new x,d=v;return b=i(a),d[b]?(d[b].fromCache=!0,c.resolve(d[b])):j(b).then(function(a){d[b]=a,a.fromCache=!1,c.resolve(a)},c.reject),c}function m(){var a=new x;return s=!0,k(null,t.supplemental).then(a.resolve,a.reject),a}function n(a){var b=h(t.supplemental,a,w.supplemental[0]),c=u.supplemental[b]||null,e=null;if(a=d.locale().attributes.script,c)return c.some(function(b){if(b.IDENTIFIER===a){switch(b.RTL){case"YES":e=!0;break;case"NO":e=!1;break;case"UNKNOWN":e=!0}return!0}return!1}),e;throw new Error("Globalize is not initialized")}function o(b){var c=new x;return s?a.tizen&&!b?a.tizen.systeminfo.getPropertyValue("LOCALE",function(a){var b=a.country;b&&(b=g(b.replace("_","-"))),k(b,t.main).then(function(a){c.resolve(a)},c.reject)}):k(b,t.main).then(function(a){c.resolve(a)},c.reject):m().then(function(){o(b).then(function(a){c.resolve(a)},c.reject)}),c}function p(){var a=n(d.locale().locale),c=b.body,e=c.classList;a?(e.contains(z)||e.add(z),d.prototype.rtl=!0):(e.contains(z)&&e.remove(z),d.prototype.rtl=!1)}function q(){d.prototype.getLocale=c.util.globalize.getLocale,d.prototype.getCalendar=c.util.globalize.getCalendar}function r(){return a.Globalize&&a.Cldr}var s=!1,t={main:"main",supplemental:"supplemental"},u={main:{},supplemental:{}},v={},w={main:["currencies","ca-gregorian","numbers"],supplemental:["scriptMetaData","likelySubtags","currencyData","plurals","timeData","weekData","numberingSystems"]},x=c.util.deferred,y=null,z="ui-script-direction-rtl",A=".json",B="cldr-data",C="lib",D="locale";c.util.globalize={importModule:function(a){var b,c=a.split("/"),d=c.shift(),e=w.main,f=w.supplemental,g=0;switch(a=c.shift(),d){case"main":for(b=e.length;b>g;g++)if(e[g]===a)return;e.push(a);break;case"supplemental":for(b=f.length;b>g;g++)if(f[g]===a)return;f.push(a)}},setLocale:function(a){var b=new x;if(a=f(a),r())return o(a).then(function(a){return d.locale(a),y=new d(a),a},b.reject).done(function(a){l(a).then(function(c){c.fromCache||d.loadMessages(c.data),y=new d(a),b.resolve(y)},function(){y=new d(a),b.resolve(y)})}).done(p).done(q),b;throw new Error("Globalize is not loaded")},getLocale:function(){if(r())return d.locale().locale;throw new Error("Globalize is not loaded")},getCalendar:function(){if(r()&&y)return y.cldr.main("dates/calendars/gregorian");throw new Error("Globalize is not initialized")}}}(a,a.document,d,a.Globalize),function(a,b,c){var d=b.querySelector("meta[name=viewport]"),e=d&&d.getAttribute("content"),f=e+",maximum-scale=1, user-scalable=no",g=e+",maximum-scale=10, user-scalable=yes",h=/(user-scalable[\s]*=[\s]*no)|(maximum-scale[\s]*=[\s]*1)[$,\s]/.test(e),i={enabled:!h,locked:!1,disable:function(a){h||i.locked||(d&&d.setAttribute("content",f),i.enabled=!1,i.locked=a||!1)},enable:function(a){h||i.locked&&a!==!0||(d&&d.setAttribute("content",g),i.enabled=!0,i.locked=!1)},restore:function(){h||(d&&d.setAttribute("content",e),i.enabled=!0)}};c.util.zoom=i}(a,a.document,d),function(a,b){function c(a,b,c){var d=new XMLHttpRequest;d.open("GET",a,!1),d.send(),200===d.status||0===d.status?"function"==typeof b&&b(d,d.status):"function"==typeof c&&c(d,d.status,new Error(d.statusText))}function d(a,b,c){var d,e=new XMLHttpRequest,f=function(){if(200===e.status){if("function"==typeof b)try{d=JSON.parse(e.responseText),b(d,e.status)}catch(a){c(e,e.status,new Error(a))}}else"function"==typeof c&&c(e,e.status,new Error(e.statusText))},g=function(){4===e.status&&f()};e.open("GET",a,!0),e.onreadystatechange=g,e.onload=f,e.onerror=function(a){c(e,e.status,new Error(a))},e.send()}function e(b,c,d){var e=a.createElement("script");e.type="text/javascript",e.text=c.responseText,a.body.appendChild(e),"function"==typeof b&&b(c,d)}function f(a,b,d){c(a,e.bind(null,b),d)}function g(b,c,d){var e=a.createElement("style"),f=b.replace(x,"");e.type="text/css",e.textContent=d.responseText.replace(v,"url("+f+"$1)"),"function"==typeof c&&c(e)}function h(b,c,d){var e=a.createElement("style");e.type="text/css",e.textContent=d.responseText.replace(u,"url("+b.replace(w,"images")),"function"==typeof c&&c(e)}function i(a,b,d){c(a,g.bind(null,a,b),d)}function j(a,b,d){c(a,h.bind(null,a,b),d)}function k(a,b){var c;if(o){if(b&&(c=o.firstElementChild))return void o.insertBefore(a,c);o.appendChild(a)}}function l(b){var c=a.createElement("link");return c.setAttribute("rel","stylesheet"),c.setAttribute("href",b),c.setAttribute("name","tizen-theme"),c}function m(a,b,c){s(a,"name","tizen-theme"),s(a,"theme-name",b),c?c.parentNode.replaceChild(a,c):k(a,!0)}function n(a,c,d){var e,f,g,h=p.length,i=null;for(e=0;h>e;e++)if(f=p[e].ownerNode,"tizen-theme"===r(f,"name")||f.getAttribute("href")===a){if(r(f,"theme-name")===c)return;i=f;break}d?j(a,function(a){m(a,c,i)},function(a,d){b.warn("There was a problem when loading '"+c+"', status: "+d)}):(g=l(a),m(g,c,i))}var o=a.head,p=a.styleSheets,q=b.util.DOM,r=q.getNSData,s=q.setNSData,t=b.util.load||{},u=/url\((\.\/)?images/gm,v=/url\((.+)\)/gm,w=/[^/]+\.css$/,x=/[^\/]+$/;t.cacheBust=a.location.href.match(/debug=true/)?"?cacheBust="+(new Date).getTime():"",t.scriptSync=f,t.addElementToHead=k,t.makeLink=l,t.themeCSS=n,t.cssSync=i,t.JSON=d,b.util.load=t}(a.document,d),function(a,b){var c=Array.prototype.slice,d="tizen-web-ui-fw",e="tau",f=/(^|[\\\/])(tau(\.full|\.mvc)?(\.min)?\.js)$/,g=/(^|[\\\/])(tau|tizen-web-ui-fw)(\.full|\.mvc|\.custom)?(\.min)?\.js$/,h=/(^|[\\\/])(tau|tizen-web-ui-fw)(\.full|\.mvc|\.custom)?(\.min)?\.css$/,i=/^(changeable|white|black|default)$/i,j=/\.min\.js$/,k={frameworkName:d,rootDir:"/usr/share/"+d,version:"latest",theme:"default",themeLoaded:!1,defaultViewportWidth:360,viewportWidth:"device-width",viewportScale:!1,defaultFontSize:22,minified:!1,deviceCapa:{inputKeyBack:!0,inputKeyMenu:!0},debug:!1,pkgVersion:"0.2.83",dataPrefix:"data-framework-",profile:""};k.getParams=function(){function b(a){var b,c=a.ownerNode,d=c.getAttribute("data-theme-name"),e=c.getAttribute("href"),f=e&&e.split("/");d?i.test(d)&&(l=d):e&&h.test(e)&&f.length>=2&&(b=f.slice(-2)[0].match(i),l=b&&b[0]),q=q||!!l}function k(a){var b,c,h,i=a.getAttribute("src"),k="";g.test(i)&&(l=l||a.getAttribute(n+"theme")||m.theme,l=l.toLowerCase(),f.test(i)?(b=e,k=a.getAttribute(n+"profile")||i.split("/").slice(-3)[0],c="/"+k+"/theme/"+l,h="/"+k+"/js"):(b=d,c="/latest/themes/"+l,h="/latest/js"),m.rootDir=a.getAttribute(n+"root")||i.substring(0,i.lastIndexOf(b)-h.length-1)||m.rootDir,m.themePath=m.rootDir+c,m.jsPath=m.rootDir+h,m.version=a.getAttribute(n+"version")||m.version,m.theme=l,m.themeLoaded=q,m.frameworkName=b,m.minified=i.search(j)>-1,m.profile=k)}var l,m=this,n=m.dataPrefix,o=c.call(a.querySelectorAll("script[src]")),p=c.call(a.styleSheets),q=!1;p.forEach(b),o.forEach(k)},b.frameworkData=k,b.frameworkData.getParams()}(a.document,d),function(a,b){function e(a,b,c,d){var e=f.call(a).map(b);c[d].apply(c,e)}var f=[].slice,g={},h=d.jqm.jQuery,i=d.util,j=i.zoom,k=d.event,l=i.load,m=i.object,n=function(a){return"object"==typeof a&&a.selector&&a.get?1===a.length?a.get(0):a.toArray():a},o=d.engine,p=o.eventType,q=function(){var f,p,q,r,s,t=Object.keys(o),u=/:jqmData\(([^)]*)\)/g,v=":jqmData";if(h){for(f=0,p=t.length;p>f;++f)q=t[f],h[q]=e.bind(null,arguments,n,o,q);m.merge(h.mobile,{ns:"",nsNormalize:function(a){return a?(g[a]=g[a]||h.camelCase(h.mobile.ns+a),g[a]):null},activeBtnClass:d.widget.core.Button.classes.uiBtnActive,activePageClass:d.widget.core.Page.classes.uiPageActive,focusClass:d.widget.core.Button.classes.uiFocus,version:"1.2.0",getAttrFixed:function(a,b){var d=a.getAttribute(b);return"true"===d?!0:"false"===d?!1:null===d?c:d},path:d.util.path,back:a.history.back.bind(a.history),silentScroll:function(d){d===c&&(d=h.mobile.defaultHomeScroll),setTimeout(function(){a.scrollTo(0,d),k.trigger(b,"silentscroll",{x:0,y:d})},20),setTimeout(function(){},150)},nsNormalizeDict:g,closestPageData:function(a){var b=d.util.selectors.getClosestBySelector(h(a)[0],"[data-"+(h.mobile.ns||"")+"role='page'], [data-"+(h.mobile.ns||"")+"role='dialog']");return d.engine.instanceWidget(b,"Page")},enhanceable:function(a){return this.haveParents(a,"enhance")},hijackable:function(a){return this.haveParents(a,"ajax")},haveParents:function(a,b){var c,d,e,f,g,i=0,j=null;if(!h.mobile.ignoreContentEnabled)return a;for(i=a.length,j=h(),f=0;i>f;f++){for(d=a.eq(f),e=!1,c=a[f];c;){if(g=c.getAttribute?c.getAttribute("data-"+h.mobile.ns+b):"","false"===g){e=!0;break}c=c.parentNode}e||(j=j.add(d))}return j},getScreenHeight:function(){return a.innerHeight},widget:function(){return null},media:d.support.media,browser:{},gradeA:function(){return null},zoom:j,popupwindow:{}}),h.mobile.buttonMarkup=h.mobile.buttonMarkup||d.widget.mobile.Button,h.mobile.$window=h(a),h.mobile.$document=h(b),h.mobile.keyCode={ALT:18,BACKSPACE:8,CAPS_LOCK:20,COMMA:188,COMMAND:91,COMMAND_LEFT:91,COMMAND_RIGHT:93,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,MENU:93,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38,WINDOWS:91},h.tizen=h.tizen||{},s=h.tizen,s.globalize=d.util.globalize,h.mobile.tizen=m.merge(h.mobile.tizen,{_widgetPrototypes:{},disableSelection:function(){d.warn("Function $.mobile.tizen.disableSelection is deprecated")},enableSelection:function(){d.warn("Function $.mobile.tizen.enableSelection is deprecated")},enableContextMenu:function(){d.warn("Function $.mobile.tizen.enableContextMenu is deprecated")},disableContextMenu:function(){d.warn("Function $.mobile.tizen.disableContextMenu is deprecated")}}),h.mobile.tizen.loadPrototype=null,h.fn.jqmData=function(a,b){var d;return a!==c&&(a&&(a=h.mobile.nsNormalize(a)),d=arguments.length<2||b===c?this.data(a):this.data(a,b)),d},h.fn.jqmRemoveData=function(a){return a!==c&&(a&&(a=h.mobile.nsNormalize(a)),this.removeData(a)),this},h.jqmData=function(a,b,c){var d=h(a).jqmData(b,c);return c||d},h.jqmRemoveData=function(a,b){h(a).jqmRemoveData(b)},h.fn.removeWithDependents=function(){h.removeWithDependents(this)},h.removeWithDependents=function(a){var b=h(a);(b.jqmData("dependents")||h()).remove(),b.remove()},h.fn.addDependents=function(a){h.addDependents(h(this),a)},h.addDependents=function(a,b){var c=h(a).jqmData("dependents")||h();h(a).jqmData("dependents",h.merge(c,b))},h.fn.getEncodedText=function(){return h("<div/>").text(h(this).text()).html()},h.fn.jqmEnhanceable=function(){return h.mobile.enhanceable(this)},h.fn.jqmHijackable=function(){return h.mobile.hijackable(this)},r=h.find,h.find=function(a,b,c,d){return a.indexOf(v)>-1&&(a=a.replace(u,"[data-"+(h.mobile.ns||"")+"$1]")),r.call(this,a,b,c,d)},h.extend(h.find,r),h.find.matches=function(a,b){return h.find(a,null,null,b)},h.find.matchesSelector=function(a,b){return h.find(b,null,null,[a]).length>0},h(b).bind("create",d.engine._createEventHandler),h(b).bind("pagecreate",function(a){var b,c=a.originalEvent||a,e=c.detail instanceof d.widget.core.Page;e||(b=o.instanceWidget(c.target,"Page"),b.refresh(),d.engine._createEventHandler(c))}),h(b).bind("activePopup",function(a){h.mobile.popup.active=h.mobile.popupwindow.active=a.originalEvent.detail}),h.tizen.frameworkData=d.frameworkData,h.tizen.__tizen__=s,s.libFileName="tizen-web-ui-fw(.custom|.full)?(.min)?.js",s.log={debug:function(a){h.tizen.frameworkData.debug&&d.log(a)},warn:d.warn.bind(d),error:d.error.bind(d),alert:a.alert.bind(a)},s.util={loadScriptSync:l.scriptSync,isMobileBrowser:function(){d.warn("Function $.tizen.__tizen__.util.isMobileBrowser is deprecated")}},s.css={cacheBust:l.cacheBust,addElementToHead:l.addElementToHead.bind(l),makeLink:l.makeLink.bind(l),load:l.themeCSS},s.loadTheme=function(){d.warn("Function $.tizen.__tizen__.loadTheme is deprecated")},s.setLocale=i.globalize.setLocale,s.setViewport=function(){d.warn("Function $.tizen.__tizen__.setViewport is deprecated")},s.scaleBaseFontSize=function(){d.warn("Function $.tizen.__tizen__.scaleBaseFontSize is deprecated")},s.setScaling=function(){d.warn("Function $.tizen.__tizen__.setScaling is deprecated")},s.getParams=d.frameworkData.getParams.bind(d.frameworkData),d.setConfig("enableHWKeyHandler",h.mobile.tizen.enableHWKeyHandler)}},r=function(){b.removeEventListener(p.INIT,q,!1),b.removeEventListener(p.DESTROY,r,!1)};b.addEventListener(p.INIT,q,!1),b.addEventListener(p.DESTROY,r,!1)}(a,a.document),function(a,b,d){function e(a,b,c,d){var e,f,g,h;for(e=0,f=d.length;f>e;++e)h=d[e],(isNaN(c[h])===!1||isNaN(a[h])===!1)&&(g=Object.getOwnPropertyDescriptor(b,h),"detail"===h||g&&!g.writable||(b[h]=c[h]||a[h]))}function f(a,b,c){var d,f,g,h,i=new CustomEvent(a,{bubbles:b.bubbles,cancelable:b.cancelable,detail:b.detail}),j=b.type,k=0;if(e(b,i,c,x),i._originalEvent=b,-1!==j.indexOf("touch")&&(j=b.touches,d=b.changedTouches,f=j&&j.length?j[0]:d&&d.length?d[0]:null))for(g=D.length;g>k;k++)h=D[k],i[h]=f[h];return i}function g(a,b,c){return b.target.dispatchEvent(f(a,b,c||{}))}function h(a){g("vmousedown",a)}function i(a){var b=a.clientX,c=a.clientY;return b||c?null:t(a)}function j(a){g("vclick",a,i(a))}function k(a){g("vmouseup",a)}function l(a){g("vmousemove",a)}function m(a){g("vmouseover",a)}function n(a){g("vmouseout",a)}function o(a){var b,c=a.touches;c&&1===c.length&&(y=!1,b=c[0],B=b.pageX||b.clientX||0,C=b.pageY||b.clientX||0,g("vmousedown",a))}function p(a){var b=a.touches;b&&0===b.length&&(g("vmouseup",a),g("vmouseout",a),A=null)}function q(a){var d,e,f,h=a.touches&&a.touches[0],i=y,j=w.eventDistanceThreshold;return h===c||h.identifier>0?void a.stopPropagation():(e=h.pageX||h.clientX||0,f=h.pageY||h.clientY||0,y=y||Math.abs(e-B)>j||Math.abs(f-C)>j,d=b.elementFromPoint(e,f),d&&A!==d&&(A=d,g("vmouseover",a)),y&&!i&&(g("vmousecancel",a),A=null),void g("vmousemove",a))}function r(a){y||g("vmousecancel",a),y=!0}function s(a){g("vmousecancel",a),A=null}function t(a){var b=a.target&&a.target.getBoundingClientRect(),c={};return b&&(c={clientX:b.left+b.width/2,clientY:b.top+b.height/2,which:1}),c}function u(a){var b;a.keyCode===E.enter&&(b=t(a),g("vmouseup",a,b),g("vclick",a,b))}function v(a){a.keyCode===E.enter&&g("vmousedown",a,t(a))}var w,x,y,z=a.hasOwnProperty("ontouchstart"),A=null,B=0,C=0,D=["clientX","clientY","pageX","pageY","screenX","screenY"],E={enter:13};x=["currentTarget","detail","button","buttons","clientX","clientY","offsetX","offsetY","pageX","pageY","screenX","screenY","toElement","which"],w={eventDistanceThreshold:10,touchSupport:z},w.bindCommonEvents=function(){b.addEventListener("keyup",u,!0),b.addEventListener("keydown",v,!0),b.addEventListener("scroll",r,!0),b.addEventListener("click",j,!0)},w.bindTouch=function(){b.addEventListener("touchstart",o,!0),b.addEventListener("touchend",p,!0),b.addEventListener("touchmove",q,!0),b.addEventListener("touchcancel",s,!0)},w.bindMouse=function(){b.addEventListener("mousedown",h,!0),b.addEventListener("mouseup",k,!0),b.addEventListener("mousemove",l,!0),b.addEventListener("mouseover",m,!0),b.addEventListener("mouseout",n,!0)},w.unbindTouch=function(){b.removeEventListener("touchstart",o,!0),b.removeEventListener("touchend",p,!0),b.removeEventListener("touchmove",q,!0),b.removeEventListener("touchcancel",s,!0),b.removeEventListener("click",j,!0)},w.unbindMouse=function(){b.removeEventListener("mousedown",h,!0),b.removeEventListener("mouseup",k,!0),b.removeEventListener("mousemove",l,!0),b.removeEventListener("mouseover",m,!0),b.removeEventListener("mouseout",n,!0),b.removeEventListener("keyup",u,!0),b.removeEventListener("keydown",v,!0),b.removeEventListener("scroll",r,!0),b.removeEventListener("click",j,!0)},d.event.vmouse=w,z?w.bindTouch():w.bindMouse(),w.bindCommonEvents()}(a,a.document,d),function(a,b,d){var e=d.event,f=d.engine.eventType,g={_window:a,supported:a.orientation!==c&&a.onorientationchange!==c,properties:["orientation"],_orientation:"portrait"},h=function(b){var c=g._window,d=c.innerWidth,f=c.innerHeight;c.screen&&(d=c.screen.availWidth,f=c.screen.availHeight),d>f?g._orientation="landscape":g._orientation="portrait",b||e.trigger(a,"orientationchange",{orientation:g._orientation})},i=function(){if(g._window.orientation)switch(g._window.orientation){case 90:case-90:g._orientation="portrait";break;default:g._orientation="landscape"}else h(!0)},j=function(b,c){b.matches?g._orientation="portrait":g._orientation="landscape",c||e.trigger(a,"orientationchange",{orientation:g._orientation})},k=null;g.getOrientation=function(){return g._orientation},g.trigger=function(a){e.trigger(a,"orientationchange",{orientation:g._orientation})},g.unbind=function(){a.removeEventListener("orientationchange",i,!1),b.removeEventListener("throttledresize",h,!0),b.removeEventListener(f.DESTROY,g.unbind,!1)},g.detect=function(){g.supported?(a.addEventListener("orientationchange",i,!1),i()):g._window.matchMedia?(k=g._window.matchMedia("(orientation: portrait)"),k.matches?g._orientation="portrait":g._orientation="landscape",k.addListener(j)):(b.addEventListener("throttledresize",h,!0),h())},b.addEventListener(f.DESTROY,g.unbind,!1),g.detect(),d.event.orientationchange=g}(a,a.document,d),function(a,b){var e,f,g=d.event,h=d.jqm.jQuery,i={CLICK:"click",SUBMIT:"submit",KEYUP:"keyup",TOUCHSTART:"touchstart",TOUCHEND:"touchend",VCLICK:"vclick",MOUSEDOWN:"mousedown",MOUSEUP:"mouseup",BEFOREROUTERINIT:"beforerouterinit",DESTROY:"taudestroy"},j=["touchstart","touchmove","touchend","tap","taphold","swipeleft","swiperight","scrollstart","scrollstop"],k={proxyEventTriggerMethod:function(a,b){h.fn[a]=function(){var a,c=this,d=c.length;for(a=0;d>a;a++)b(c.get(a))}},proxyTrigger:function(a,b){var c,d=this,f=d.length;for(i[a.toUpperCase()]||e.call(d,a,b),c=0;f>c;c++)g.trigger(d.get(c),a);return this},proxyDispatch:function(a){var b,c=a.originalEvent&&a.originalEvent.detail||a.detail;return b=[].slice.call(arguments),c&&b.push(c),f.apply(this,b)},copyEventProperties:function(b,c,d){h(b).on(c,function(c){var e,f;for(e=0;e<d.length;e++)f=d[e],c[f]||(b instanceof a.screen.constructor?c[f]=c.originalEvent.detail&&c.originalEvent.detail[f]||c.target[f]:c[f]=c.originalEvent.detail&&c.originalEvent.detail[f])})},init:function(){var d=function(a){return a.stopPropagation(),a.preventDefault(),!1},l=[i.TOUCHSTART,i.TOUCHEND,i.VCLICK,i.MOUSEDOWN,i.MOUSEUP,i.CLICK],m=l.length,n=b.body.parentNode;h&&(j.forEach(function(a){h.fn[a]=function(b){return b?this.bind(a,b):this.trigger(a)},h.attrFn&&(h.attrFn[a]=!0)}),k.copyEventProperties(a.screen,"orientationchange",g.orientationchange.properties),
+k.proxyEventTriggerMethod("orientationchange",g.orientationchange.trigger),e===c&&(e=h.fn.trigger,h.fn.trigger=k.proxyTrigger),f||(f=h.event.dispatch,h.event.dispatch=k.proxyDispatch),h.mobile=h.mobile||{},h.mobile.tizen=h.mobile.tizen||{},h.mobile.tizen.documentRelativeCoordsFromEvent=null,h.mobile.tizen.targetRelativeCoordsFromEvent=null,h.mobile.addEventBlocker=function(){var a;for(n.classList.add("ui-blocker"),a=0;m>a;a++)n.addEventListener(l[a],d,!0)},h.mobile.removeEventBlocker=function(){var a;for(n.classList.remove("ui-blocker"),a=0;m>a;a++)n.removeEventListener(l[a],d,!0)},h.mobile.tizen.documentRelativeCoordsFromEvent=g.documentRelativeCoordsFromEvent.bind(g),h.mobile.tizen.targetRelativeCoordsFromEvent=g.targetRelativeCoordsFromEvent.bind(g))},destroy:function(){b.removeEventListener(i.BEFOREROUTERINIT,k.init,!1),b.removeEventListener(i.DESTROY,k.destroy,!1)}};b.addEventListener(i.BEFOREROUTERINIT,k.init,!1),b.addEventListener(i.DESTROY,k.destroy,!1),d.jqm.event=k}(a,a.document),function(a,b,d){var e,f=d.util.object,g=d.util.selectors,h=d.util.DOM,i={},j={uiStateKey:"&ui-state",urlParseRE:/^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)((#[^\?]*)(\?.*)?)?/,getLocation:function(b){var c=this.parseUrl(b||a.location.href),d=c.hash,e=c.hashSearch;return d="#"!==d||e?d:"",i=c,c.protocol+"//"+c.host+c.pathname+c.search+d+e},getDocumentUrl:function(a){return a?f.copy(j.documentUrl):j.documentUrl.href},parseLocation:function(){return this.parseUrl(this.getLocation())},parseUrl:function(a){var b;return"object"==typeof a?a:(b=j.urlParseRE.exec(a||"")||[],{href:b[0]||"",hrefNoHash:b[1]||"",hrefNoSearch:b[2]||"",domain:b[3]||"",protocol:b[4]||"",doubleSlash:b[5]||"",authority:b[6]||"",username:b[8]||"",password:b[9]||"",host:b[10]||"",hostname:b[11]||"",port:b[12]||"",pathname:b[13]||"",directory:b[14]||"",filename:b[15]||"",search:b[16]||"",hash:b[18]||"",hashSearch:b[19]||""})},makePathAbsolute:function(a,b){var c,d,e,f;if(a&&"/"===a.charAt(0))return a;for(a=a||"",b=b?b.replace(/^\/|(\/[^\/]*|[^\/]+)$/g,""):"",c=b?b.split("/"):[],d=a.split("/"),f=0;f<d.length;f++)switch(e=d[f]){case".":break;case"..":c.length&&c.pop();break;default:c.push(e)}return"/"+c.join("/")},isSameDomain:function(a,b){return j.parseUrl(a).domain===j.parseUrl(b).domain},isRelativeUrl:function(a){return""===j.parseUrl(a).protocol},isAbsoluteUrl:function(a){return""!==j.parseUrl(a).protocol},makeUrlAbsolute:function(a,b){var c,d,e,f,g,h,i,k,l;return j.isRelativeUrl(a)?(c=j.parseUrl(a),d=j.parseUrl(b),e=c.protocol||d.protocol,f=c.protocol?c.doubleSlash:c.doubleSlash||d.doubleSlash,g=c.authority||d.authority,h=""!==c.pathname,i=j.makePathAbsolute(c.pathname||d.filename,d.pathname),k=c.search||!h&&d.search||"",l=c.hash,e+f+g+i+k+l):a},addSearchParams:function(a,b){var c,d=j.parseUrl(a),e="object"==typeof b?this.getAsURIParameters(b):b,f=d.hash;return j.isEmbedded(a)&&e.length>0?(c=d.hashSearch||"?",d.hrefNoHash+(f||"")+c+("?"===c.charAt(c.length-1)?"":"&")+e):(c=d.search||"?",d.hrefNoSearch+c+("?"===c.charAt(c.length-1)?"":"&")+e+(f||""))},addHashSearchParams:function(a,b){var c=j.parseUrl(a),d="object"==typeof b?j.getAsURIParameters(b):b,e=c.hash,f=e?e.indexOf("?")<0?e+"?":e+"&":"#?";return c.hrefNoHash+f+("?"===f.charAt(f.length-1)?"":"&")+d},convertUrlToDataUrl:function(b,c,d){var e=j.parseUrl(b);return j.isEmbeddedPage(e,!!c)?j.getFilePath(e.hash+e.hashSearch,c):(d=d||j.documentBase,j.isSameDomain(e,d)?e.hrefNoHash.replace(d.domain,""):a.decodeURIComponent(b))},get:function(a){return a===c&&(a=this.parseLocation().hash),this.stripHash(a).replace(/[^\/]*\.[^\/*]+$/,"")},isPath:function(a){return/\//.test(a)},clean:function(a,b){return a.replace(b.domain,"")},stripHash:function(a){return a.replace(/^#/,"")},stripQueryParams:function(a){return a.replace(/\?.*$/,"")},isHashValid:function(a){return/^#[^#]+$/.test(a)},isExternal:function(a,b){var c=j.parseUrl(a);return c.protocol&&c.domain!==b.domain?!0:!1},hasProtocol:function(a){return/^(:?\w+:)/.test(a)},isEmbedded:function(a){var b=j.parseUrl(a);return""!==b.protocol?!j.isPath(b.hash)&&!!b.hash&&b.hrefNoHash===j.parseLocation().hrefNoHash:/\?.*#|^#/.test(b.href)},squash:function(a,b){var c,d,e,f,g=this.isPath(a),h=this.parseUrl(a),i=h.hash,k="";return b=b||(j.isPath(a)?j.getLocation():j.getDocumentUrl()),d=g?j.stripHash(a):a,d=j.isPath(h.hash)?j.stripHash(h.hash):d,f=d.indexOf(this.uiStateKey),f>-1&&(k=d.slice(f),d=d.slice(0,f)),c=j.makeUrlAbsolute(d,b),e=this.parseUrl(c).search,g?((j.isPath(i)||0===i.replace("#","").indexOf(this.uiStateKey))&&(i=""),k&&-1===i.indexOf(this.uiStateKey)&&(i+=k),-1===i.indexOf("#")&&""!==i&&(i="#"+i),c=j.parseUrl(c),c=c.protocol+"//"+c.host+c.pathname+e+i):c+=c.indexOf("#")>-1?k:"#"+k,c},isPreservableHash:function(a){return 0===a.replace("#","").indexOf(this.uiStateKey)},hashToSelector:function(a){var b="#"===a.substring(0,1);return b&&(a=a.substring(1)),(b?"#":"")+a.replace(new RegExp("([!\"#$%&'()*+,./:;<=>?@[\\]^`{|}~])","g"),"\\$1")},isFirstPageUrl:function(a,b,d,e,f){var g,h,i,k;return d=d===c?j.documentBase:d,e=e===c?j.documentBaseDiffers:e,f=f===c?j.documentUrl:f,g=j.parseUrl(j.makeUrlAbsolute(a,d)),h=g.hrefNoHash===f.hrefNoHash||e&&g.hrefNoHash===d.hrefNoHash,i=b&&b.id||!1,k=g.hash,h&&(!k||"#"===k||i&&k.replace(/^#/,"")===i)},isPermittedCrossDomainRequest:function(a,b){return d.getConfig("allowCrossDomainPages",!1)&&"file:"===a.protocol&&-1!==b.search(/^https?:/)},getAsURIParameters:function(a){var b,c="";for(b in a)a.hasOwnProperty(b)&&(c+=encodeURIComponent(b)+"="+encodeURIComponent(a[b])+"&");return c.substring(0,c.length-1)},documentUrl:null,documentBaseDiffers:!1,set:function(a){i.hash=a},getFilePath:function(a,b){var c="&"+d.getConfig("subPageUrlKey","");return a&&a.split(c)[0].split(b)[0]},cleanHash:function(a,b){return j.stripHash(a.replace(/\?.*$/,"").replace(b,""))},isEmbeddedPage:function(a,b){var c=j.parseUrl(a);return""!==c.protocol?c.hash&&(b?c.hrefNoHash===j.documentUrl.hrefNoHash:c.hrefNoHash===j.parseLocation().hrefNoHash):/^#/.test(c.href)}};j.documentUrl=j.parseLocation(),e=b.querySelector("base"),j.documentBase=e?j.parseUrl(j.makeUrlAbsolute(e.getAttribute("href"),j.documentUrl.href)):j.documentUrl,j.documentBaseDiffers=j.documentUrl.hrefNoHash!==j.documentBase.hrefNoHash,j.getDocumentBase=function(a){return a?f.copy(j.documentBase):j.documentBase.href},j.getClosestBaseUrl=function(a,b){var c=h.getNSData(g.getClosestBySelector(a,b),"url"),e=j.documentBase.hrefNoHash;return d.getConfig("dynamicBaseEnabled",!0)&&c&&j.isPath(c)||(c=e),j.makeUrlAbsolute(c,e)},d.util.path=j}(a,a.document,d),function(a){function b(a){for(var b,c=[],d=0,e=0,g="";null!=(b=o.exec(a));){var h=b[0],i=b[1],j=b.index;if(g+=a.slice(e,j),e=j+h.length,i)g+=i[1];else{g&&(c.push(g),g="");var k=b[2],l=b[3],m=b[4],n=b[5],p=b[6],q="+"===p||"*"===p,r="?"===p||"*"===p,s=k||"/";c.push({name:l||d++,prefix:k||"",delimiter:s,optional:r,repeat:q,pattern:f(m||n||"[^"+s+"]+?")})}}return e<a.length&&(g+=a.substr(e)),g&&c.push(g),c}function c(a){return d(b(a))}function d(a){for(var b=new Array(a.length),c=0;c<a.length;c++)"object"==typeof a[c]&&(b[c]=new RegExp("^"+a[c].pattern+"$"));return function(c){var d="";c=c||{};for(var e=0;e<a.length;e++){var f=a[e];if("string"!=typeof f){var g=c[f.name];if(null==g){if(f.optional)continue;throw new TypeError('Expected "'+f.name+'" to be defined')}if(n(g)){if(!f.repeat)throw new TypeError('Expected "'+f.name+'" to not repeat');if(0===g.length){if(f.optional)continue;throw new TypeError('Expected "'+f.name+'" to not be empty')}for(var h=0;h<g.length;h++){if(!b[e].test(g[h]))throw new TypeError('Expected all "'+f.name+'" to match "'+f.pattern+'"');d+=(0===h?f.prefix:f.delimiter)+encodeURIComponent(g[h])}}else{if(!b[e].test(g))throw new TypeError('Expected "'+f.name+'" to match "'+f.pattern+'"');d+=f.prefix+encodeURIComponent(g)}}else d+=f}return d}}function e(a){return a.replace(/([.+*?=^!:${}()[\]|\/])/g,"\\$1")}function f(a){return a.replace(/([=!:$\/()])/g,"\\$1")}function g(a,b){return a.keys=b,a}function h(a){return a.sensitive?"":"i"}function i(a,b){var c=a.source.match(/\((?!\?)/g);if(c)for(var d=0;d<c.length;d++)b.push({name:d,prefix:null,delimiter:null,optional:!1,repeat:!1,pattern:null});return g(a,b)}function j(a,b,c){for(var d=[],e=0;e<a.length;e++)d.push(m(a[e],b,c).source);var f=new RegExp("(?:"+d.join("|")+")",h(c));return g(f,b)}function k(a,c,d){for(var e=b(a),f=l(e,d),h=0;h<e.length;h++)"string"!=typeof e[h]&&c.push(e[h]);return g(f,c)}function l(a,b){b=b||{};for(var c=b.strict,d=b.end!==!1,f="",g=a[a.length-1],i="string"==typeof g&&/\/$/.test(g),j=0;j<a.length;j++){var k=a[j];if("string"==typeof k)f+=e(k);else{var l=e(k.prefix),m=k.pattern;k.repeat&&(m+="(?:"+l+m+")*"),m=k.optional?l?"(?:"+l+"("+m+"))?":"("+m+")?":l+"("+m+")",f+=m}}return c||(f=(i?f.slice(0,-2):f)+"(?:\\/(?=$))?"),f+=d?"$":c&&i?"":"(?=\\/|$)",new RegExp("^"+f,h(b))}function m(a,b,c){return b=b||[],n(b)?c||(c={}):(c=b,b=[]),a instanceof RegExp?i(a,b,c):n(a)?j(a,b,c):k(a,b,c)}var n=Array.isArray;m.parse=b,m.compile=c,m.tokensToFunction=d,m.tokensToRegExp=l;var o=new RegExp(["(\\\\.)","([\\/.])?(?:\\:(\\w+)(?:\\(((?:\\\\.|[^)])*)\\))?|\\(((?:\\\\.|[^)])*)\\))([+*?])?"].join("|"),"g");a.pathToRegexp=m}(a),function(a){d.util.pathToRegexp=a.pathToRegexp}(a),function(){d.router=d.router||{}}(),function(){d.router.route=d.router.route||{}}(),function(a){var c,e=d.util.object,f=0,g=0,h=a.history,i={activeState:null,startURL:null,replace:function(a,b,d){var j=e.merge({},a,{uid:c?g:++f,stateUrl:d,stateTitle:b});!this.startURL&&d&&d.length&&(this.startURL=d),h[c?"replaceState":"pushState"](j,b,d),i.setActive(j)},back:function(){var c;this.startURL!==a.location.href?h.back():(c=new CustomEvent("tauback",{bubbles:!0,cancelable:!0}),b.body.dispatchEvent(c))},setActive:function(a){return a&&(i.activeState=a,g=a.uid,a.volatileRecord)?void i.enableVolatileMode():void i.disableVolatileMode()},getDirection:function(a){return a?a.uid<=g?"back":"forward":"back"},enableVolatileMode:function(){c=!0},disableVolatileMode:function(){c=!1}};d.history=i}(a),function(a,b){function c(a){return o.trigger(b,t,a,!0,!0)}function e(a){var b,d,e,f,g=a.target,h=p.getClosestBySelector(g,l),i=!0;return h&&1===a.which&&(b=h.getAttribute("href"),f=h.getAttribute("rel"),d="external"===f||h.hasAttribute("target"),d||(e=s.getData(h),e.event=a,f&&!e.rel?e.rel=f:f=e.rel,b&&!e.href&&(e.href=b),"popup"!==f||e.link||(e.link=h),n.disableVolatileMode(),"back"===f&&(o.preventDefault(a),i=!1),c(e)||(o.preventDefault(a),i=!1))),i}function f(a){var d,e=a.state,f=n.activeState,g={},i=!0,j=!1;h.locked?(n.disableVolatileMode(),f&&n.replace(f,f.stateTitle,f.stateUrl)):e&&(d="back"===n.getDirection(e),g=q.merge(g,e,{reverse:d,transition:d?f&&f.transition||"none":e.transition,fromHashChange:!0}),f&&(i=o.trigger(b,u,q.merge(g,{url:r.getLocation(),stateUrl:f.stateUrl}),!0,!0),j=i),e.url=r.getLocation(),n.setActive(e),j||(g.event=a,c(g)))}function g(a){var b=a.newURL;b&&n.activeState.url!==b&&c({href:b,fromHashChange:!0,event:a})}var h=Object.create(null),i="popstate",j="hashchange",k="vclick",l="a,tau-button",m=d.util,n=d.history,o=d.event,p=m.selectors,q=m.object,r=m.path,s=m.DOM,t="historystatechange",u="historyhashchange",v="historyenabled",w="historydisabled",x={STATECHANGE:t,HASHCHANGE:u,ENABLED:v,DISABLED:w};h.events=x,h.enabled=!0,h.locked=!1,h.lock=function(){this.locked=!0},h.unlock=function(){this.locked=!1},h.enable=function(){b.addEventListener(k,e,!1),a.addEventListener(i,f,!1),a.addEventListener(j,g,!1),n.enableVolatileMode(),this.enabled=!0,o.trigger(b,v,this)},h.disable=function(){b.removeEventListener(k,e,!1),a.removeEventListener(i,f,!1),a.removeEventListener(j,g,!1),n.disableVolatileMode(),this.enabled=!1,o.trigger(b,w,this)},d.history.manager=h}(a,a.document),function(a,b){b.widget.core=b.widget.core||{}}(a.document,d),function(b,c){function d(a,b,c,d){a&&(a.onHide(),c._removeExternalPage(a,d)),b.onShow(),c.trigger(k.PAGE_CHANGE)}var e=c.widget.BaseWidget,f=c.util,g=f.DOM,h=c.engine,i={pageContainer:"ui-page-container",uiViewportTransitioning:"ui-viewport-transitioning",out:"out","in":"in",reverse:"reverse",uiPreIn:"ui-pre-in",uiBuild:"ui-page-build"},j=function(){this.activePage=null,this.inTransition=!1},k={PAGE_BEFORE_CHANGE:"pagebeforechange",PAGE_CHANGE:"pagechange",PAGE_REMOVE:"pageremove"},l="animationend",m="webkitAnimationEnd",n="mozAnimationEnd",o="msAnimationEnd",p="oAnimationEnd",q=[l,m,n,o,p],r=new e;j.events=k,j.classes=i,r._build=function(a){return a.classList.add(i.pageContainer),a},r.change=function(a,b){var c,e=this,f=e.getActivePage(),g=b||{};e._options=g,g.widget=g.widget||"Page",f&&f.element===a||(a.parentNode!==e.element&&(a=e._include(a)),e.trigger(k.PAGE_BEFORE_CHANGE),a.classList.add(i.uiBuild),delete b.url,c=h.instanceWidget(a,g.widget,b),c.layout(),(c.option("autoBuildWidgets")||a.querySelector(".ui-i3d")||a.querySelector(".ui-coverflow"))&&h.createWidgets(a,b),f&&f.onBeforeHide(),c.onBeforeShow(),a.classList.remove(i.uiBuild),g===e._options&&(g.deferred={resolve:d},e._transition(c,f,g)))},r._transition=function(b,c,d){var e,f,g=this,h=g.element,j=h.classList,k=c&&d.transition?d.transition:"none",l=d.deferred,m=[i["in"],i.out,i.uiPreIn,k];d.reverse&&m.push(i.reverse),g.inTransition=!0,j.add(i.uiViewportTransitioning),e=l.resolve,l.resolve=function(){var a=c&&c.element.classList,f=b.element.classList;g._setActivePage(b),g._clearTransitionClasses(m,a,f),e(c,b,g,d)},"none"!==k?(f=function(){b.off(q,f,!1),l.resolve()},b.on(q,f,!1),g._appendTransitionClasses(c,b,k,d.reverse)):a.setTimeout(l.resolve,0)},r._appendTransitionClasses=function(a,b,c,d){var e;a&&(e=a.element.classList,e.add(c,i.out),d&&e.add(i.reverse)),e=b.element.classList,e.add(c,i["in"],i.uiPreIn),d&&e.add(i.reverse)},r._clearTransitionClasses=function(a,b,c){var d=this,e=d.element,f=e.classList;f.remove(i.uiViewportTransitioning),d.inTransition=!1,a.forEach(function(a){c.remove(a)}),b&&a.forEach(function(a){b.remove(a)})},r._include=function(a){var c=this.element;return a.parentNode&&a.ownerDocument===b||(a=f.importEvaluateAndAppendElement(a,c)),a},r._setActivePage=function(a){var b=this;b.activePage&&b.activePage.setActive(!1),b.activePage=a,a.setActive(!0)},r.getActivePage=function(){return this.activePage},r._removeExternalPage=function(a,b){var c=a.element;b&&b.reverse&&g.hasNSData(c,"external")&&c.parentNode&&(a.destroy(),c.parentNode.removeChild(c),this.trigger(k.PAGE_REMOVE))},j.prototype=r,c.widget.core.PageContainer=j,h.defineWidget("pagecontainer","",["change","getActivePage"],j,"core")}(a.document,d),function(b,d){function e(){return b.querySelector(":focus")||b.activeElement}function f(a){return a===Y.left||a===Y.right||a===Y.up||a===Y.down||a===Y.enter||a===Y.escape}function g(b,c){var d=[];return b?(d=S.call(b.querySelectorAll(V)),c?d.filter(function(b){return b.offsetWidth&&"hidden"!==a.getComputedStyle(b).visibility}):d):[]}function h(a){return a.element}function i(){var a=aa.length;V="",L.forEach(aa,function(b,c){V+=b.value,b.includeDisabled||(V+=_),a-1>c&&(V+=",")})}function j(a,b){var c=b instanceof HTMLElement?b.getBoundingClientRect():b,d={x:a.width/2+a.left,y:a.height/2+a.top},e={x:c.width/2+c.left,y:c.height/2+c.top},f=d.y-e.y,g=d.x-e.x;return Math.sqrt(f*f+g*g)}function k(a,b,c){var d,e,f,g,h=!1,i=b instanceof HTMLElement?b.getBoundingClientRect():b;if("down"===c||"up"===c)d=i.left,e=i.left+i.width,f=a.left,g=a.left+a.width;else{if("left"!==c&&"right"!==c)return h;d=i.top,e=i.top+i.height,f=a.top,g=a.top+a.height}return h=d>f&&g>d||e>f&&g>e||f>=d&&e>=g}function l(a,b){var c=b instanceof HTMLElement?b.getBoundingClientRect():b,d={x:a.width/2+a.left,y:a.height/2+a.top},e={x:c.width/2+c.left,y:c.height/2+c.top},f=d.y-e.y,g=d.x-e.x,h=180*O(-f,g)/Q;return h}function m(a,b){return b=b||0,P(a-180)<b||P(a+180)<b?$.left:P(a-90)<b?$.up:P(a)<b?$.right:P(a+90)<b?$.down:""}function n(a,b){return a===b?0:b>a?-1:1}function o(a,b,c){return c===$.right&&parseInt(a.right)<=parseInt(b.left)?c:c===$.left&&parseInt(b.right)<=parseInt(a.left)?c:c===$.down&&parseInt(a.bottom)<=parseInt(b.top)?c:c===$.up&&parseInt(a.top)>=parseInt(b.bottom)?c:b?m(l(b,a),5):""}function p(a,b){var c=a.left-b.left,d=a.top-b.top;return 0|R(c*c+d*d)}function q(a,b){var c={top:b.top-(a.top+a.height)+0,bottom:a.top-b.top-b.height,right:a.left-b.left-b.width,left:b.left-(a.left+a.width)};return c.leftRest=c.left+a.width,c.rightRest=c.right+a.width,c.topRest=c.top+a.height,c.bottomRest=c.bottom+a.height,c}function r(a,b){return a.distanceByCenter===b.distanceByCenter?0:a.distanceByCenter<b.distanceByCenter?-1:1}function s(a,b){return a.distanceByDirection.distance===b.distanceByDirection.distance?r(a,b):a.distanceByDirection.distance<b.distanceByDirection.distance?-1:1}function t(a,b){return a.inSideDistanceLimit&&b.inSideDistanceLimit?s(a,b):a.inSideDistanceLimit||b.inSideDistanceLimit?a.inSideDistanceLimit&&!b.inSideDistanceLimit?-1:1:r(a,b)}function u(a,b){return a.inLine&&b.inLine||!a.inLine&&!b.inLine?t(a,b):a.inLine&&!b.inLine?-1:1}function v(a,b){switch(b){case"left":return{distance:a.left,distanceRest:a.leftRest};case"right":return{distance:a.right,distanceRest:a.rightRest};case"up":return{distance:a.top,distanceRest:a.topRest};case"down":return{distance:a.bottom,distanceRest:a.bottomRest}}return null}function w(a,c,d){var f,i,m,r=d.direction,s=c||e(),t=[],w=s.getBoundingClientRect(),x=[],y=null,A=null,B={},C=0,D=0;if(i=s&&z(s,r,a))return[i];if(f=g(a,!0),s&&s!==b.body){for(C=0,D=f.length;D>C;++C)y=f[C],A=y.getBoundingClientRect(),B=q(A,w),m=v(B,r),x.push({element:y,angle:l(A,w),direction:o(w,A,r),distance:p(w,A),distanceByDirection:m,distanceByCenter:j(A,w),inLine:k(A,w,r),inSideDistanceLimit:m.distance>=0&&m.distance<T});return x=x.filter(function(a){return a.distanceByDirection.distanceRest>0}),x=x.filter(function(b){return 0===b.distance?r===$.down?!!(s.compareDocumentPosition(typeof b===a?b:b.element)&Node.DOCUMENT_POSITION_CONTAINED_BY):r===$.up?!!(s.compareDocumentPosition(typeof b===a?b:b.element)&Node.DOCUMENT_POSITION_PRECEDING):!1:b.direction===r}),x=x.sort(u).map(h)}return t=L.map(f,function(a){var b=a.getBoundingClientRect();return{offset:b,element:a,width:a.offsetWidth,height:a.offsetHeight}}),L.map(t.sort(function(a,b){return a.offset.top===b.offset.top?n(a.offset.left,b.offset.left):n(a.offset.top,b.offset.top)}),h)}function x(a){var b,c,d;a=a||{},b=a.current||Z||e(),b&&(d=I.getBinding(b),d?d.blur(a):(a.element=b,c=!M.trigger(b,"taublur",a),c||(b.classList.remove(X.focus),b.blur())),Z=null)}function y(a,b,c){var d,f,g,h=c.current||Z||e(),i=b&&N.getClosestBySelectorNS(b.parentNode,"focus-lock=true"),j=i&&I.getBinding(i)||null;return j&&j!==G?!1:(c=c||{},f=I.getBinding(b),f?(c.previousElement=h,d=f.focus(c),x(c)):b!==h&&(c.previousElement=h,b&&(c.element=b,g=!M.trigger(b,"taufocus",c),g||(b.classList.add(X.focus),b.focus())),x(c),d=!0),Z=b,a&&a._openActiveElement&&a._openActiveElement(b),d)}function z(a,c,d){var e=a.getAttribute("data-focus-"+c),f={selector:e,direction:c,currentElement:a,nextElement:null},g="true"===a.getAttribute("data-focus-container-context"),h=a.getAttribute("data-focus-context");if(e){if(M.trigger(a,"focusquery",f,!0,!0))return g&&(h&&(d=b.querySelector(h)),d)?d.parentNode.querySelector(e):a.parentNode.querySelector(e);if(f.nextElement)return f.nextElement}return null}function A(a,b){var c=null;return J.getNSData(b,"focus-lock")===!0&&(c=I.getBinding(b),c&&c!==G)?(c.saveKeyboardSupport(),c.enableKeyboardSupport(),c.blur(),C(a,b,{direction:H,key:Y.down}),!0):!1}function B(a,b){var c;return J.getNSData(b,"focus-lock")===!0||(b=N.getClosestBySelectorNS(b.parentNode,"focus-lock=true"))?(c=I.getBinding(b),c&&c===G?(c.disableKeyboardSupport(),c.restoreKeyboardSupport(),y(a,b,{direction:H,key:Y.down}),!0):!1):!1}function C(a,b,c){var e,f,g="",h=[],i=0,j=c.current,k=c.event,l=!1;switch(c.key){case Y.left:g=$.left;break;case Y.up:g=$.up;break;case Y.right:g=$.right;break;case Y.down:g=$.down;break;case Y.enter:if(j)return void(A(a,j)?k&&(k.preventDefault(),k.stopImmediatePropagation()):(f=d.engine.getBinding(j),f&&"function"==typeof f._actionEnter&&f._actionEnter(j)));break;case Y.escape:if(j)return void(B(a,j)?k&&(k.preventDefault(),k.stopImmediatePropagation()):(f=d.engine.getBinding(j),f&&"function"==typeof f._actionEscape&&f._actionEscape(j)));break;default:return}if(c.direction=c.direction||g,g&&(H=g),e=z(b,g),e||(h=w(b,j,c),e=h[i]),c._last)for(i=h.length-1,e=h[i];e&&!l;)l=y(a,e,c),e=h[--i];else if(i=0,e=h[i])for(;e&&!l;)l=y(a,e,c),e=h[++i];else M.trigger(J.isChildElementOf(j,b)?j:b,"taufocusborder",c)}function D(a,b,c,d){var e=b.offset,f=b.height,g=b.width,h=c.offsetHeight,i=c.offsetWidth;switch(d=d||c.getBoundingClientRect(),a){case"top":return d.left>=e.left+g||d.left+i<=e.left?!1:e.top<d.top;case"bottom":return d.left>=e.left+g||d.left+i<=e.left?!1:e.top>=d.bottom;case"left":return d.top>=e.top+f||d.top+h<=e.top?!1:e.left<d.left;case"right":return d.top>=e.top+f||d.top+h<=e.top?!1:e.left>=d.right}return!1}function E(a){return a.value}function F(a){return L.map(aa,E).indexOf(a)}var G,H,I=d.engine,J=d.util.DOM,K=d.util.object,L=d.util.array,M=d.event,N=d.util.selectors,O=Math.atan2,P=Math.abs,Q=Math.PI,R=Math.sqrt,S=[].slice,T=200,U={_supportKeyboard:!1},V="",W=function(){var a=this,b=a.options||{};K.merge(a,U),K.merge(b,{focusDirection:null,focusContext:null,focusContainerContext:!1,focusUp:null,focusDown:null,focusLeft:null,focusRight:null,focusLock:!1}),a.isKeyboardSupport=!0,""===V&&i(),a._onKeyupHandler=null,a._onClickHandler=null,a._onHWKeyHandler=null,a.keydownEventTimeStart=null,a.keydownEventRepeated=!1},X={focusDisabled:"ui-focus-disabled",focusEnabled:"ui-focus-enabled",focusDisabledByWidget:"ui-focus-disabled-by-widget",focus:"ui-focus"},Y={left:37,up:38,right:39,down:40,enter:13,tab:9,escape:27},Z=null,$={up:"up",down:"down",left:"left",right:"right"},_=":not(."+X.focusDisabled+"):not(."+d.widget.BaseWidget.classes.disable+")",aa=[{value:"a",includeDisabled:!1,count:1},{value:"."+X.focusEnabled,includeDisabled:!1,count:1},{value:"[tabindex]",includeDisabled:!1,count:1},{value:"[data-focus-lock=true]",includeDisabled:!1,count:1}],ba=[],ca=50;W.KEY_CODES=Y,W.classes=X,U.preventFocusOnElement=function(a){a.classList.add(X.focusDisabled)},U.disableFocusableElements=function(a){this.getFocusableElements(a).forEach(function(a){a.classList.add(X.focusDisabled),a.classList.add(X.focusDisabledByWidget)})},U.enableDisabledFocusableElements=function(a){var b;a&&(b=a.querySelectorAll("."+X.focusDisabledByWidget),S.call(b).forEach(function(a){a.classList.remove(X.focusDisabled),a.classList.remove(X.focusDisabledByWidget)}))},U.getActiveSelector=function(){return V},W.copyFocusAttributes=function(a,b){var c=a.options;J.setNSDataAttributes(b,{focusDirection:c.focusDirection,focusContext:c.focusContext,focusContainerContext:c.focusContainerContext,focusUp:c.focusUp,focusDown:c.focusDown,focusLeft:c.focusLeft,focusRight:c.focusRight},!0)},U.blurOnActiveElement=x,U._onKeyup=function(a){var b=this,c=d.getConfig("keyboardSupport",!1);c&&b._supportKeyboard&&(b.keydownEventRepeated||b._onShortPress(a),b.keydownEventTimeStart=null,b.keydownEventRepeated=!1)},U._onMouseMove=function(a){var c=this,e=b.elementFromPoint(a.pageX,a.pageY),f=d.getConfig("keyboardSupport",!1),g=null,h=Z,i=$.down;f&&c._supportKeyboard&&(g=N.getClosestBySelector(e,V),g!==h&&(i=m(h?l({left:a.pageX,top:a.pageY},h):l({left:a.pageX,top:a.pageY},{left:a.pageX-a.movementX,top:a.pageY-a.movementY})),y(c,g,{direction:i})))},U._onHWKey=function(a){var b=this,c=Z||e();return"back"===a.keyName&&c&&B(b,c)?(a.preventDefault(),a.stopImmediatePropagation(),!0):!1},U._onLongPress=function(a){var b=this,c=d.getConfig("keyboardLongpressInterval",100),f={current:Z||e(),key:a.keyCode,duration:c-30>=ca?c-30:ca,_last:!0,_filterNeighbors:D};C(b,b.keyboardElement||b.element,f)},U._onShortPress=function(a){var b=this;d.getConfig("keyboardSupport",!1)&&C(b,b.keyboardElement||b.element,{current:Z||e(),event:a,key:a.keyCode})},U._onKeydown=function(a){var b,c=this,e=d.getConfig("keyboardLongpressInterval",1e3),g=d.getConfig("keyboardSupport",!1);g&&c._supportKeyboard&&f(a.keyCode)&&(a.preventDefault(),a.stopPropagation(),b=Date.now(),(!c.keydownEventTimeStart||b-c.keydownEventTimeStart>e)&&(c.keydownEventTimeStart&&(c._onLongPress(a),c.keydownEventRepeated=!0),c.keydownEventTimeStart=b))},U._bindEventKey=function(){var a=this;a._onKeyupHandler||(a._onKeyupHandler=a._onKeyup.bind(a),a._onKeydownHandler=a._onKeydown.bind(a),a._onHWKeyHandler=a._onHWKey.bind(a),b.addEventListener("keyup",a._onKeyupHandler,!1),b.addEventListener("keydown",a._onKeydownHandler,!1),b.addEventListener("tizenhwkey",a._onHWKeyHandler,!1))},U._bindEventMouse=function(){var a=this;a._onMouseMoveHandler||(a._onMouseMoveHandler=a._onMouseMove.bind(a),b.addEventListener("mousemove",a._onMouseMoveHandler,!1))},U._destroyEventKey=function(){this._onKeyupHandler&&(b.removeEventListener("keyup",this._onKeyupHandler,!1),b.removeEventListener("keydown",this._onKeydownHandler,!1),b.removeEventListener("tizenhwkey",this._onHWKeyHandler,!1),this._onKeyupHandler=null)},U._destroyEventMouse=function(){this._onClickHandler&&b.removeEventListener("mousemove",this._onMouseMoveHandler,!1)},W.blurAll=function(){var a=Z||e(),b=a&&I.getBinding(a);b?b.blur():a&&a.blur()},W.focusElement=function(a,b,d){var f,h,i;if(d=d||{},d.current===c&&(d.current=e()),b instanceof HTMLElement)if(a)for(f=g(a,!0),h=f.length,i=0;h>i;i++)f[i]===b&&b.focus();else b.focus();else"number"==typeof b?(f=g(a,!0),f[b]&&y(null,f[b],d)):"string"==typeof b&&Y[b]?(d.direction=Y[b],C(null,a,d)):(f=g(a,!0),f[0]&&y(null,f[0],d))},U.enableKeyboardSupport=function(){this._supportKeyboard=!0,G=this},U.restoreKeyboardSupport=function(){var a=ba.pop();a&&a.enableKeyboardSupport()},U.disableKeyboardSupport=function(){G=null,this._supportKeyboard=!1},U.saveKeyboardSupport=function(){G&&(ba.push(G),G.disableKeyboardSupport())},U.getFocusableElements=g,W.registerActiveSelector=function(a,b){var c,d=a.split(",");L.forEach(d,function(a){a=a.trim(),c=F(a),-1===c?aa.push({value:a,includeDisabled:b,count:1}):aa[c].count++}),i()},W.unregisterActiveSelector=function(a){var b,c=a.split(",");L.forEach(c,function(a){a=a.trim(),b=F(a),-1!==b&&(--aa[b].count,0===aa[b].count&&aa.splice(b,1))}),i()},d.widget.core.BaseKeyboardSupport=W}(a.document,d),function(b,d){var e=d.widget.BaseWidget,f=d.widget.core.PageContainer,g=d.util,h=g.DOM,i=g.selectors,j=d.engine,k=d.widget.core.BaseKeyboardSupport,l=d.util.array,m=function(a,b){var c=this;k.call(c),c._contentFillAfterResizeCallback=null,c._initialContentStyle={},c._lastScrollPosition=0,c._requestToShowGoToTopButton=null,c.options=b||{},c._contentStyleAttributes=["height","width","minHeight","marginTop","marginBottom"],c._ui={}},n={SHOW:"pageshow",HIDE:"pagehide",CREATE:"pagecreate",BEFORE_CREATE:"pagebeforecreate",BEFORE_SHOW:"pagebeforeshow",BEFORE_HIDE:"pagebeforehide"},o={uiPage:"ui-page",uiPageActive:"ui-page-active",uiSection:"ui-section",uiHeader:"ui-header",uiMore:"ui-more",uiHeaderOnlyMoreButton:"ui-header-has-only-more-button",uiFooter:"ui-footer",uiContent:"ui-content",uiTitle:"ui-title",uiPageScroll:"ui-scroll-on",uiScroller:"ui-scroller",uiArcListview:"ui-arc-listview",uiContentUnderPopup:"ui-content-under-popup",uiPageFlex:"ui-page-flex",uiAppbar:"ui-appbar",uiAppbarTitle:"ui-appbar-title",uiAppbarTitleContainer:"ui-appbar-title-container"},p="header,[data-role='header'],."+o.uiHeader,q="footer,[data-role='footer'],."+o.uiFooter,r="[data-role='content'],."+o.uiContent,s="."+o.uiMore+":first-child:last-child",t=800,u=new e;m.classes=o,m.events=n,m.selector="[data-role=page],.ui-page",u._configure=function(){var a=this.options;a.header=null,a.footer=null,a.content=null,a.goToTopButton=d.getConfig("goToTopButton"),a.enablePageScroll=d.getConfig("enablePageScroll"),a.autoBuildWidgets=d.getConfig("autoBuildOnPageChange"),this.options=a},u.getContentHeight=function(){return this._contentHeight},u._contentFill=function(){var b,c=this,d=c.element,e=a.innerWidth,f=a.innerHeight,g=d.style,i=c._ui,j=i.content,k=i.header,l=0,m=0,n=i.footer,p=i.mainTab;p&&(f-=p.getBoundingClientRect().height),g.width=e+"px",g.height=f+"px",n&&(m+=n.getBoundingClientRect().height),k&&(l=h.getElementHeight(k,null,!1,!0)),c._contentHeight=f-l-m,j&&!d.classList.contains(o.uiPageFlex)&&(b=j.style,n&&(b.marginBottom=m+"px",b.paddingBottom=-m+"px"),c.options.enablePageScroll||(b.height=c._contentHeight+"px")),c.options.model&&c._fillContentsFromModel()},u._fillContentsFromModel=function(){var a=this,b=a.options.model||{},c=b;Object.keys(c).forEach(function(b){[].slice.call(a.element.querySelectorAll("[data-bind='"+b+"']")).forEach(function(a){a.textContent=c[b]})})},u._storeContentStyle=function(){var a=this,b=a._initialContentStyle,c=a._contentStyleAttributes,d=a.element.querySelector("."+o.uiContent),e=d?d.style:{};c.forEach(function(a){b[a]=e[a]})},u._restoreContentStyle=function(){var a=this,b=a._initialContentStyle,c=a._contentStyleAttributes,d=a.element.querySelector("."+o.uiContent),e=d?d.style:{};c.forEach(function(a){b[a]&&(e[a]=b[a])})},u._setFooter=function(a,c){var d=this,e=d._ui,f=e.footer;!f&&c&&(f=b.createElement("footer"),a.appendChild(f),e.footer=f),f&&(c===!1?(a.removeChild(f),e.footer=null):(f.classList.add(o.uiFooter),"string"==typeof c&&(e.footer.textContent=c)),d.options.footer=c)},u._setHeader=function(a,c){var e=this,f=e._ui,g=f.header;!g&&c&&(g=b.createElement("header"),a.appendChild(g),f.header=g),g&&(c===!1?(a.removeChild(g),f.header=null):(g.classList.add(o.uiHeader),"string"==typeof c&&(f.header.textContent=c),d.support&&d.support.shape&&d.support.shape.circle&&g.querySelector(s)&&""===g.textContent.trim()&&g.classList.add(o.uiHeaderOnlyMoreButton)),e.options.header=c)},u._setContent=function(a,c){var d,e=this,f=e._ui,g=f.content,h=a.firstChild;if(!g&&c){for(g=b.createElement("div");h;)d=h.nextSibling,h!==f.footer&&h!==f.header&&g.appendChild(h),h=d;a.insertBefore(g,f.footer),f.content=g}g&&(c===!1?(a.removeChild(g),f.content=null):(g.classList.add(o.uiContent),"string"==typeof c&&(g.textContent=c)),e.options.content=c)},u._buildHeader=function(a){var b=this;b._ui.header=i.getChildrenBySelector(a,p)[0]||null,b.options.header===c&&(b.options.header=!!b._ui.header),b._setHeader(a,b.options.header)},u._buildFooter=function(a){var b=this;b._ui.footer=i.getChildrenBySelector(a,q)[0]||null,b.options.footer===c&&(b.options.footer=!!b._ui.footer),b._setFooter(a,b.options.footer)},u._buildContent=function(a){var b=this;b._ui.content=i.getChildrenBySelector(a,r)[0]||null,b.options.content===c&&(b.options.content=!!b._ui.content),b._setContent(a,b.options.content)},u._findMainTab=function(){var a=this,b=i.getClosestBySelector(a.element,"."+f.classes.pageContainer);a._ui.mainTab=a.element.querySelector(".ui-main-tab")||b&&b.querySelector(".ui-main-tab-visible")||null},u._buildGoToTopButton=function(a){var c=this,d=c._ui;c.options.goToTopButton&&(d.goToTopButton=b.createElement("div"),d.goToTopButton.classList.add("ui-button-go-to-top"),a.appendChild(d.goToTopButton))},u._showGoToTopButton=function(){var a=this,b=a._ui,c=b.goToTopButton;a._requestToShowGoToTopButton||(a._requestToShowGoToTopButton=setTimeout(function(){c.style.display="block",a._requestToShowGoToTopButton=null},t))},u._hideGoToTopButton=function(){var a=this,b=a._ui,c=b.goToTopButton;a._requestToShowGoToTopButton&&(clearTimeout(a._requestToShowGoToTopButton),a._requestToShowGoToTopButton=null),c.style.display="none"},u._handleGoToTopButtonClick=function(){var a=this,b=a.element,c=a.getScroller(),e=null,f=null;a._hideGoToTopButton(),e=b.querySelector("."+o.uiArcListview),e?(f=d.engine.getBinding(e),f&&f.scrollToPosition(0,!1)):c.scrollTop=0},u._setAria=function(){var a=this,b=a._ui,c=b.content,d=b.header,e=b.footer,f=b.title;
+c&&c.setAttribute("role","main"),d&&d.setAttribute("role","header"),e&&e.setAttribute("role","footer"),f&&(f.setAttribute("role","heading"),f.setAttribute("aria-level",1),f.setAttribute("aria-label","title"))},u._setTitle=function(a){var c,d,e,f=this,g=h.getNSData(a,"title"),j=f._ui.header,k=g;j&&(j.classList.add(o.uiAppbar),e=i.getChildrenByClass(j,o.uiAppbarTitleContainer)[0],e||(e=b.createElement("div"),e.classList.add(o.uiAppbarTitleContainer),j.appendChild(e)),c=i.getChildrenBySelector(j,"h1, h2, h3, h4, h5, h6"),d=c[0],!k&&d&&(k=d.innerText,f._ui.title=d),!g&&k&&h.setNSData(a,"title",k),l.forEach(c,function(a){a.classList.add(o.uiTitle),a.classList.add(o.uiAppbarTitle),e.appendChild(a)}))},u._build=function(a){var b=this;return a.classList.add(o.uiPage),a.classList.add(o.uiPageFlex),b._buildHeader(a),b._buildFooter(a),b._buildContent(a),b._buildGoToTopButton(a),b._setTitle(a),b._setAria(),b.options.enablePageScroll!==!0||a.querySelector("."+o.uiScroller)||j.instanceWidget(a,"Scrollview"),a},u.setActive=function(a){var b=this.element.classList;a||a===c?(this.focus(),b.add(o.uiPageActive)):(this.blur(),b.remove(o.uiPageActive))},u.isActive=function(){return this.element.classList.contains(o.uiPageActive)},u.focus=function(){var a=this.element,b=a.querySelector("[autofocus]")||a;b.focus()},u.blur=function(){var a=this.element,c=b.activeElement||a;c.blur()},u._bindEvents=function(){var b=this,c=b.element,e=b._ui.header,f=b._ui.goToTopButton;b._contentFillAfterResizeCallback=b._contentFill.bind(b),a.addEventListener("resize",b._contentFillAfterResizeCallback,!1),e&&(e.addEventListener("appbarcollapsed",function(){var a=b.getScroller(),c=d.engine.getBinding(a);c.enableScrolling()},!1),e.addEventListener("appbarexpanded",function(){var a=b.getScroller(),c=d.engine.getBinding(a,"Scrollview");c&&c.disableScrolling()},!1)),f&&(c.addEventListener("showGoToTopButton",b._showGoToTopButton.bind(b),!1),c.addEventListener("hideGoToTopButton",b._hideGoToTopButton.bind(b),!1),f.addEventListener("vclick",b._handleGoToTopButtonClick.bind(b),!1))},u._refresh=function(){this._findMainTab(),this._restoreContentStyle(),this._contentFill()},u.layout=function(){this._findMainTab(),this._storeContentStyle(),this._contentFill()},u.onBeforeShow=function(){var a=this,b=a.getScroller();b&&(b.scrollTop=a._lastScrollPosition||0),"function"==typeof a.enableKeyboardSupport&&(a.enableKeyboardSupport(),a._bindEventKey()),a.trigger(n.BEFORE_SHOW)},u.onShow=function(){this.trigger(n.SHOW)},u.onBeforeHide=function(){var a=this,b=a.getScroller();b&&(a._lastScrollPosition=b.scrollTop),"function"==typeof a.disableKeyboardSupport&&(a.disableKeyboardSupport(),a._destroyEventKey()),a.trigger(n.BEFORE_HIDE)},u.onHide=function(){this._restoreContentStyle(),this.trigger(n.HIDE)},u._destroy=function(b){var c=this;b=b||c.element,a.removeEventListener("resize",c._contentFillAfterResizeCallback,!1),j.destroyAllWidgets(b,!0),c._contentFillAfterResizeCallback=null},u.getScroller=function(){var a=this.element,b=a.querySelector("."+o.uiScroller);return b||a.querySelector("."+o.uiContent)||a},u.setLastScrollPosition=function(a){this._lastScrollPosition=a},m.prototype=u,m.createEmptyElement=function(){var a=b.createElement("div");return a.classList.add(o.uiPage),a},j.defineWidget("Page",m.selector,["focus","blur","setActive"],m,"mobile"),d.widget.core.Page=m}(a.document,d),function(){function a(a){return l[a]}function b(a,b){l[a]=b}function c(a,b){k[a]=b}function e(a){k[a]=null}function f(a){return k[a]}function g(a,b){var c=d.info.profile,e=a.lastIndexOf(".");return j.isAbsoluteUrl(a)?a:(b&&(a=a.substring(0,e)+"."+c+a.substring(e)),j.makeUrlAbsolute((l.pathPrefix||"")+a,j.getLocation()))}function h(b,c,e,f){var h,i=k[f||a("default")||""],j=function(a,b){a.absUrl=h,e(a,b)},m=function(a,d){a.success?j(a,d):(h=g(b,!1),i(l,h,c||{},j))};i||(i=k[Object.keys(k).pop()]),i?(h=g(b,d.getConfig("findProfileFile",!1)),i(l,h,c||{},m)):e({success:!1,description:"Can't get engine system"},null)}var i,j=d.util.path,k={},l={pathPrefix:"","default":""};i={get:a,set:b,register:c,unregister:e,engine:f,render:h},d.template=i}(),function(a,b){function c(a){for(;a&&(a.nodeType!==Node.ELEMENT_NODE||!a.nodeName||"A"!==a.nodeName);)a=a.parentNode;return a}function e(a,b){var d,e,f,g=c(b.target);g&&1===b.which&&(d=g.getAttribute("href"),e="external"===g.getAttribute("rel")||g.hasAttribute("target"),e||(f=q.getData(g),a.open(d,f,b),p.preventDefault(b)))}function f(a,b){var c,d,e,f,g,h=v.route,i=w.activeState,j=b&&"back"===w.getDirection(b),k=[],l=r.getLocation(),m=!0;f=j?i&&i.transition||"none":b.transition,e=t.merge({},b,{reverse:j,transition:f,fromHashChange:!0});for(d in h)h.hasOwnProperty(d)&&h[d].active&&k.push(h[d].orderNumber);if(c=Math.max.apply(null,k),g=h[D[c]],g&&g.onHashChange(l,e,i)){if(10===c)return;m=!1}w.setActive(b),m&&a.open(b.url,e)}function g(a){var b=G.classes,c="."+b.uiPageActive,d=B.call(a.querySelectorAll(c));d.forEach(function(a){a.classList.remove(c)})}function h(a,b){f(a,b.detail)}function i(a,b){var c=b.detail,d=c.reverse?c.url:c.href||c.url;delete c.event,a.open(d,c),p.preventDefault(b),p.stopImmediatePropagation(b)}function j(a,c){var e=null,f=b.implementation.createHTMLDocument(c),g=f.body;if(a instanceof HTMLElement)e=a;else try{g.insertAdjacentHTML("beforeend",a),e=g.firstChild}catch(h){d.error("Failed to inject element",h)}return e}function k(a,b){b&&a instanceof HTMLElement&&!q.hasNSData(a,"url")&&(b=b.replace(/^#/,""),q.setNSData(a,"url",b))}function l(a,b){var c,d=b.detail,e=d.content,f=d.options,g=f.href||f.url;e&&(c=j(e,f.title),k(c,g),a.open(c,f),p.preventDefault(b))}function m(a){var c,d;return"string"==typeof a&&(c="#"===a[0]?a.substr(1):a,d=b.getElementById(c),d&&(a=d)),a}var n,o=d.util,p=d.event,q=o.DOM,r=o.path,s=o.selectors,t=o.object,u=d.engine,v=d.router,w=d.history,x=w.manager,y=x.events,z=v.route,A=b.body,B=[].slice,C=!1,D={1:"page",10:"panel",100:"popup",101:"dialog",1e3:"drawer",2e3:"circularindexscrollbar"},E={BEFORE_ROUTER_INIT:"beforerouterinit",ROUTER_INIT:"routerinit"},F=/[#|\s]/g,G=d.widget.core.Page,H=d.template,I=function(){var a=this;a.container=null,a.settings={},a._onStateChangeHandler=null,a._onHashChangeHandler=null,a._onControllerContent=null,a.locked=!1};I.prototype.defaults={fromHashChange:!1,reverse:!1,volatileRecord:!1},I.prototype.linkClick=function(a){e(this,a)},I.prototype.detectRel=function(a){var b,c;for(c in z)if(z.hasOwnProperty(c)&&(b=z[c],s.matchesSelector(a,b.filter)))return c;return null},I.prototype._openDeferred=function(a,b,c){var d=this,e=z[b.rel],f={resolve:function(a,b){e.open(b,a,c)},reject:function(a){p.trigger(d.container.element,"changefailed",a)}};"string"==typeof a?a.replace(F,"")&&d._loadUrl(a,b,e,f):a&&s.matchesSelector(a,e.filter)?f.resolve(b,a):f.reject(b)},I.prototype.open=function(a,b,c){var d,e,f=this;if(!C)if(a=m(a),d=b&&b.rel||a instanceof HTMLElement&&f.detectRel(a),d=d||"page",e=z[d],"back"===d)w.back();else{if(!e)throw new Error("Not defined router rule ["+d+"]");b=t.merge({rel:d},f.defaults,e.option(),b),f._openDeferred(a,b,c)}},I.prototype._initRoutes=function(){var a,b=v.route;for(a in b)b.hasOwnProperty(a)&&b[a].init&&b[a].init()},I.prototype._autoInitializePage=function(c,e,f){var h,i=this,j=a.location,k=G.classes.uiPageActive,l=c.querySelector("."+k);if(l||(l=e[0]),l&&g(c),j.hash&&(h=b.getElementById(j.hash.replace("#","")),h&&s.matchesSelector(h,f)&&(l=h)),!l&&d.getConfig("addPageIfNotExist",!0)){for(l=G.createEmptyElement();c.firstChild;)l.appendChild(c.firstChild);c.appendChild(l)}return i.justBuild&&l&&i.register(u.instanceWidget(c,"pagecontainer"),l),l},I.prototype.init=function(a){var c,e,f,g=d.engine.getWidgetDefinition("Page"),h=g.selector,i=this;p.trigger(b,E.BEFORE_ROUTER_INIT,i,!1),A=b.body,i.justBuild=a,c=d.getConfig("pageContainer")||A,f=B.call(c.querySelectorAll(h)),d.getConfig("pageContainerBody",!1)||(c=f.length?f[0].parentNode:c),d.getConfig("autoInitializePage",!0)&&(e=i._autoInitializePage(c,f,h),a)||(x.enable(),i._initRoutes(),i.register(u.instanceWidget(c,"pagecontainer"),e),p.trigger(b,E.ROUTER_INIT,i,!1))},I.prototype.destroy=function(){var b=this,c=this.getRoute("panel");x.disable(),a.removeEventListener("popstate",b.popStateHandler,!1),c&&a.removeEventListener("tauback",c.tauback,!1),A&&(A.removeEventListener("pagebeforechange",b.pagebeforechangeHandler,!1),A.removeEventListener("vclick",b.linkClickHandler,!1)),d.setConfig("pageContainer",null)},I.prototype.setContainer=function(a){this.container=a},I.prototype.getContainer=function(){return this.container},I.prototype.getFirstPage=function(){return this.getRoute("page").getFirstElement()},I.prototype.register=function(c,e){var f=this,g=this.getRoute("popup");f.container=c,f.getRoute("page").setFirstElement(e),p.trigger(b,"themeinit",f),f._onHashChangeHandler||(f._onHashChangeHandler=h.bind(null,f),a.addEventListener(y.HASHCHANGE,f._onHashChangeHandler,!1)),f._onStateChangeHandler||(f._onStateChangeHandler=i.bind(null,f),a.addEventListener(y.STATECHANGE,f._onStateChangeHandler,!1)),f._onControllerContent||(f._onControllerContent=l.bind(null,f),a.addEventListener("controller-content-available",f._onControllerContent,!1)),d.getConfig("loader",!1)&&c.element.appendChild(f.getLoader().element),w.enableVolatileMode(),e&&f.open(e,{transition:"none"}),g&&g.setActive(null)},I.prototype.close=function(a,b){var c,d="back",e=m(a);if(b&&b.rel?d=b.rel:e&&(d=this.detectRel(e)),c=z[d],!this.locked)if("back"===d)w.back();else{if(!c)throw new Error("Not defined router rule ["+d+"]");c.close(e,b)}},I.prototype.back=function(){this.locked||w.back()},I.prototype.openPopup=function(a,b){this.open(a,t.fastMerge({rel:"popup"},b))},I.prototype.closePopup=function(a){var b=this.getRoute("popup");b&&b.close(null,a)},I.prototype.lock=function(){this.locked=!0},I.prototype.unlock=function(){this.locked=!1},I.prototype._loadUrl=function(a,b,c,d){var e,f=r.makeUrlAbsolute(a,r.getLocation()),g=this,h=b.data||{};e=c.find(f),!e&&r.isEmbedded(f)?d.reject({}):e?d.resolve(t.fastMerge({absUrl:f},b),e):(p.trigger(g.getContainer().element,b.rel+"beforeload"),h.fullDocument=!0,H.render(a,h,function(a,e){a.success?(g._loadSuccess(a.absUrl,b,c,d,e),p.trigger(g.getContainer().element,b.rel+"load")):g._loadError(a.absUrl,b,d)}))},I.prototype._loadError=function(a,b,c){var e=t.fastMerge({url:a},b),f=this;d.error("load error, file: ",a),f.container.trigger("loadfailed",e),c.reject(e)},I.prototype._loadSuccess=function(a,b,c,d,e){var f=t.fastMerge({url:a},b),g=c.parse(e,a);g?d.resolve(f,g):d.reject(f)},I.prototype._getInitialContent=function(){return this.getRoute("page").getFirstElement()},I.prototype._showError=function(a){d.error("load error, file: ",a)},I.prototype.getActive=function(a){var b=this.getRoute(a||"page");return b&&b.getActive()},I.prototype.hasActive=function(a){var b=this.getRoute(a||"page");return!(!b||!b.hasActive())},I.prototype.hasActivePopup=function(){return this.hasActive("popup")},I.prototype.getRoute=function(a){return z[a]},I.prototype.getLoader=function(){var a,c=u.getWidgetDefinition("Loader"),d=c.selector;return c?(a=b.querySelector(d),u.instanceWidget(a,"Loader")):null},I.newInstance=function(){return n=new I},I.getInstance=function(){return n?n:this.newInstance()},v.Router=I,I.eventType=E,u.getRouter=function(){return d.warn("getRouter() method is deprecated! Use tau.router.Router.getInstance() instead"),I.getInstance()},d.getConfig("disableRouter",!1)||(b.addEventListener(u.eventType.READY,function(){I.getInstance().init()},!1),b.addEventListener(u.eventType.DESTROY,function(){I.getInstance().destroy()},!1),b.addEventListener(u.eventType.STOP_ROUTING,function(){I.getInstance().destroy()},!1))}(a,a.document),function(a,b){var e=d.engine,f=d.jqm.jQuery,g=d.router.Router.eventType,h={beforeinit:function(){var a,e=d.router.Router.getInstance();f&&(f.mobile?(f.mobile.pageContainer&&(a=f.mobile.pageContainer,a instanceof f&&(a=a[0]),a instanceof HTMLElement||(a=b.body),d.setConfig("pageContainer",a),f.mobile.pageContainer=f(a)),f.mobile.autoInitializePage!==c&&d.setConfig("autoInitializePage",f.mobile.autoInitializePage),f.mobile._bindPageRemove!==c&&d.setConfig("_bindPageRemove",f.mobile._bindPageRemove),f.mobile.changePage=function(a,b){var c;return a instanceof f?(c=f(a).get(0),e.open(c,b)):e.open(a,b)},b.addEventListener("pagechange",function(){var a=e.getRoute("page"),b=a&&a.getActive(),c=b&&b.element;f.mobile.activePage=f(c)},!0),f.mobile.activePage=f(),f.mobile.firstPage=f(e.getRoute("page").getFirstElement()),f.mobile.pageContainer=f(),f.mobile.subPageUrlKey=d.widget.core.Page.classes.uiPage,f.mobile.ajaxEnabled=!0,f.mobile.hashListeningEnabled=!0,f.mobile.linkBindingEnabled=!0,f.mobile.maxTransitionWidth=!1,f.mobile.minScrollBack=250,f.mobile.touchOverflowEnabled=!1,f.mobile.defaultDialogTransition="pop",f.mobile.pageLoadErrorMessage="Error Loading Page",f.mobile.pageLoadErrorMessageTheme="e",f.mobile.phonegapNavigationEnabled=!1,f.mobile.autoInitializePage=!1,f.mobile.pushStateEnabled=!0,f.mobile.ignoreContentEnabled=!1,f.mobile.orientationChangeEnabled=!0,f.mobile.ajaxBlacklist=!1,f.mobile.defaultTransitionHandler=null,f.mobile.transitionHandlers={},f.mobile.transitionFallbacks={},f.mobile._maybeDegradeTransition=null,f.mobile.focusPage=null,f.mobile.dialogHashKey="&ui-state=dialog",f.mobile.allowCrossDomainPages=!1,f.mobile.getDocumentUrl=d.util.path.getDocumentUrl,f.mobile.getDocumentBase=d.util.path.getDocumentBase,f.mobile._bindPageRemove=null,f.mobile.loadPage=e.loadPage===c?d.error.bind(null,"router PageExternal is not loaded"):e.loadPage.bind(e),f.mobile.navreadyDeferred=e.navreadyDeferred,f.mobile.initializePage=null,f.mobile._handleHashChange=e._hashChangeHandler):f.mobile={})},init:function(){var a,b,g,h=d.router.Router.getInstance();if(f){if(f.mobile.defaultPageTransition="none",h.getTransitions){a=h.getTransitions();for(b in a)a.hasOwnProperty(b)&&(a[b].fallback!==c&&(f.mobile.transitionFallbacks[b]=a[b].fallback),a[b].handler!==c&&(f.mobile.transitionHandlers[b]=a[b].handler));f.mobile.defaultTransitionHandler=a.sequential.handler,f.mobile._maybeDegradeTransition=h._maybeDegradeTransition.bind(h),f.mobile.getMaxScrollForTransition=h.getMaxScrollForTransition.bind(h)}f.mobile.focusPage=function(a){var b=f(a)[0],c=e.getBinding(b);c.focus()},f.mobile.initializePage=h.init.bind(h),g=h.getContainer(),g&&(f.mobile.pageContainer=f(g.element))}},destroy:function(){b.removeEventListener(g.ROUTER_INIT,h.init,!1),b.removeEventListener(g.BEFORE_ROUTER_INIT,h.beforeinit,!1),b.removeEventListener(g.DESTROY,h.destroy,!1)}};b.addEventListener(g.ROUTER_INIT,h.init,!1),b.addEventListener(g.BEFORE_ROUTER_INIT,h.beforeinit,!1),b.addEventListener(g.DESTROY,h.destroy,!1),d.jqm.router=h}(a,a.document),function(a,b){var e=d.support,f=d.jqm.jQuery,g=d.util.object,h=d.engine.eventType,i={touch:b.ontouchend!==c,init:function(){var a=d.router.Router.getInstance();f&&(d.support=g.merge(f.support,e),f.mobile=f.mobile||{},f.mobile.support=f.mobile.support||{},f.mobile.support.touch=e.touch,f.mobile.base=e.dynamicBaseTag&&{element:a.resetBase===c?d.error.bind(null,"router PageExternal is not loaded"):a.resetBase(),set:a.setBase===c?d.error.bind(null,"router PageExternal is not loaded"):a.setBase.bind(a),reset:a.resetBase===c?d.error.bind(null,"router PageExternal is not loaded"):a.resetBase.bind(a)},f.mobile.gradeA=d.support.gradeA.bind(d.support),f.mobile.browser=d.support.browser)},destroy:function(){b.removeEventListener(h.INIT,i.init,!1),b.removeEventListener(h.DESTROY,i.destroy,!1)}};b.addEventListener(h.INIT,i.init,!1),b.addEventListener(h.DESTROY,i.destroy,!1),d.jqm.support=i}(a,a.document),function(a,b,c){c.util.colors={nearestInt:function(a){var b=Math.floor(a);return a-b>.5?b+1:b},HTMLToRGB:function(a){return a="#"===a.charAt(0)?a.substring(1):a,[a.substring(0,2),a.substring(2,4),a.substring(4,6)].map(function(a){return parseInt(a,16)/255})},RGBToHTML:function(a){return"#"+a.map(function(a){var b=255*a,c=Math.floor(b);return b=b-c>.5?c+1:c,b=(16>b?"0":"")+(255&b).toString(16)}).join("")},HSLToRGB:function(a){var b,c,d,e,f=a[0]/360,g=a[1],h=a[2];return 0===g?e=[h,h,h]:(c=.5>h?h*(1+g):h+g-h*g,b=2*h-c,d={r:f+1/3,g:f,b:f-1/3},d.r=d.r<0?d.r+1:d.r>1?d.r-1:d.r,d.g=d.g<0?d.g+1:d.g>1?d.g-1:d.g,d.b=d.b<0?d.b+1:d.b>1?d.b-1:d.b,e=[6*d.r<1?b+6*(c-b)*d.r:2*d.r<1?c:3*d.r<2?b+(c-b)*(2/3-d.r)*6:b,6*d.g<1?b+6*(c-b)*d.g:2*d.g<1?c:3*d.g<2?b+(c-b)*(2/3-d.g)*6:b,6*d.b<1?b+6*(c-b)*d.b:2*d.b<1?c:3*d.b<2?b+(c-b)*(2/3-d.b)*6:b]),e},HSVToRGB:function(a){return this.HSLToRGB(this.HSVToHSL(a))},RGBToHSV:function(a){var b,c,d,e,f,g,h=a[0],i=a[1],j=a[2];return b=Math.min(h,Math.min(i,j)),c=Math.max(h,Math.max(i,j)),d=c-b,e=0,f=0,g=c,d>1e-5&&(f=d/c,e=h===c?(i-j)/d:i===c?2+(j-h)/d:4+(h-i)/d,e*=60,0>e&&(e+=360)),[e,f,g]},HSVToHSL:function(a){var b=a[2],c=a[1]*b,d=b-c,e=b+d,f=e/2,g=.5>f?e:2-b-d;return[a[0],0===g?0:c/g,f]},RGBToHSL:function(a){return this.HSVToHSL(this.RGBToHSV(a))}}}(a,a.document,d),function(b){var c=d.engine.eventType,e=d.jqm.jQuery,f={init:function(){e&&(e.mobile.tizen.clrlib=f)},destroy:function(){b.removeEventListener(c.INIT,f.init,!1),b.removeEventListener(c.DESTROY,f.destroy,!1),e&&delete e.mobile.tizen.clrlib,a.ns=null,e=null,c=null,f=null}};b.addEventListener(c.INIT,f.init,!1),b.addEventListener(c.DESTROY,f.destroy,!1)}(a.document),function(a,b,c){function d(a){return x.getClosestBySelector(a,"a, label")}function e(a){return x.getClosestByClass(a,v.BUTTON)||x.getClosestByClass(a,v.HEADER_BUTTON)||x.getClosestByClass(a,v.NAVIGATION_BUTTON)||x.getClosestByClass(a,v.SUBTAB_ANCHOR)}function f(a){var b=a.target,c=b.classList;c.contains(v.ACTIVE_BTN)&&!c.contains(v.INACTIVE_BTN)?(B._activeAnimationFinished=!0,(B._touchEnd||b!==B._buttonTarget)&&c.add(v.INACTIVE_BTN)):(c.contains(v.ACTIVE_BTN)||c.contains(v.INACTIVE_BTN)||(b.parentNode.classList.remove(v.ACTIVE_BTN),b.parentNode.classList.remove(v.INACTIVE_BTN)),c.remove(v.INACTIVE_BTN),c.remove(v.ACTIVE_BTN))}function g(){B._buttonTarget&&(B._buttonTarget.classList.add(v.INACTIVE_BTN),B._buttonTarget.classList.remove(v.ACTIVE_BTN))}function h(){B._buttonTarget.classList.add(v.ACTIVE_BTN),B._activeAnimationFinished=!1}function i(){var a=B._buttonTarget;a&&(a.classList.remove(v.ACTIVE_BTN),a.classList.remove(v.INACTIVE_BTN)),B._target&&B._target.classList.remove(v.ACTIVE_LI)}function j(){var a,b;B._startTime&&(b=Date.now()-B._startTime,b>B.options.addActiveClassDelay?(B._startTime=0,B._buttonTarget=e(B._target),B._target=d(B._target),B._didScroll||(B._liTarget=B._detectLiElement(B._target),B._buttonTarget?(a=B._buttonTarget.classList,a.remove(v.ACTIVE_BTN),a.remove(v.INACTIVE_BTN),B._requestAnimationFrame(h)):B._liTarget&&(B._liTarget.classList.add(v.ACTIVE_LI),y.trigger(B._liTarget,w.ACTIVE_LI,{})))):B._requestAnimationFrame(j))}function k(){return C.call(a.getElementsByClassName(v.ACTIVE_LI))}function l(){for(var a=k(),b=a.length,c=0;b>c;c++)a[c].classList.remove(v.ACTIVE_LI)}function m(){var a=Date.now()-B._startRemoveTime;a>B.options.keepActiveClassDelay?l():B._requestAnimationFrame(m)}function n(a){var b=a.touches[0],c=B.options.scrollThreshold;!B._didScroll&&(z(b.clientX-t)>c||z(b.clientY-u)>c)&&(B._startTime=0,B._requestAnimationFrame(l),B._didScroll=!0)}function o(a){var b=a.touches,c=b?1===b.length?b[0]:null:a;c&&(B._didScroll=!1,t=c.clientX,u=c.clientY,B._target=a.target,B._startTime=Date.now(),B._startRemoveTime=0,B._requestAnimationFrame(j),B._touchEnd=!1)}function p(a){B._startRemoveTime=a.timeStamp,(!a.touches||a.touches&&0===a.touches.length)&&(B._didScroll||(B._startTime=0,B._requestAnimationFrame(m)),B._activeAnimationFinished&&B._requestAnimationFrame(g),B._didScroll=!1,B._touchEnd=!0)}function q(){"hidden"===a.visibilityState&&B._removeActiveClassLoop()}function r(){a.addEventListener("touchstart",B._touchstartHandler,!1),a.addEventListener("touchend",B._touchendHandler,!1),a.addEventListener("touchmove",B._touchmoveHandler,!1),a.addEventListener("mousedown",B._touchstartHandler,!1),a.addEventListener("mouseup",B._touchendHandler,!1),a.addEventListener("visibilitychange",B._checkPageVisibility,!1),a.addEventListener("pagehide",B._hideClear,!1),a.addEventListener("popuphide",B._hideClear,!1),a.addEventListener("animationend",B._clearBtnActiveClass,!1),a.addEventListener("animationEnd",B._clearBtnActiveClass,!1),a.addEventListener("webkitAnimationEnd",B._clearBtnActiveClass,!1)}function s(){a.removeEventListener("touchstart",B._touchstartHandler,!1),a.removeEventListener("touchend",B._touchendHandler,!1),a.removeEventListener("touchmove",B._touchmoveHandler,!1),a.removeEventListener("mousedown",B._touchstartHandler,!1),a.removeEventListener("mouseup",B._touchendHandler,!1),a.removeEventListener("visibilitychange",B._checkPageVisibility,!1),a.removeEventListener("pagehide",B._hideClear,!1),a.removeEventListener("popuphide",B._hideClear,!1),a.removeEventListener("animationend",B._clearBtnActiveClass,!1),a.removeEventListener("animationEnd",B._clearBtnActiveClass,!1),a.removeEventListener("webkitAnimationEnd",B._clearBtnActiveClass,!1)}var t=0,u=0,v={ACTIVE_LI:"ui-li-active",ACTIVE_BTN:"ui-btn-active",INACTIVE_BTN:"ui-btn-inactive",BUTTON:"ui-btn",HEADER_BUTTON:"ui-header-btn",SUBTAB_ANCHOR:"ui-sub-tab-anchor",NAVIGATION_BUTTON:"ui-navigation-item"},w={ACTIVE_LI:"anchorhighlightactiveli"},x=c.util.selectors,y=c.event,z=Math.abs,A=function(a){return x.getClosestByTag(a,"li")},B={options:{scrollThreshold:10,addActiveClassDelay:50,keepActiveClassDelay:100},_startTime:0,_startRemoveTime:0,_touchEnd:!1,_liTarget:null,_target:null,_didScroll:!1,_buttonTarget:null,_activeAnimationFinished:!1,_requestAnimationFrame:c.util.windowRequestAnimationFrame},C=Array.prototype.slice;c.util.anchorHighlight=B,B.enable=r,B.disable=s,B._clearActiveClass=l,B._detectHighlightTarget=d,B._detectBtnElement=e,B._removeActiveClassLoop=m,B._addButtonInactiveClass=g,B._addButtonActiveClass=h,B._addActiveClass=j,B._detectLiElement=A,B._touchmoveHandler=n,B._touchendHandler=p,B._touchstartHandler=o,B._checkPageVisibility=q,B._hideClear=i,B._clearBtnActiveClass=f,r()}(b,a,d),function(a){function b(a,b,d){a.forEach(function(a){c.matchesSelector(a,b)&&a.classList.add(d)})}var c=a.util.selectors,d=[].slice,e=[null,"solo","a","b","c","d"];a.util.grid={makeGrid:function(a,c){var f,g=a.classList,h=d.call(a.children);c||(c=e[h.length],c||(c="a",f=2,g.add("ui-grid-duo"))),f||(f=e.indexOf(c)),g.add("ui-grid-"+c),b(h,":nth-child("+f+"n+1)","ui-block-a"),f>1&&b(h,":nth-child("+f+"n+2)","ui-block-b"),f>2&&b(h,":nth-child("+f+"n+3)","ui-block-c"),f>3&&b(h,":nth-child("+f+"n+4)","ui-block-d"),f>4&&b(h,":nth-child("+f+"n+5)","ui-block-e")}}}(d),function(a,b,d){var e={},f=d.event,g=d.util.object,h=b.body,i=function(a,b){var c,d,e="data-"+b;if(a.hasAttribute(e)){c=a.getAttribute(e);try{d=JSON.parse(c)}catch(f){}}return d},j=function(a,b){var c="data-"+b;a.hasAttribute(c)&&a.removeAttribute(c)},k=function(a){var b;if(a===c||null===a||a===!1)throw"Hashed object/primitive can not be undefined, null or false";return a instanceof Element&&a.hasAttribute("data-ns-hash")?a.getAttribute("data-ns-hash"):(a instanceof Object&&(a.__tauHash=a.__tauHash||d.getUniqueId()),b=typeof a+"-"+(a instanceof Object?a.__tauHash:a.toString()),a instanceof Element&&a.setAttribute("data-ns-hash",b),b)};d.util.data={set:function(a,b,c){var d=k(a);return d?(e[d]||(e[d]={}),e[d][b]=c,a instanceof Element&&f.trigger(a,"setData",{key:b,value:c}),f.trigger(h,"globalSetData",{element:a,key:b,value:c}),c):!1},get:function(a,b,d){var g,j=k(a);return j?(e[j]&&e[j][b]!==c&&(g=e[j][b]),a instanceof Element&&(g===c&&(g=i(a,b),e[j]=e[j]||{},e[j][b]=e[j][b]||g),f.trigger(a,"getData",{key:b,value:g})),f.trigger(h,"globalGetData",{element:a,key:b,value:g}),g):d},remove:function(a,b){var d,i=k(a);return i&&e[i]&&e[i][b]!==c?(d=e[i][b],e[i][b]=c,g.hasPropertiesOfValue(e[i],c)&&(e[i]=c),a instanceof Element&&(j(a,b),f.trigger(a,"removeData",{key:b,value:d})),f.trigger(h,"globalRemoveData",{element:a,key:b,value:d}),!0):!1}}}(a,a.document,d),function(a){var b=/([\-0-9.]*)(ms|s)?/i,c={convertToMiliseconds:function(a){var c,d=a.match(b),e=0;return 3===d.length&&(c=parseFloat(d[1])||0,"ms"===d[2]?e=c:"s"===d[2]&&(e=1e3*c)),e}};a.util.date=c}(d),function(a,b,c){var d=function(a){var b,d,e,f=0,g=[].slice.call(arguments),h=g.length,i=1!==h||a&&"function"==typeof a.promise?h:0,j=1===i?a:new c.util.deferred,k=function(a,c,d){return function(e){c[a]=this,d[a]=arguments.length>1?[].slice.call(arguments):e,d===b?j.notifyWith(c,d):--i||j.resolveWith(c,d)}};if(h>1)for(b=[],b.length=h,d=[],d.length=h,e=[],e.length=h;h>f;f++)g[f]&&"function"==typeof g[f].promise?g[f].promise().done(k(f,e,g)).fail(j.reject).progress(k(f,d,b)):--i;return i||j.resolveWith(e,g),j.promise()};c.util.deferredWhen=d}(a,a.document,d),function(a){var b,c=Math.PI/2,d=.001,e=function(a,b){var c=[b[0]-a[0],b[1]-a[1],b[2]-a[2]];return Math.sqrt(c[0]*c[0]+c[1]*c[1]+c[2]*c[2])};b=function(){return this},b.prototype={points:[],step:d,length:0,levels:[],init:function(a){return this.points=a.points,this.step=a.step||d,this.length=this.calculateTotalLength(),this.levels=this.calculateLevel(a.maxLevel)||[],this},calculateLevel:function(a){var b,c=this.length,d=c/a,e=[];if(!a)return null;for(b=0;a>b;b+=1)e[a-b]=this.getPercent(0,d*b);return e},calculateTotalLength:function(){var a,b=this.step,c=this.getPosition(0),d=c,f=0;for(a=b;1>=a;a+=b)c=this.getPosition(a),f+=e(d,c),d=c;return f},getPosition:function(a){var b=this.points,c=function(a,b,c,d,e){return Math.pow(1-e,3)*a+3*e*Math.pow(1-e,2)*b+3*Math.pow(e,2)*(1-e)*c+Math.pow(e,3)*d},d=[c(b[0][0],b[1][0],b[2][0],b[3][0],a),c(b[0][2],b[1][2],b[2][2],b[3][2],a)];return[d[0],0,d[1]]},getPercent:function(a,b){var c,d,f,g,h=this.step,i=0;for(a=a||0,c=this.getPosition(a),d=c,f=a+b,g=a+h;1>=g;g+=h){if(c=this.getPosition(g),i+=e(d,c),i>=f)return g;d=c}return 1},getAngle:function(a){var b=this.points,d=function(a,b,c,d,e){return 3*e*e*(-a+3*b-3*c+d)+6*e*(a-2*b+c)+3*(-a+b)},e=d(b[0][0],b[1][0],b[2][0],b[3][0],a),f=d(b[0][2],b[1][2],b[2][2],b[3][2],a);return Math.atan2(e,f)-c}},a.util.bezierCurve=new b}(d),function(a){a.util.anim=a.util.anim||{}}(d),function(a){var b=null,c=function(a,b,c){var d,e,f,g,h="@"+a+"keyframes "+b+" {";for(d=0,e=c.length;e>d;++d)if(g=c[d]){h+=d+"% { ";for(f in g)g.hasOwnProperty(f)&&(h+=f+": "+g[f]+"; ");h+="} "}return h+="} "},e=d.support.cssAnimationPrefix,f=function(f){var g,h=d.getUniqueId();b||(g=a.createElement("style"),g.appendChild(a.createTextNode("")),a.head.appendChild(g),b=g.sheet),b.insertRule(c(e,h,f),0),this.keyframes=b.rules[0],this.id=h};f.prototype.destroy=function(){var a,b,c=this.keyframes,d=c.parentStyleSheet,e=d.rules;for(a=0,b=e.length;b>a;++a)if(e[a]===c){d.deleteRule(a);break}},d.util.anim.Keyframes=f}(a.document),function(){var b=d.util.object,c=d.util.anim.Keyframes,e=d.util.DOM,f=d.util.date,g=d.support.cssAnimationPrefix,h=function(a){return a.trim()},i=function(a,b){return"string"==typeof a&&(a=a.split(",").map(h)),a.indexOf(b)},j=(g||"").replace(/\-/gi,""),k=j.length>0?j+"AnimationEnd":"animationEnd",l=0,m=1,n=2,o="function",p=function(a,b){var c=a.options,d=c.element,e=c.onEnd,f=c.onPause;if(b.animationName===a.keyframes.id)switch(a.state){case m:a.state=n,typeof e===o&&e(a,d,b);break;case l:typeof f===o&&f(a,d,b)}},q=function(b,c){var d,e,j,k,l,n,p=null,q=null;return b._applied||b._apply(),d=b.options,p=d.element,q=d.onPlay,e=p.style,j=b.keyframes,k=e.getPropertyValue(g+"animation-play-state"),l=k&&k.split(",").map(h)||[],n=j?i(e.getPropertyValue(g+"animation-name"),j.id):-1,n>-1&&(l[n]=c||"running",e.setProperty(g+"animation-play-state",l.join(",")),b.state=m,typeof q===o&&(a.clearTimeout(b.playTimer),b.playTimer=a.setTimeout(function(){q(b,p)},f.convertToMiliseconds(d.delay)))),b},r=function(a){var c,d,f=this,g=b.merge({element:null,from:null,to:null,steps:[],duration:"0",direction:"normal",delay:"0",iterationCount:1,infinite:!1,fillMode:"none",preserve:!1,onEnd:null,onPause:null,onPlay:null,timingFunction:"ease",autoPlay:!1},a||{}),h=p.bind(null,this),i=g.element;0===g.steps.length?(c=[],c.length=101,g.to&&(c[100]=g.to),g.from?c[0]=g.from:g.to&&g.element&&(d=Object.keys(g.to),e.extractCSSProperties(g.element,d),c[0]=d)):c=g.steps,f.options=g,f.steps=c,f._applied=!1,f.keyframes=null,f.state=l,f.playTimer=null,this._endCallback=h,i&&(i.addEventListener(k,h,!1),g.autoPlay&&f.play())},s={};s._apply=function(){var a,b=this,d=b.options,e=d.element,f=e.style,i=f.getPropertyValue(g+"animation"),j=i&&i.split(",").map(h)||[];b.keyframes=new c(b.steps),a=b.keyframes.id,e&&(j.push(a+" "+d.duration+" "+d.timingFunction+" "+d.delay+" "+d.iterationCount+" "+d.direction+" "+d.fillMode),e.style.setProperty(g+"animation",j.join(",")),b._applied=!0)},s.step=function(a,b){var c=this;return c.steps[a]=b,c.reset()},s.reset=function(){var a=this,b=a.keyframes,d=a.options.element.style,e=d.getPropertyValue(g+"animation-name"),f=e&&e.split(",").map(h)||[],i=b?f.indexOf(b.id):-1;return a.keyframes&&a.keyframes.destroy(),b=new c(a.steps),i>-1&&(f[i]=b.id,a.keyframes=b,d.setProperty(g+"animation-name",f.join(","))),a},s.play=function(){return q(this,"running")},s.pause=function(){return q(this,"paused")},s.destroy=function(){var b,c,d,e=this,f=e.options.element,h=e.keyframes,i=e._endCallback;f&&(e._applied&&h&&(c=f.style,b=c.getPropertyValue(g+"animation"),b&&(d=new RegExp(",? ?"+h.id+"[^,%]*,? ?","i"),c.removeProperty(g+"animation",b.replace(d,""))),h.destroy(),e._applied=!1),i&&f.removeEventListener(k,i,!1)),a.clearTimeout(e.playTimer)},r.states={PAUSED:l,PLAYING:m,FINISHED:n},r.prototype=s,d.util.anim.Animation=r}(),function(){var a=d.util.anim.Animation,b=d.util.object,c=d.util.date,e=0,f=1,g=2,h="function",i=function(a,b){var c=a.options.onEnd,d=a.animations,e=d.indexOf(b);a.current=e,e===d.length-1&&(a.state=g,typeof c===h&&c(a))},j=function(a,c){var d=b.merge({conocurrent:!0,onPlay:null,onPause:null,onEnd:null},a||{}),f=this;f.current=null,f.animations=[],f.totalTime=0,f.options=d,f.state=e,c&&c.length>0&&f.addMultiple(c)},k={add:function(b){var d=b instanceof a?b:new a(b),e=d.options,f=c.convertToMiliseconds(e.duration),g=c.convertToMiliseconds(e.delay),j=e.onEnd,k=this;return typeof j===h?e.onEnd=function(a,b,c){j(a,b,c),i(k,a)}:e.onEnd=i.bind(null,k),k.options.concurrent===!1&&(e.delay=g+k.totalTime+"ms",k.totalTime+=g+f),k.animations.push(d),k.current||(k.current=0),k},addMultiple:function(a){var b,c;for(b=0,c=a.length;c>b;++b)this.add(a[b]);return this},play:function(){var a,b,c=this,d=c.options.onPlay;for(a=c.current,b=c.animations.length;b>a;++a)c.animations[a].play();return c.state=f,typeof d===h&&d(c),c},pause:function(){var a,b,c=this,d=c.options.onPause;for(a=c.current,b=c.animations.length;b>a;++a)c.animations[a].pause();return c.state=e,typeof d===h&&d(c),c},destroy:function(){var a,b;for(a=0,b=this.animations.length;b>a;++a)this.animations[a].destroy()}};j.states={PAUSED:e,PLAYING:f,FINISHED:g},j.prototype=k,d.util.anim.Chain=j}(),function(a,c){function d(){i.unbind(),i.bind()}function e(){b.removeEventListener(h.INIT,d,!1),b.removeEventListener(h.DESTROY,e,!1)}var f=function(a){var b,d,e,f=a.keyName,g=c.activePopup;if(c.getConfig("enableHWKeyHandler",!0)&&g){if(b=g._ui.container,d=b&&b.classList,"menu"===f&&(e=g.element.querySelector(".ui-focus")))return a.preventDefault(),void a.stopPropagation();("menu"===f||"back"===f)&&(!d||d.contains("ui-datetimepicker")&&!d.contains("in")||(g.close(),a.preventDefault(),a.stopPropagation()))}},g=function(a){var d,e,f=a.keyName;!c.getConfig("enableHWKeyHandler",!0)||"menu"!==f&&"back"!==f||(d=b.querySelector("div.ui-selectmenu-active select"),d&&(e=c.widget.SelectMenu(d),e.close(),a.preventDefault(),a.stopPropagation()))},h=c.engine.eventType,i={bind:function(){b.addEventListener("tizenhwkey",f,!0),b.addEventListener("tizenhwkey",g,!0)},unbind:function(){b.removeEventListener("tizenhwkey",f,!0),b.removeEventListener("tizenhwkey",g,!0)}};c.event.hwkey=i,b.addEventListener(h.INIT,d,!1),
+b.addEventListener(h.DESTROY,e,!1)}(a,d),function(a){var b,c={enabled:d.getConfig("enableThrottleResize",!0),ttl:250},e=d.event,f=function(){b&&a.clearTimeout(b),b=a.setTimeout(function(){e.trigger(a,"throttledresize")},c.ttl)},g=function(){c.enabled||(c.enabled=!0),a.addEventListener("resize",f,!0)},h=function(){c.enabled=!1,a.removeEventListener("resize",f,!0)};c.enabled&&g(),c.enable=g,c.unbind=h,d.event.throttledresize=c}(a),function(a){var b=a.event,c=function(b,c){return new a.event.gesture.Instance(b,c)};c.defaults={triggerEvent:!1,updateVelocityInterval:16,estimatedPointerTimeDifference:15},c.Orientation={VERTICAL:"vertical",HORIZONTAL:"horizontal"},c.Direction={UP:"up",DOWN:"down",LEFT:"left",RIGHT:"right"},c.Event={START:"start",MOVE:"move",END:"end",CANCEL:"cancel",BLOCKED:"blocked"},c.Result={PENDING:1,RUNNING:2,FINISHED:4,BLOCK:8},c.plugin={},c.createDetector=function(a,b,c){if(!a.plugin[a])throw a+" gesture is not supported";return new a.plugin[a](b,c)},b.gesture=c}(d),function(a){var b=a.event.gesture,c=a.util.object.merge,d=function(a,b){this.sender=b,this.strategy=a.create(),this.name=this.strategy.name,this.index=this.strategy.index||100,this.options=this.strategy.options||{}};d.prototype.detect=function(a){return this.strategy.handler(a,this.sender,this.strategy.options)},d.Sender={sendEvent:function(){}},d.plugin={},d.plugin.create=function(a){var b;return a.types||(a.types=[a.name]),b=function(b){this.options=c({},a.defaults,b)},b.prototype.create=function(){return c({options:this.options},a)},d.plugin[a.name]=b,b},b.Detector=d}(d),function(a,b){var c=a.event.gesture;c.utils={getCenter:function(a){var c=[],d=[];return[].forEach.call(a,function(a){c.push(isNaN(a.clientX)?a.pageX:a.clientX),d.push(isNaN(a.clientY)?a.pageY:a.clientY)}),{clientX:(b.min.apply(b,c)+b.max.apply(b,c))/2,clientY:(b.min.apply(b,d)+b.max.apply(b,d))/2}},getVelocity:function(a,c,d){return{x:b.abs(c/a)||0,y:b.abs(d/a)||0}},getAngle:function(a,c){var d=c.clientY-a.clientY,e=c.clientX-a.clientX;return 180*b.atan2(d,e)/b.PI},getDirection:function(a,d){var e=b.abs(a.clientX-d.clientX),f=b.abs(a.clientY-d.clientY);return e>=f?a.clientX-d.clientX>0?c.Direction.LEFT:c.Direction.RIGHT:a.clientY-d.clientY>0?c.Direction.UP:c.Direction.DOWN},getDistance:function(a,c){var d=c.clientX-a.clientX,e=c.clientY-a.clientY;return b.sqrt(d*d+e*e)},getScale:function(a,b){return a.length>=2&&b.length>=2?this.getDistance(b[0],b[1])/this.getDistance(a[0],a[1]):1},getRotation:function(a,b){return a.length>=2&&b.length>=2?this.getAngle(b[1],b[0])-this.getAngle(a[1],a[0]):0},isVertical:function(a){return a===c.Direction.UP||a===c.Direction.DOWN},isHorizontal:function(a){return a===c.Direction.LEFT||a===c.Direction.RIGHT},getOrientation:function(a){return this.isVertical(a)?c.Orientation.VERTICAL:c.Orientation.HORIZONTAL}}}(d,a.Math),function(a,b,c){function d(a,b){return a.index<b.index?-1:a.index>b.index?1:0}var e=a.event.gesture,f=e.utils,g=a.util.object,h=null,i=/touch/,j=function(){var a=this;a.instances=[],a.gestureDetectors=[],a.runningDetectors=[],a.detectorRequestedBlock=null,a.unregisterBlockList=[],a.gestureEvents={},a.velocity=null,a._isReadyDetecting=!1,a._blockMouseEvent=!1,a.touchSupport="ontouchstart"in b};j.prototype={_bindStartEvents:function(a){var b=a.getElement();this.touchSupport?b.addEventListener("touchstart",this,{passive:!1}):b.addEventListener("mousedown",this,!1)},_bindEvents:function(){var a=this;a.touchSupport?(c.addEventListener("touchmove",a,{passive:!1}),c.addEventListener("touchend",a,{passive:!1}),c.addEventListener("touchcancel",a,{passive:!1})):(c.addEventListener("mousemove",a),c.addEventListener("mouseup",a))},_unbindStartEvents:function(a){var b=a.getElement();this.touchSupport?b.removeEventListener("touchstart",this,{passive:!1}):b.removeEventListener("mousedown",this,!1)},_unbindEvents:function(){var a=this;a.touchSupport?(c.removeEventListener("touchmove",a,{passive:!1}),c.removeEventListener("touchend",a,{passive:!1}),c.removeEventListener("touchcancel",a,{passive:!1})):(c.removeEventListener("mousemove",a,!1),c.removeEventListener("mouseup",a,!1))},_detectEventType:function(a){var b=a.type;if(b.match(i))this._blockMouseEvent=!0;else if(this._blockMouseEvent||1!==a.which)return null;return b},handleEvent:function(a){var b=this,c=b._detectEventType(a);switch(c){case"mousedown":case"touchstart":b._start(a);break;case"mousemove":case"touchmove":b._move(a);break;case"mouseup":case"touchend":b._end(a);break;case"touchcancel":b._cancel(a)}},_start:function(a){var b=this,c=a.currentTarget,f={},h=[];b._isReadyDetecting||(b.resetDetecting(),b._bindEvents(),f=b._createDefaultEventData(e.Event.START,a),b.gestureEvents={start:f,last:f},b.velocity={event:f,x:0,y:0},f=g.fastMerge(f,b._createGestureEvent(e.Event.START,a)),b._isReadyDetecting=!0),b.instances.forEach(function(a){a.getElement()===c&&(h=h.concat(a.getGestureDetectors()))},b),h.sort(d),b.gestureDetectors=b.gestureDetectors.concat(h),b._detect(h,f)},_move:function(a){var b,c=this;c._isReadyDetecting&&(b=c._createGestureEvent(e.Event.MOVE,a),c._detect(c.gestureDetectors,b),c.gestureEvents.last=b)},_end:function(a){var b=this,c=g.merge({},b.gestureEvents.last,b._createDefaultEventData(e.Event.END,a));0===c.pointers.length&&(b._detect(b.gestureDetectors,c),b.unregisterBlockList.forEach(function(a){this.unregister(a)},b),b.resetDetecting(),b._blockMouseEvent=!1)},_cancel:function(a){var b=this;a=g.merge({},b.gestureEvents.last,b._createDefaultEventData(e.Event.CANCEL,a)),b._detect(b.gestureDetectors,a),b.unregisterBlockList.forEach(function(a){this.unregister(a)},b),b.resetDetecting(),b._blockMouseEvent=!1},_detect:function(a,b){var c=this,d=[];a.forEach(function(a){var f;c.detectorRequestedBlock||(f=a.detect(b),f&e.Result.RUNNING&&c.runningDetectors.indexOf(a)<0&&c.runningDetectors.push(a),f&e.Result.FINISHED&&d.push(a),f&e.Result.BLOCK&&(c.detectorRequestedBlock=a))}),d.forEach(function(a){var b=c.gestureDetectors.indexOf(a);b>-1&&c.gestureDetectors.splice(b,1),b=c.runningDetectors.indexOf(a),b>-1&&c.runningDetectors.splice(b,1)}),c.detectorRequestedBlock&&(c.runningDetectors.forEach(function(a){var c=g.fastMerge({},b);c.eventType=e.Event.BLOCKED,a.detect(c)}),c.runningDetectors.length=0,c.gestureDetectors.length=0,d.indexOf(c.detectorRequestedBlock)<0&&c.gestureDetectors.push(c.detectorRequestedBlock))},resetDetecting:function(){var a=this;a._isReadyDetecting=!1,a.gestureDetectors.length=0,a.runningDetectors.length=0,a.detectorRequestedBlock=null,a.gestureEvents={},a.velocity=null,a._unbindEvents()},_createDefaultEventData:function(a,b){var c=b.touches;return c||("mouseup"===b.type?c=[]:(b.identifier=1,c=[b])),{eventType:a,timeStamp:Date.now(),pointer:c[0],pointers:c,srcEvent:b,preventDefault:b.preventDefault.bind(b),stopPropagation:b.stopPropagation.bind(b)}},_createGestureEvent:function(a,b){var c,d=this,h=d._createDefaultEventData(a,b),i=d.gestureEvents.start,j=d.gestureEvents.last,k=d.velocity,l=k.event,m={time:h.timeStamp-i.timeStamp,x:h.pointer.clientX-i.pointer.clientX,y:h.pointer.clientY-i.pointer.clientY},n={x:h.pointer.clientX-j.pointer.clientX,y:h.pointer.clientY-j.pointer.clientY},o=e.defaults.estimatedPointerTimeDifference;return i&&h.pointers.length!==i.pointers.length&&(i.pointers=Array.prototype.slice.call(h.pointers)),h.timeStamp-l.timeStamp>e.defaults.updateVelocityInterval&&(g.fastMerge(k,f.getVelocity(h.timeStamp-l.timeStamp,h.pointer.clientX-l.pointer.clientX,h.pointer.clientY-l.pointer.clientY)),k.event=h),c={x:Math.round(h.pointer.clientX+o*k.x*(n.x<0?-1:1)),y:Math.round(h.pointer.clientY+o*k.y*(n.y<0?-1:1))},(n.x<0&&c.x>j.estimatedX||n.x>0&&c.x<j.estimatedX)&&(c.x=j.estimatedX),(n.y<0&&c.y>j.estimatedY||n.y>0&&c.y<j.estimatedY)&&(c.y=j.estimatedY),g.fastMerge(h,{deltaTime:m.time,deltaX:m.x,deltaY:m.y,velocityX:k.x,velocityY:k.y,estimatedX:c.x,estimatedY:c.y,estimatedDeltaX:c.x-i.pointer.clientX,estimatedDeltaY:c.y-i.pointer.clientY,distance:f.getDistance(i.pointer,h.pointer),angle:f.getAngle(i.pointer,h.pointer),direction:f.getDirection(i.pointer,h.pointer),scale:f.getScale(i.pointers,h.pointers),rotation:f.getRotation(i.pointers,h.pointers),startEvent:i,lastEvent:j}),h},register:function(a){var b=this,c=b.instances.indexOf(a);0>c&&(b.instances.push(a),b._bindStartEvents(a))},unregister:function(a){var b,c=this;c.gestureDetectors.length?c.unregisterBlockList.push(a):(b=c.instances.indexOf(a),b>-1&&(c.instances.splice(b,1),c._unbindStartEvents(a)),c.instances.length||c._destroy())},_destroy:function(){var a=this;a.resetDetecting(),a.instances.length=0,a.unregisterBlockList.length=0,a._blockMouseEvent=!1,h=null}},j.getInstance=function(){return h||(h=new j),h},e.Manager=j}(d,a,a.document),function(a){var b=a.event.gesture,c=b.Detector,d=b.Manager,e=a.event,f=a.util.object.merge,g=function(a,e){this.element=a,this.eventDetectors=[],this.options=f({},b.defaults,e),this.gestureManager=d.getInstance(),this.eventSender=f({},c.Sender,{sendEvent:this.trigger.bind(this)})};g.prototype={setOptions:function(a){return f(this.options,a),this},addDetector:function(a){var b=new c(a,this.eventSender),d=!!this.eventDetectors.length;return this.eventDetectors.push(b),this.eventDetectors.length&&!d&&this.gestureManager.register(this),this},removeDetector:function(a){var b=this.eventDetectors.indexOf(a);return b>-1&&this.eventDetectors.splice(b,1),this.eventDetectors.length||this.gestureManager.unregister(this),this},trigger:function(a,b){return e.trigger(this.element,a,b,!1)},getElement:function(){return this.element},getGestureDetectors:function(){return this.eventDetectors},destroy:function(){this.element=null,this.eventHandlers={},this.gestureManager=null,this.eventSender=null,this.eventDetectors.length=0}},b.Instance=g}(d),function(a,b,c){var d=a.event.gesture,e=d.utils,f=d.Detector,g=a.util.object.merge,h={start:"dragstart",drag:"drag",end:"dragend",cancel:"dragcancel",prepare:"dragprepare"},i=!!b.navigator.userAgent.match(/tizen/i)&&function(){var b,d=!0;if(c&&c.systeminfo&&c.systeminfo.getCapability)try{return b=c.systeminfo.getCapability("http://tizen.org/feature/platform.version"),"3.0">b}catch(e){a.error("Error name: "+e.name+", message: "+e.message)}return d}(),j=b.navigator.userAgent.indexOf("Chrome")>-1,k=d.Result,l=f.plugin.create({name:"drag",index:500,defaults:{blockHorizontal:!1,blockVertical:!1,threshold:20,delay:0},isTriggered:!1,handler:function(a,b,c){var f,l=c.threshold,m=k.PENDING,n=a.direction;if(!this.isTriggered&&a.eventType===d.Event.MOVE){if(Math.abs(a.deltaX)<l&&Math.abs(a.deltaY)<l)return j&&a.preventDefault(),k.PENDING;if(c.delay&&a.deltaTime<c.delay)return i||a.preventDefault(),k.PENDING;if(c.blockHorizontal&&e.isHorizontal(a.direction)||c.blockVertical&&e.isVertical(a.direction))return k.FINISHED;this.fixedStartPointX=0,this.fixedStartPointY=0,e.isHorizontal(a.direction)?this.fixedStartPointX=(a.deltaX<0?1:-1)*l:this.fixedStartPointY=(a.deltaY<0?1:-1)*l}switch(c.blockHorizontal&&(n=a.deltaY<0?d.Direction.UP:d.Direction.DOWN),c.blockVertical&&(n=a.deltaX<0?d.Direction.LEFT:d.Direction.RIGHT),f=g({},a,{deltaX:a.deltaX+this.fixedStartPointX,deltaY:a.deltaY+this.fixedStartPointY,estimatedDeltaX:a.estimatedDeltaX+this.fixedStartPointX,estimatedDeltaY:a.estimatedDeltaY+this.fixedStartPointY,direction:n}),f.eventType){case d.Event.START:this.isTriggered=!1,b.sendEvent(h.prepare,f)===!1&&(m=k.FINISHED);break;case d.Event.MOVE:this.isTriggered||b.sendEvent(h.start,f)!==!1||f.preventDefault(),m=b.sendEvent(h.drag,f)?k.RUNNING:k.FINISHED,m===!1&&f.preventDefault(),this.isTriggered=!0;break;case d.Event.BLOCKED:case d.Event.END:m=k.FINISHED,this.isTriggered&&(b.sendEvent(h.end,f)===!1&&f.preventDefault(),this.isTriggered=!1);break;case d.Event.CANCEL:m=k.FINISHED,this.isTriggered&&(b.sendEvent(h.cancel,f)===!1&&f.preventDefault(),this.isTriggered=!1)}return m}});a.event.gesture.Drag=l}(d,a,a.tizen),function(a){var b=a.event.gesture,c=b.Result,d=b.Detector,e=d.plugin.create({name:"swipe",index:400,defaults:{timeThreshold:400,velocity:.6,orientation:b.Orientation.HORIZONTAL},handler:function(a,d,e){var f=c.PENDING,g=e.velocity;return a.eventType===b.Event.END&&(a.deltaTime>e.timeThreshold||e.orientation!==b.utils.getOrientation(a.direction)?f=c.FINISHED:(a.velocityX>g||a.velocityY>g)&&(d.sendEvent(this.name,a),f=c.FINISHED|c.BLOCK)),f}});b.Swipe=e}(d),function(a){var b=a.event.gesture,c=b.Result,d=a.event.gesture.Detector,e={start:"pinchstart",move:"pinchmove",end:"pinchend",cancel:"pinchcancel","in":"pinchin",out:"pinchout"},f=d.plugin.create({name:"pinch",index:300,eventNames:e,defaults:{velocity:.6,timeThreshold:400},isTriggered:!1,handler:function(a,d,f){var g,h=c.PENDING;switch(a.eventType){case b.Event.MOVE:if(1===a.pointers.length&&a.distance>35)h=c.FINISHED;else if(!this.isTriggered&&a.pointers.length>=2)this.isTriggered=!0,d.sendEvent(e.start,a)===!1&&a.preventDefault(),h=c.RUNNING;else if(this.isTriggered){if(a.deltaTime<f.timeThreshold&&(a.velocityX>f.velocity||a.velocityY>f.velocity))return g=a.scale<1?d.sendEvent(e["in"],a):d.sendEvent(e.out,a),g===!1&&a.preventDefault(),this.isTriggered=!1,h=c.FINISHED|c.BLOCK;d.sendEvent(e.move,a)===!1&&a.preventDefault(),h=c.RUNNING}break;case b.Event.BLOCKED:case b.Event.END:this.isTriggered&&(d.sendEvent(e.end,a)===!1&&a.preventDefault(),this.isTriggered=!1,h=c.FINISHED);break;case b.Event.CANCEL:this.isTriggered&&(d.sendEvent(e.cancel,a)===!1&&a.preventDefault(),this.isTriggered=!1,h=c.FINISHED)}return h}});a.event.gesture.Pinch=f}(d),function(a){var b=a.event.gesture,c=b.Detector,d=c.plugin.create({name:"longpress",index:600,defaults:{longPressTimeThreshold:750,longPressDistanceThreshold:20,preventClick:!0},isTriggered:!1,longPressTimeOutId:0,handler:function(a,c,d){var e=b.Result.PENDING;switch(a.eventType){case b.Event.START:this.isTriggered=!1,this.longPressTimeOutId=setTimeout(function(){this.isTriggered=!0,c.sendEvent(this.name,a)}.bind(this),d.longPressTimeThreshold);break;case b.Event.MOVE:a.distance>d.longPressDistanceThreshold&&!this.isTriggered&&(clearTimeout(this.longPressTimeOutId),e=b.Result.FINISHED);break;case b.Event.END:this.isTriggered?d.preventClick&&a.preventDefault():clearTimeout(this.longPressTimeOutId),e=b.Result.FINISHED}return e}});b.LongPress=d}(d),function(a,b){b.widget.core.scroller=b.widget.core.scroller||{}}(a,d),function(a,b){b.widget.core.scroller.effect=b.widget.core.scroller.effect||{}}(a,d),function(a,b){var c=b.util.object,d=b.util.selectors,e=function(a,d){var f=this;f._orientation=null,f._maxScrollValue=null,f._container=null,f._effectElement={top:null,bottom:null,left:null,right:null},f.options=c.merge({},e.defaults,{scrollEndEffectArea:b.getConfig("scrollEndEffectArea",e.defaults.scrollEndEffectArea)}),f._targetElement=null,f._isShow=!1,f._isDrag=!1,f._isShowAnimating=!1,f._isHideAnimating=!1,f._create(a,d)},f={VERTICAL:"vertical",HORIZONTAL:"horizontal",VERTICAL_HORIZONTAL:"vertical-horizontal"},g={content:"content",screen:"screen"},h={duration:500,scrollEndEffectArea:"content"},i={bouncingEffect:"ui-scrollbar-bouncing-effect",page:"ui-page",left:"ui-left",right:"ui-right",top:"ui-top",bottom:"ui-bottom",hide:"ui-hide",show:"ui-show"};e.Orientation=f,e.defaults=h,e.prototype={_create:function(a,b){var c=this;c.options.scrollEndEffectArea===g.content?c._container=a:c._container=d.getClosestByClass(a,i.page),c._orientation=b.orientation,c._orientation===f.HORIZONTAL||c._orientation==f.VERTICAL?c._maxScrollValue=c._getValue(b.maxScrollX,b.maxScrollY):c._maxScrollValue={x:b.maxScrollX,y:b.maxScrollY},c._initLayout()},_createDivElement:function(){return a.createElement("DIV")},_initLayout:function(){var a=this,b=null,c=null,d=null,e=null,g=i.bouncingEffect;(a._orientation===f.HORIZONTAL||a._orientation==f.VERTICAL_HORIZONTAL)&&(b=a._createDivElement(),c=a._createDivElement(),b.className=g+" "+i.left,c.className=g+" "+i.right,a._container.appendChild(b),a._container.appendChild(c),a._registerAnimationEnd(b),a._registerAnimationEnd(c),a._effectElement.left=b,a._effectElement.right=c),(a._orientation===f.VERTICAL||a._orientation==f.VERTICAL_HORIZONTAL)&&(d=a._createDivElement(),e=a._createDivElement(),d.className=g+" "+i.top,e.className=g+" "+i.bottom,a._container.appendChild(d),a._container.appendChild(e),a._registerAnimationEnd(d),a._registerAnimationEnd(e),a._effectElement.top=d,a._effectElement.bottom=e)},_registerAnimationEnd:function(a){a.addEventListener("animationEnd",this),a.addEventListener("webkitAnimationEnd",this),a.addEventListener("mozAnimationEnd",this),a.addEventListener("msAnimationEnd",this),a.addEventListener("oAnimationEnd",this)},_unregisterAnimationEnd:function(a){a.removeEventListener("animationEnd",this),a.removeEventListener("webkitAnimationEnd",this),a.removeEventListener("mozAnimationEnd",this),a.removeEventListener("msAnimationEnd",this),a.removeEventListener("oAnimationEnd",this)},drag:function(a,b){this._isDrag=!0,this._checkAndShow(a,b)},dragEnd:function(){var a=this;!a._isShow||a._isShowAnimating||a._isHideAnimating||a._beginHide(),a._isDrag=!1},show:function(){var a=this;a._targetElement&&(a._isShow=!0,a._beginShow())},hide:function(){var a=this;a._isShow&&(a._targetElement.style.display="none",a._targetElement.classList.remove(i.hide),a._targetElement.classList.remove(i.show)),a._isShow=!1,a._isShowAnimating=!1,a._isHideAnimating=!1,a._targetElement=null},_checkAndShow:function(a,b){var c=this,d=null;c._isShow?!c._isShow||c._isDrag||c._isShowAnimating||c._isHideAnimating||c._beginHide():(c._orientation===f.HORIZONTAL||c._orientation===f.VERTICAL?(d=c._getValue(a,b),d>=0?c._targetElement=c._getMinEffectElement():d<=c._maxScrollValue&&(c._targetElement=c._getMaxEffectElement())):0==b?c._targetElement=c._effectElement.top:b==-c._maxScrollValue.y?c._targetElement=c._effectElement.bottom:0==a?c._targetElement=c._effectElement.left:a==-c._maxScrollValue.x&&(c._targetElement=c._effectElement.right),c.show())},_getValue:function(a,b){return this._orientation===f.VERTICAL_HORIZONTAL?null:this._orientation===f.HORIZONTAL?a:b},_getMinEffectElement:function(){var a=this;return a._orientation===f.VERTICAL_HORIZONTAL?null:a._orientation===f.HORIZONTAL?a._effectElement.left:a._effectElement.top},_getMaxEffectElement:function(){var a=this;return a._orientation===f.VERTICAL_HORIZONTAL?null:a._orientation===f.HORIZONTAL?a._effectElement.right:a._effectElement.bottom},_beginShow:function(){var a=this;a._targetElement&&!a._isShowAnimating&&(a._targetElement.style.display="block",a._targetElement.classList.remove(i.hide),a._targetElement.classList.add(i.show),a._isShowAnimating=!0,a._isHideAnimating=!1)},_finishShow:function(){var a=this;a._isShowAnimating=!1,a._isDrag||(a._targetElement.classList.remove(i.show),a._beginHide())},_beginHide:function(){var a=this;a._isHideAnimating||(a._targetElement.classList.remove(i.show),a._targetElement.classList.add(i.hide),a._isHideAnimating=!0,a._isShowAnimating=!1)},_finishHide:function(){var a=this;a._isHideAnimating=!1,a._targetElement.classList.remove(i.hide),a.hide(),a._checkAndShow()},handleEvent:function(a){a.type.toLowerCase().indexOf("animationend")>-1&&"-"!==a.animationName.charAt(0)&&(this._isShowAnimating?this._finishShow():this._isHideAnimating&&this._finishHide())},destroy:function(){var a=this,b=a._effectElement.top,c=a._effectElement.bottom,d=a._effectElement.left,e=a._effectElement.right;b&&(a._unregisterAnimationEnd(b),a._container.removeChild(b)),c&&(a._unregisterAnimationEnd(c),a._container.removeChild(c)),d&&(a._unregisterAnimationEnd(d),a._container.removeChild(d)),e&&(a._unregisterAnimationEnd(e),a._container.removeChild(e)),a._container=null,a._effectElement=null,a._targetElement=null,a._isShow=null,a._orientation=null,a._maxScrollValue=null}},b.widget.core.scroller.effect.Bouncing=e}(a.document,d),function(b,c){var d=c.widget.BaseWidget,e=c.engine,f=c.util.object,g=c.event,h=new d,i=c.widget.core.scroller.effect.Bouncing,j={START:"scrollstart",MOVE:"scrollmove",END:"scrollend",CANCEL:"scrollcancel"},k=!1,l=function(){};l.Orientation={VERTICAL:"vertical",HORIZONTAL:"horizontal"},l.EventType=j,h._build=function(a){return 1!==a.children.length?c.error("[Scroller] Scroller should have only one child."):(this.scroller=a.children[0],this.scrollerStyle=this.scroller.style,this.bouncingEffect=null,this.scrollbar=null,this.scrollerWidth=0,this.scrollerHeight=0,this.scrollerOffsetX=0,this.scrollerOffsetY=0,this.maxScrollX=0,this.maxScrollY=0,this.startScrollerOffsetX=0,this.startScrollerOffsetY=0,this.orientation=null,this.enabled=!0,this.scrolled=!1,this.dragging=!1,this.scrollCanceled=!1),a},h._configure=function(){this.options=f.merge({},this.options,{scrollDelay:0,threshold:30,scrollbar:"",useBouncingEffect:!0,orientation:"vertical"})},h._init=function(a){var b=null,c=this.options,d=null,e=a.style,f=null,g=a.offsetWidth/2,h=a.offsetHeight/2;return b=a.children[0],this.scroller=b,f=b.style,this.scrollerStyle=f,d=b.children,this.orientation=this.orientation||("horizontal"===c.orientation?l.Orientation.HORIZONTAL:l.Orientation.VERTICAL),this.scrollerWidth=b.offsetWidth,this.scrollerHeight=b.offsetHeight,d.length?(this.maxScrollX=g-this.scrollerWidth+d[d.length-1].offsetWidth/2,this.maxScrollY=h-this.scrollerHeight+d[d.length-1].offsetHeight/2,this.minScrollX=g-d[0].offsetWidth/2,this.minScrollY=h-d[0].offsetHeight/2):(this.maxScrollY=360,this.minScrollY=0),this.scrolled=!1,this.touching=!0,this.scrollCanceled=!1,this.orientation===l.Orientation.HORIZONTAL?this.maxScrollY=0:this.maxScrollX=0,e.overflow="hidden",e.position="relative",f.position="absolute",f.top="0px",f.left="0px",f.width=this.scrollerWidth+"px",f.height=this.scrollerHeight+"px",this._initScrollbar(),this._initBouncingEffect(),a},h._initScrollbar=function(){var a,b=this.options.scrollbar;b&&(a=c.widget.core.scroller.scrollbar.type[b],a&&(this.scrollbar=e.instanceWidget(this.element,"ScrollBar",{type:a,orientation:this.orientation})))},h._initBouncingEffect=function(){var a=this.options;a.useBouncingEffect&&(this.bouncingEffect=new i(this.element,{maxScrollX:this.maxScrollX,maxScrollY:this.maxScrollY,orientation:this.orientation}))},h._resetLayout=function(){var a=this.element.style,b=this.scrollerStyle;a.overflow="hidden",a.position="relative",b&&(b.position="",b.top="",b.left="",b.width="",b.height="",b["-webkit-transform"]="",b["-moz-transition"]="",b["-ms-transition"]="",b["-o-transition"]="",b.transition="")},h._bindEvents=function(){c.event.enableGesture(this.scroller,new c.event.gesture.Drag({threshold:this.options.threshold,delay:this.options.scrollDelay,blockVertical:this.orientation===l.Orientation.HORIZONTAL,blockHorizontal:this.orientation===l.Orientation.VERTICAL})),g.on(this.scroller,"drag dragstart dragend dragcancel",this),a.addEventListener("resize",this)},h._unbindEvents=function(){this.scroller&&(c.event.disableGesture(this.scroller),g.off(this.scroller,"drag dragstart dragend dragcancel",this),a.removeEventListener("resize",this))},h.handleEvent=function(a){switch(a.type){case"dragstart":this._start(a);break;case"drag":this._move(a);break;case"dragend":this._end(a);break;case"dragcancel":this._cancel(a);break;case"resize":this.refresh()}},h._refresh=function(){this._unbindEvents(),this._clear(),this._init(this.element),this._bindEvents()},h.scrollTo=function(a,b,c){this._translate(a,b,c),this._translateScrollbar(a,b,c)},h._translate=function(b,c,d){var e,f={normal:"none",webkit:"none",moz:"none",ms:"none",o:"none"},g=this.scrollerStyle;d&&(f.normal="transform "+d/1e3+"s ease-out",f.webkit="-webkit-transform "+d/1e3+"s ease-out",f.moz="-moz-transform "+d/1e3+"s ease-out",f.ms="-ms-transform "+d/1e3+"s ease-out",f.o="-o-transform "+d/1e3+"s ease-out"),e="translate3d("+b+"px,"+c+"px, 0)",g["-webkit-transform"]=g["-moz-transform"]=g["-ms-transform"]=g["-o-transform"]=g.transform=e,g.transition=f.normal,g["-webkit-transition"]=f.webkit,g["-moz-transition"]=f.moz,g["-ms-transition"]=f.ms,g["-o-transition"]=f.o,this.scrollerOffsetX=a.parseInt(b,10),this.scrollerOffsetY=a.parseInt(c,10)},h._translateScrollbar=function(a,b,c,d){this.scrollbar&&this.scrollbar.translate(this.orientation===l.Orientation.HORIZONTAL?-a:-b,c,d)},h._start=function(){var a=this;a.scrolled=!1,a.dragging=!0,a.scrollCanceled=!1,a.startScrollerOffsetX=a.scrollerOffsetX,a.startScrollerOffsetY=a.scrollerOffsetY},h._move=function(a){var b=this.startScrollerOffsetX,c=this.startScrollerOffsetY,d=!k;this.enabled&&!this.scrollCanceled&&this.dragging&&(this.orientation===l.Orientation.HORIZONTAL?b+=a.detail.estimatedDeltaX:c+=a.detail.estimatedDeltaY,(b>this.minScrollX||b<this.maxScrollX)&&(b=b>this.minScrollX?this.minScrollX:this.maxScrollX),(c>this.minScrollY||c<this.maxScrollY)&&(c=c>this.minScrollY?this.minScrollY:this.maxScrollY),b!==this.scrollerOffsetX||c!==this.scrollerOffsetY?(this.scrolled||this.trigger(j.START),this.scrolled=!0,this._translate(b,c),this._translateScrollbar(b,c,0,d),this.trigger(j.MOVE),this.bouncingEffect&&this.bouncingEffect.hide()):(this.bouncingEffect&&this.bouncingEffect.drag(b,c),this._translateScrollbar(b,c,0,d)))},h._end=function(){this.dragging&&(this.bouncingEffect&&this.bouncingEffect.dragEnd(),this.scrollbar&&this.scrollbar.end(),this._endScroll(),this.dragging=!1)},h._endScroll=function(){this.scrolled&&this.trigger(j.END),this.scrolled=!1},h._cancel=function(){this.scrollCanceled=!0,this.scrolled&&(this._translate(this.startScrollerOffsetX,this.startScrollerOffsetY),this._translateScrollbar(this.startScrollerOffsetX,this.startScrollerOffsetY),this.trigger(j.CANCEL)),this.scrollbar&&this.scrollbar.end(),this.scrolled=!1,this.dragging=!1},h._clear=function(){this.scrolled=!1,this.scrollCanceled=!1,this._resetLayout(),this._clearScrollbar(),this._clearBouncingEffect()},h._clearScrollbar=function(){this.scrollbar&&this.scrollbar.destroy(),this.scrollbar=null},h._clearBouncingEffect=function(){this.bouncingEffect&&this.bouncingEffect.destroy(),this.bouncingEffect=null},h._disable=function(){this.enabled=!1},h._enable=function(){this.enabled=!0},h._destroy=function(){this._unbindEvents(),this._clear(),this.scrollerStyle=null,this.scroller=null},l.prototype=h,c.widget.core.scroller.Scroller=l,e.defineWidget("Scroller",".scroller",["scrollTo","cancel"],l)}(a.document,d),function(a,b){b.widget.core.scroller.scrollbar=b.widget.core.scroller.scrollbar||{}}(a,d),function(a,b){b.widget.core.scroller.scrollbar.type=b.widget.core.scroller.scrollbar.type||{}}(a,d),function(a,b){b.widget.core.scroller.scrollbar.type["interface"]={setScrollbarLayout:function(){},remove:function(){},start:function(){},end:function(){},offset:function(){}}}(a.document,d),function(a,b){var c=b.util.object,d=b.widget.core.scroller.scrollbar.type,e=d["interface"],f=b.widget.core.scroller.Scroller;d.bar=c.merge({},e,{options:{animationDuration:500},setScrollbar:function(a,b,c){this._viewLayout=a,this._clipLayout=c,this._firstChildLayout=b,this._ratio=c/b},getScrollbarSize:function(){return this._firstChildLayout/this._viewLayout*this._firstChildLayout*this._ratio},offset:function(a,b){var c,d;return b=b*this._clipLayout/this._viewLayout,a===f.Orientation.VERTICAL?(c=0,d=b):(c=b,d=0),{x:c,y:d}},start:function(a){var b=a.style,c=this.options.animationDuration;b["-webkit-transition"]=b["-moz-transition"]=b["-ms-transition"]=b["-o-transition"]=b.transition="opacity "+c/1e3+"s ease",b.opacity=1},end:function(a){var b=a.style,c=this.options.animationDuration;b["-webkit-transition"]=b["-moz-transition"]=b["-ms-transition"]=b["-o-transition"]=b.transition="opacity "+c/1e3+"s ease",b.opacity=0}})}(a.document,d),function(b,c){var d=c.util.object,e=c.widget.core.scroller.scrollbar.type,f=e["interface"],g=c.widget.core.scroller.Scroller;e.tab=d.merge({},f,{options:{wrapperClass:"ui-scrollbar-tab-type",barClass:"ui-scrollbar-indicator",margin:1},insertAndDecorate:function(b){var c,d,e,f,h=b.wrapper,i=b.bar,j=b.container,k=b.clip,l=b.sections,m=b.orientation,n=this.options.margin,o=k.offsetWidth,p=k.offsetHeight,q=j.offsetWidth,r=j.offsetHeight,s=m===g.Orientation.VERTICAL?p:o,t=m===g.Orientation.VERTICAL?r:q,u=s/t;if(this.containerSize=q,this.maxScrollOffset=s-t,this.scrollZoomRate=q/s,this.barSize=a.parseInt((q-2*n*(u-1))/u),h.className=this.options.wrapperClass,i.className=this.options.barClass,i.style.width=this.barSize+"px",i.style.left="0px",j.insertBefore(h,k),d=i.offsetHeight,c=p-d,k.style.height=c+"px",l&&l.length)for(e=0,f=l.length;f>e;e++)l[e].style.height=c+"px"},remove:function(a){var b=a.wrapper,c=a.container;c&&b&&c.removeChild(b)},offset:function(a,b){return{x:0===b?-1:b===this.maxScrollOffset?this.containerSize-this.barSize-this.options.margin:b*this.scrollZoomRate,y:0}}})}(a.document,d),function(b,c){var d=c.widget.BaseWidget,e=c.engine,f=new d,g=c.util.object,h=c.util.selectors,i=c.widget.core.Page,j={wrapperClass:"ui-scrollbar-bar-type",barClass:"ui-scrollbar-indicator",orientationClass:"ui-scrollbar-",page:i.classes.uiPage},k=c.widget.core.scroller.Scroller,l=function(){this.wrapper=null,this.barElement=null,this.container=null,this.view=null,this.options={},this.type=null,this.maxScroll=null,this.started=!1,this.displayDelayTimeoutId=null,this.lastScrollPosition=0};f._build=function(a){return this.clip=a,this.view=a.children[0],this.firstChild=this.view.children[0],a},f._configure=function(){this.options=g.merge({},this.options,{type:!1,displayDelay:700,orientation:k.Orientation.VERTICAL})},f._init=function(a){this.clip=a,this.view=a.children[0],this.firstChild=this.view.children[0],this.type=this.options.type,this.type&&this._createScrollbar()},f._bindEvents=function(){b.addEventListener("visibilitychange",this)},f._createScrollbar=function(){var a=this.options.orientation,c=b.createElement("DIV"),d=b.createElement("span"),e=this.view,f=this.clip,g=this.firstChild,h=this.type;f.appendChild(c),c.appendChild(d),c.classList.add(j.wrapperClass),d.className=j.barClass,a===k.Orientation.HORIZONTAL?(h.setScrollbar(e.offsetWidth,g.offsetWidth,f.offsetWidth),d.style.width=h.getScrollbarSize()+"px",c.classList.add(j.orientationClass+"horizontal")):(h.setScrollbar(e.offsetHeight,g.offsetHeight,f.offsetHeight),d.style.height=h.getScrollbarSize()+"px",c.classList.add(j.orientationClass+"vertical")),this.wrapper=c,this.barElement=d},f._removeScrollbar=function(){this.clip.removeChild(this.wrapper),this.wrapper=null,this.barElement=null},f._refresh=function(){var a=this;a._clear(),a._init(a.element),a.translate(a.lastScrollPosition)},f.translate=function(b,c,d){var e,f,g,h=this.options.orientation,i={normal:"none",webkit:"none",moz:"none",ms:"none",o:"none"};this.wrapper&&this.type&&this.lastScrollPosition!==b&&(d=d!==!1,this.lastScrollPosition=b,b=this.type.offset(h,b),f=this.barElement.style,c&&(i.normal="transform "+c/1e3+"s ease-out",i.webkit="-webkit-transform "+c/1e3+"s ease-out",i.moz="-moz-transform "+c/1e3+"s ease-out",i.ms="-ms-transform "+c/1e3+"s ease-out",i.o="-o-transform "+c/1e3+"s ease-out"),e="translate3d("+b.x+"px,"+b.y+"px, 0)",f["-webkit-transform"]=f["-moz-transform"]=f["-ms-transform"]=f["-o-transform"]=f.transform=e,f["-webkit-transition"]=i.webkit,f["-moz-transition"]=i.moz,f["-ms-transition"]=i.ms,f["-o-transition"]=i.o,f.transition=i.normal,this.started||this._start(),null!==this.displayDelayTimeoutId&&(a.clearTimeout(this.displayDelayTimeoutId),this.displayDelayTimeoutId=null),d&&(g=(c||0)+this.options.displayDelay,this.displayDelayTimeoutId=a.setTimeout(this._end.bind(this),g)))},f.end=function(){this.displayDelayTimeoutId||(this.displayDelayTimeoutId=a.setTimeout(this._end.bind(this),this.options.displayDelay))},f._start=function(){this.type.start(this.wrapper,this.barElement),this.started=!0},f._end=function(){this.started=!1,this.displayDelayTimeoutId=null,this.type&&this.type.end(this.wrapper,this.barElement)},f.handleEvent=function(a){var d;switch(a.type){case"visibilitychange":d=h.getClosestBySelector(this.clip,"."+j.page),"visible"===b.visibilityState&&d===c.activePage&&this.refresh()}
+},f._clear=function(){this._removeScrollbar(),this.started=!1,this.type=null,this.barElement=null,this.displayDelayTimeoutId=null},f._destroy=function(){this._clear(),b.removeEventListener("visibilitychange",this),this.options=null,this.clip=null,this.view=null},l.prototype=f,c.widget.core.scroller.scrollbar.ScrollBar=l,e.defineWidget("ScrollBar","",["translate"],l)}(a.document,d),function(a){a.util.easing={cubicOut:function(a,b,c,d){return a/=d,a--,c*(a*a*a+1)+b},easeOutQuad:function(a,b,c,d){return-c*(a/=d)*(a-2)+b},easeOutSine:function(a,b,c,d){return c*Math.sin(a/d*(Math.PI/2))+b},easeOutExpo:function(a,b,c,d){return a===d?b+c:c*(-Math.pow(2,-10*a/d)+1)+b},linear:function(a,b,c,d){return b+c*a/d}}}(d),function(a,b,c){function d(a){"static"===o.getCSSProperty(a,"position")?a.style.position="relative":a.style.position="absolute"}function e(a,b,c,d,e,f,g,h,i,j){var k=(new Date).getTime()-c,n=parseInt(m.cubicOut(k,d,f,j),10),o=parseInt(m.cubicOut(k,e,g,j),10);b.scrollLeft!==h&&(b.scrollLeft=n),b.scrollTop!==i&&(b.scrollTop=o),(n!==h||o!==i)&&n>=0&&o>=0&&a.currentTransition?l.requestAnimationFrame(a.currentTransition):a.currentTransition=null}function f(a,b,c,d,f){f?(a.currentTransition=e.bind(null,a,b,(new Date).getTime(),b.scrollLeft,b.scrollTop,c,d,b.scrollLeft+c,b.scrollTop+d,f),l.requestAnimationFrame(a.currentTransition)):(c&&(b.scrollLeft=b.scrollLeft+c),d&&(b.scrollTop=b.scrollTop+d))}function g(a){var b=a._ui,c=b.jumpHorizontalButton,d=b.jumpVerticalButton,e=c||d?o.getElementOffset(a.element):null;c&&(c.style.left=e.left+"px"),d&&(d.style.top=e.top+"px")}function h(a){var b=a.classList,c=p.getChildrenByClass(a,w.indicatorTop)[0],d=p.getChildrenByClass(a,w.indicatorBottom)[0];b.remove(w.indicatorTopShown),b.remove(w.indicatorBottomShown),b.remove(w.indicatorRightShown),b.remove(w.indicatorLeftShown),c.style="",d.style=""}function i(a,b){var c,d=p.getChildrenByClass(a,w.indicatorTop)[0],e=p.getChildrenByClass(a,w.indicatorBottom)[0];d&&(c=d.style,c.width=b.width+"px",c.top=b.clipTop+"px",c.backgroundColor=b.color),e&&(c=e.style,c.width=b.width+"px",c.top=b.clipTop+b.clipHeight-o.getElementHeight(e)+"px",c.backgroundColor=b.color)}var j=c.widget.BaseWidget,k=c.engine,l=c.util,m=c.util.easing,n=c.event,o=c.util.DOM,p=c.util.selectors,q=null,r=c.widget.core.Page,s=r.classes.uiPage,t=r.classes.uiPageActive,u=r.events,v=function(){var a,b=this;b._scrollState={currentTransition:null},b.scrollDuration=300,b.scrollviewSetHeight=!1,b.options={scroll:"y",scrollJump:!1,scrollIndicator:!1},a=b._ui||{},a.view=null,a.page=null,a.jumpHorizontalButton=null,a.jumpVerticalButton=null,b._ui=a,b._callbacks={repositionJumps:null,jumpTop:null,jumpBottom:null},b._timers={scrollIndicatorHide:null}},w={view:"ui-scrollview-view",clip:"ui-scrollview-clip",jumpTop:"ui-scroll-jump-top-bg",jumpLeft:"ui-scroll-jump-left-bg",indicatorTop:"ui-overflow-indicator-top",indicatorBottom:"ui-overflow-indicator-bottom",indicatorTopShown:"ui-scrollindicator-top",indicatorBottomShown:"ui-scrollindicator-bottom",indicatorLeftShown:"ui-scrollindicator-left",indicatorRightShown:"ui-scrollindicator-right"};v.classes=w,v.prototype=new j,v.prototype._build=function(a){var c,e,f,g=this,h=g._ui,i=p.getChildrenByClass(a,w.view)[0]||b.createElement("div"),j=a.firstChild,l=g.options,m=l.scroll;for(i.className=w.view;j;)c=j,j=j.nextSibling,i!==c&&i.appendChild(c);return i.parentNode!==a&&a.appendChild(i),d(i),a.classList.add(w.clip),a.classList.add("ui-content"),g._setClipOverflowStyle(a),l.scrollJump&&(m.indexOf("x")>-1&&(f=b.createElement("div"),f.className=w.jumpLeft,e=b.createElement("div"),f.appendChild(e),a.appendChild(f),k.instanceWidget(e,"Button",{icon:"scrollleft",style:"box"}),h.jumpHorizontalButton=f),m.indexOf("y")>-1&&(f=b.createElement("div"),f.className=w.jumpTop,e=b.createElement("div"),f.appendChild(e),a.appendChild(f),k.instanceWidget(e,"Button",{icon:"scrolltop",style:"box"}),h.jumpVerticalButton=f)),h.view=i,l.scrollIndicator&&g._addOverflowIndicator(a),a},v.prototype._setClipOverflowStyle=function(a){var b,c=this,d=c.options.scroll;switch(a=a||c.element,b=a.style,d){case"x":b.overflowX="scroll";break;case"xy":b.overflow="scroll";break;default:b.overflowY="auto"}},v.prototype._setClipOverflowHidden=function(a){var b,c=this,d=c.options.scroll;switch(a=a||c.element,b=a.style,d){case"x":b.overflowX="hidden";break;case"xy":b.overflow="hidden";break;default:b.overflowY="hidden"}},v.prototype._init=function(a){var b=this._ui,c=b.page;b.view||(b.view=p.getChildrenByClass(a,w.view)[0]),c||(c=p.getClosestByClass(a,s),c&&(b.page=c,c.classList.contains(t)&&this.options.scrollJump&&g(this)))},v.prototype._addOverflowIndicator=function(a){a.insertAdjacentHTML("beforeend","<div class='"+w.indicatorTop+"'></div><div class='"+w.indicatorBottom+"'></div>")},v.prototype._showScrollIndicator=function(){var b=this,c=b.element,d=b._ui.view,e=c.scrollTop,f=o.getElementHeight(c),g=o.getElementOffset(c),j=o.getElementHeight(d),k=o.getElementWidth(d),l=o.getElementOffset(d);switch(h(c),b.options.scroll){case"x":case"xy":break;default:i(c,{clipTop:g.top,clipHeight:f,width:k,color:a.getComputedStyle(c).backgroundColor}),l.top-e<g.top&&c.classList.add(w.indicatorTopShown),l.top-e+j>g.top+f&&c.classList.add(w.indicatorBottomShown)}},v.prototype._hideScrollIndicator=function(){var b=this,c=b._timers,d=c.scrollIndicatorHide;d&&a.clearTimeout(d),c.scrollIndicatorHide=a.setTimeout(function(){h(b.element)},1500)},v.prototype.scrollTo=function(a,b,c){var d=this.element;this.translateTo(a-d.scrollLeft,b-d.scrollTop,c)},v.prototype.translateTo=function(a,b,c){f(this._scrollState,this.element,a,b,c)},v.prototype.ensureElementIsVisible=function(a){var b,c,d,e,f,g=this.element,h=o.getElementHeight(g),i=o.getElementWidth(g),j=0,k=h,l=o.getElementHeight(a),m=o.getElementWidth(a),n=0,p=h>=l&&i>=m,q=function(a){var b=a.getAttribute("id"),c=a.tagName.toLowerCase();return b&&["input","textarea","button"].indexOf(c)>-1?a.parentNode.querySelector("label[for="+b+"]"):null},r=!0;for(f=a.parentNode;f&&f!==g;)n+=f.offsetTop,f=f.parentNode;switch(b=n+l,r){case p&&n>j&&k>b:case n>j&&k>n&&b>k:case j>n&&k>b:break;case p&&n>j&&b>k:case p&&j>n&&k>b:case p:this.centerToElement(a);break;default:for(c=q(a),c||(c=a),d=c.offsetLeft+o.getCSSProperty(c,"margin-left",0,"integer"),e=c.offsetTop+o.getCSSProperty(c,"margin-top",0,"integer"),f=c.parentNode;f&&f!==g;)d+=f.offsetLeft,e+=f.offsetTop,f=f.parentNode;this.scrollTo(d,e,this.scrollDuration)}},v.prototype.centerToElement=function(a){for(var b=this.element,c=parseInt(o.getElementWidth(b)/2-o.getElementWidth(a)/2,10),d=parseInt(o.getElementHeight(b)/2-o.getElementHeight(a)/2,10),e=a.offsetLeft,f=a.offsetTop,g=a.parentNode;g&&g!==b;)e+=g.offsetLeft+o.getCSSProperty(g,"margin-left",0,"integer"),f+=g.offsetTop+o.getCSSProperty(g,"margin-top",0,"integer"),g=g.parentNode;this.scrollTo(e-c,f-d,this.scrollDuration)},v.prototype.getScrollPosition=function(){var a=this.element;return{x:a.scrollLeft,y:a.scrollTop}},v.prototype._bindEvents=function(c){var d,e,f,h=null,i=function(){n.trigger(c,"scrollstop"),a.clearTimeout(h),h=null},j=this,k=j._ui,l=k.page,m=k.jumpVerticalButton,o=k.jumpHorizontalButton,p=j._callbacks,r=j.options.scroll;l&&(j.options.scrollJump&&(d=g.bind(null,j),e=function(){j.scrollTo(c.scrollLeft,0,250)},f=function(){j.scrollTo(0,c.scrollTop,250)},l.addEventListener(u.SHOW,d,!1),m&&m.firstChild.addEventListener("vclick",e,!1),o&&o.firstChild.addEventListener("vclick",f,!1),p.repositionJumps=d,p.jumpTop=e,p.jumpLeft=f),c.addEventListener("scroll",function(){h?a.clearTimeout(h):n.trigger(c,"scrollstart"),"y"!==r||0!==c.scrollTop&&c.scrollTop+c.clientHeight!==c.scrollHeight?"x"!==r||0!==c.scrollLeft&&c.scrollLeft+c.clientWidth!==c.scrollWidth||n.trigger(c,"scrollboundary",{direction:0===c.scrollLeft?"left":"right"}):n.trigger(c,"scrollboundary",{direction:0===c.scrollTop?"top":"bottom"}),h=a.setTimeout(i,100),n.trigger(c,"scrollupdate")},!1),b.addEventListener("vmousedown",function(){q&&(q=null)},!1),j.options.scrollIndicator&&(p.scrollUpdate=j._showScrollIndicator.bind(j),c.addEventListener("scrollupdate",p.scrollUpdate,!1),p.scrollStop=j._hideScrollIndicator.bind(j),c.addEventListener("scrollstop",p.scrollStop,!1)))},v.prototype._destroy=function(){var b=this,c=b.element,d=b._ui,e=d.page,f=this.options.scrollJump,g=d.jumpVerticalButton,h=d.jumpHorizontalButton,i=b._callbacks,j=i.repositionJumps,k=i.jumpTop,l=i.jumpLeft;f&&(e&&j&&e.removeEventListener(u.SHOW,j,!1),g&&k&&g.firstChild.removeEventListener("vclick",k,!1),h&&l&&h.firstChild.removeEventListener("vclick",l,!1)),b.options.scrollIndicator&&c.removeEventListener("scrollupdate",i.scrollUpdate,!1),b._timers.scrollIndicatorHide&&a.clearTimeout(b._timers.scrollIndicatorHide)},v.prototype.enableScrolling=function(){this._setClipOverflowStyle()},v.prototype.disableScrolling=function(){this._setClipOverflowHidden()},c.widget.core.Scrollview=v}(a,a.document,d),function(a,b){var c=b.widget.BaseWidget,d=b.engine,e=b.event,f=function(){},g={},h={TAB_CHANGE:"tabchange"},i=new c;f.prototype=i,f.classes=g,i._setActive=function(a){var b=this.element;e.trigger(b,h.TAB_CHANGE,{active:a})},i.setActive=function(a){this._setActive(a)},i._getActive=function(){return this.options.active},i.getActive=function(){return this._getActive()},b.widget.core.Tab=f,d.defineWidget("Tab","",["setActive","getActive"],f,"tizen")}(a.document,d),function(a,b){var c=b.widget.core.Tab,d=b.engine,e=b.util.object,f=function(){this.tabSize=0,this.width=0},g=c.prototype,h=new c;f.prototype=h,h._init=function(a){var b=this.options;this.width=a.offsetWidth,a.classList.add(b.wrapperClass)},h._configure=function(){e.merge(this.options,{margin:4,triggerEvent:!1,wrapperClass:"ui-tab-indicator",itemClass:"ui-tab-item",activeClass:"ui-tab-active",active:0})},h._createIndicator=function(){var b,c=this.options,d=a.createDocumentFragment(),e=[],f=c.margin,g=0,h=this.tabSize,i=this.width-f*(h-1),j=Math.floor(i/h),k=i%h,l=0;for(g=0;h>g;g++)e[g]=j;for(g=Math.floor((h-k)/2);k>0;g++,k--)e[g]+=1;for(g=0;h>g;g++)b=a.createElement("span"),b.classList.add(c.itemClass),b.style.width=e[g]+"px",b.style.left=l+"px",l+=e[g]+f,g===c.active&&b.classList.add(c.activeClass),d.appendChild(b);this.element.appendChild(d)},h._removeIndicator=function(){this.element.innerHTML=""},h._refresh=function(){this._removeIndicator(),this._createIndicator()},h._setActive=function(a){var b=this.options,c=this.element.children;b.active=a,[].forEach.call(c,function(a){a.classList.remove(b.activeClass)}),a<c.length&&(c[a].classList.add(b.activeClass),g._setActive.call(this,a))},h.setSize=function(a){var b=this.tabSize!==a;this.tabSize=a,b&&this.refresh()},h._destroy=function(){var a=this.options;this._removeIndicator(),this.element.classList.remove(a.wrapperClass)},b.widget.core.TabIndicator=f,d.defineWidget("TabIndicator",".ui-tab",["setActive","getActive","setSize"],f)}(a.document,d),function(a,b){function d(){this.options=m({},s),n.call(this),this._ui={page:null}}function e(a,b,d){var e=b.length,f=d!==c?d:e,g=0,h=0;for(f>e&&(f=e),h;f>h;h++)g+=a===i.HORIZONTAL?b[h].offsetWidth:b[h].offsetHeight;return g}function f(a,b,c){var d=e(a,b,c+1),f=b[c];return f&&(d-=a===i.HORIZONTAL?f.offsetWidth/2:f.offsetHeight/2),d}var g=b.widget.core.scroller.Scroller,h=b.event.gesture,i=h.Orientation,j=b.engine,k=b.util.object,l=b.event,m=b.util.object.merge,n=b.widget.core.BaseKeyboardSupport,o=b.widget.core.Page,p=b.util.selectors,q=m({CHANGE:"sectionchange"},g.EventType),r={uiSectionChanger:"ui-section-changer"},s={items:"section",activeClass:"ui-section-active",circular:!1,animate:!0,animateDuration:100,orientation:"horizontal",changeThreshold:-1,useTab:!1,fillContent:!0,model:null,directives:null};k.inherit(d,g,{_build:function(a){var b=this,c=b.options;return b.tabIndicatorElement=null,b.tabIndicator=null,b.sections=null,b.sectionPositions=[],b.activeIndex=0,b.beforeIndex=0,b._super(a),a.classList.add(r.uiSectionChanger),b.scroller.style.position="absolute",b.scroller.classList.add("ui-section-changer-container"),b.orientation="horizontal"===c.orientation?i.HORIZONTAL:i.VERTICAL,a},_configure:function(){this._super(),this.options=k.merge(this.options,s)},_fillElementFromModel:function(a,b,c){var d,e;for(d in b)b.hasOwnProperty(d)&&(e=a.querySelector("[data-bind='"+d+"']"),e&&(c&&"function"==typeof c[d]?c[d].call(e,b[d]):e.innerText=b[d]))},_setModel:function(a,b){this.options.model=b,this._findDataBinding()},_fillWidgetFromModel:function(a,b,c){var d,e,f,g,h=this,i=h.element;d=i.querySelectorAll("[data-bind='"+a+"'] > section"),1===d.length&&(e=d[0],f=e.innerHTML,g=e.parentElement,g.removeChild(e),b.forEach(function(a){var b=e.cloneNode();b.innerHTML=f,h._fillElementFromModel(b,a,c),g.appendChild(b)}))},_findDataBinding:function(){var a,b,c,d=this.options.model,e=this.options.directives;if(d)for(c in d)d.hasOwnProperty(c)&&(a=d[c],"string"==typeof a||Array.isArray(a)&&(e&&(b=e[c]),this._fillWidgetFromModel(c,a,b)))},_init:function(a){var c,d,e,f=this,g=f.options,h=f.scroller,i=f._ui;if("tab"===g.scrollbar&&(g.scrollbar=!1,g.useTab=!0),g.model&&f._findDataBinding(),i.page=p.getClosestBySelector(f.element,"."+o.classes.uiPage),h)if(f.sections="string"==typeof g.items?h.querySelectorAll(g.items):g.items,c=f.sections.length,g.circular&&3>c)b.error("[SectionChanger] if you use circular option, you must have at least three sections.");else{for(d=0;c>d;d++)e=f.sections[d].className,e&&e.indexOf(g.activeClass)>-1?f.activeIndex=d:f.isKeyboardSupport===!0&&f.disableFocusableElements(f.sections[d]),f.sectionPositions[d]=d;f._prepareLayout(),f._initLayout(),f._super(a),f._repositionSections(!0),f.setActiveSection(f.activeIndex),g.animate||(g.animateDuration=0),g.changeThreshold<0&&(g.changeThreshold=f._sectionChangerHalfWidth)}return a},_prepareLayout:function(){var a,b=this.options,c=this.sections.length,d=this.orientation,f=this.scroller.style,g=this.element.offsetHeight;0===g&&(g=this.element.parentNode.offsetHeight,this.element.style.height=g+"px"),this._sectionChangerWidth=this.element.offsetWidth,this._sectionChangerHeight=g,this._sectionChangerHalfWidth=this._sectionChangerWidth/2,this._sectionChangerHalfHeight=this._sectionChangerHeight/2,b.useTab&&(this._initTabIndicator(),a=this.tabIndicatorElement.offsetHeight,this._sectionChangerHeight-=a,this._sectionChangerHalfHeight=this._sectionChangerHeight/2,this.element.style.height=this._sectionChangerHeight+"px"),d===i.HORIZONTAL?(f.width=(b.fillContent?this._sectionChangerWidth*c:e(d,this.sections))+"px",f.height=this._sectionChangerHeight+"px"):(f.width=this._sectionChangerWidth+"px",f.height=(b.fillContent?this._sectionChangerHeight*c:e(d,this.sections))+"px")},_initLayout:function(){var a,b,c,d=0,f=0;for(b=0,c=this.sections.length;c>b;b++)a=this.sections[b].style,a.position="absolute",this.options.fillContent&&(a.width=this._sectionChangerWidth+"px",a.height=this._sectionChangerHeight+"px"),this.orientation===i.HORIZONTAL?(f=0,d=e(this.orientation,this.sections,b)):(f=e(this.orientation,this.sections,b),d=0),a.top=f+"px",a.left=d+"px"},_initBouncingEffect:function(){var a=this.options;a.circular||this._super()},_translateScrollbar:function(a,b,c,d){var e,f=this,g=f.scrollbar;g&&(e=f.orientation===i.HORIZONTAL?-a+f.minScrollX:-b+f.minScrollY,g.translate(e,c,d))},_translateScrollbarWithPageIndex:function(a,b){var c;this.scrollbar&&(c=e(this.orientation,this.sections,this.activeIndex),this.scrollbar.translate(c,b))},_initTabIndicator:function(){var b=this,c=a.createElement("div"),d=b.element,e=null;b.tabIndicatorElement=c,d.parentNode.insertBefore(c,d),e=new j.instanceWidget(c,"TabIndicator"),b.tabIndicator=e,e.setSize(b.sections.length),e.setActive(b.activeIndex),b.tabIndicatorHandler=function(a){this.tabIndicator.setActive(a.detail.active)}.bind(b),d.addEventListener(q.CHANGE,b.tabIndicatorHandler,!1)},_clearTabIndicator:function(){this.tabIndicator&&(this.element.parentNode.removeChild(this.tabIndicatorElement),this.element.removeEventListener(q.CHANGE,this.tabIndicatorHandler,!1),this.tabIndicator.destroy(),this.tabIndicator=null,this.tabIndicatorElement=null,this.tabIndicatorHandler=null)},_resetLayout:function(){var a,b,c;for(b=0,c=this.sections.length;c>b;b++)a=this.sections[b].style,a.position="",a.width="",a.height="",a.top="",a.left="";this._super()},_bindEvents:function(){var c=this;c._super(),c.scroller&&(b.event.enableGesture(c.scroller,new b.event.gesture.Swipe({orientation:c.orientation===i.HORIZONTAL?h.Orientation.HORIZONTAL:h.Orientation.VERTICAL})),l.on(c.scroller,"swipe transitionEnd webkitTransitionEnd mozTransitionEnd msTransitionEnd oTransitionEnd",c),c._ui.page&&l.on(c._ui.page,"taufocusborder",c)),b.util.rotaryScrolling&&b.util.rotaryScrolling.lock(),a.addEventListener("rotarydetent",c,!0)},_unbindEvents:function(){var c=this;c._super(),c.scroller&&(b.event.disableGesture(c.scroller),l.off(c.scroller,"swipe transitionEnd webkitTransitionEnd mozTransitionEnd msTransitionEnd oTransitionEnd",c),c._ui.page&&l.off(c._ui.page,"taufocusborder",c)),a.removeEventListener("rotarydetent",c,!0),b.util.rotaryScrolling&&b.util.rotaryScrolling.unlock()},handleEvent:function(a){switch(this._super(a),a.type){case"swipe":case"taufocusborder":this._change(a);break;case"rotarydetent":this._change(a,!0);break;case"webkitTransitionEnd":case"mozTransitionEnd":case"msTransitionEnd":case"oTransitionEnd":case"transitionEnd":a.target===this.scroller&&this._endScroll()}},_notifyChangedSection:function(a){var b,c=this.options.activeClass,d=this.sections.length,e=0;for(e=0;d>e;e++)b=this.sections[e],b.classList.remove(c),e===this.activeIndex&&b.classList.add(c);this.trigger(q.CHANGE,{active:a})},setActiveSection:function(a,b,d,e){var g,h=this.sectionPositions[a],j=this.activeIndex,k=0,l=0;b=b||0,d=!!d,e==c&&(e=!0),g=b,this.orientation===i.HORIZONTAL?k=this._sectionChangerHalfWidth-f(this.orientation,this.sections,h):l=this._sectionChangerHalfHeight-f(this.orientation,this.sections,h),(this.beforeIndex-a>1||this.beforeIndex-a<-1)&&(g=0),this.activeIndex!==a&&this.isKeyboardSupport===!0&&this.disableFocusableElements(this.sections[this.activeIndex]),this.activeIndex=a,this.beforeIndex=this.activeIndex,k!==this.scrollerOffsetX||l!==this.scrollerOffsetY?(d!==!1&&(this.trigger(q.START),this.scrolled=!0),this._translate(k,l,b),this._translateScrollbarWithPageIndex(a,g)):this._endScroll(),this.activeIndex!==j&&this._notifyChangedSection(this.activeIndex),e&&this._repositionSections(!0)},getActiveSectionIndex:function(){return this.activeIndex},_start:function(a){this._super(a),this.beforeIndex=this.activeIndex},_move:function(a){var b=this,c=b.options.changeThreshold,d=b.orientation===i.HORIZONTAL?a.detail.deltaX:a.detail.deltaY,e=b.activeIndex,f=b.beforeIndex;b._super(a),b.scrolled&&(d>c?b.activeIndex=b._calculateIndex(f-1):-c>d?b.activeIndex=b._calculateIndex(f+1):b.activeIndex=f,b.activeIndex!==e&&b._notifyChangedSection(b.activeIndex))},_end:function(){var a=this;a.scrollbar&&a.scrollbar.end(),a.enabled&&!a.scrollCanceled&&a.dragging&&(a.bouncingEffect&&a.bouncingEffect.dragEnd(),a.setActiveSection(a.activeIndex,a.options.animateDuration,!1,!1),a.dragging=!1)},_change:function(a,b){var c,d=this,e=a.detail.direction,f=e===h.Direction.UP||e===h.Direction.LEFT||"CW"===e?1:-1;"taufocusborder"===a.type&&(f*=-1),c=d._calculateIndex(d.beforeIndex+f),b=!!b,d.enabled&&!d.scrollCanceled&&(d.bouncingEffect&&d.bouncingEffect.dragEnd(),d.activeIndex!==c&&(d.isKeyboardSupport===!0&&d.sections&&(d.disableFocusableElements(d.sections[d.activeIndex]),d.blurOnActiveElement()),d.activeIndex=c,d._notifyChangedSection(c)),d.setActiveSection(c,d.options.animateDuration,b,!1),d.dragging=!1)},_endScroll:function(){var a=this;this.isKeyboardSupport===!0&&a.enableDisabledFocusableElements(a.sections[a.activeIndex]),a.enabled&&a.scrolled&&!a.scrollCanceled&&(a._repositionSections(),a._super())},_repositionSections:function(a){var b,c,d,g,h,j,k,l=this,m=l.sections,n=l.activeIndex,o=l.orientation,p=o===i.HORIZONTAL,q=m.length,r=l.sectionPositions[n],s=Math.floor(q/2),t=l.options.circular,u=0,v=0;if(p?(j=-f(o,m,t?s:n),k=0):(j=0,k=-f(o,m,t?s:n)),l._translateScrollbarWithPageIndex(n),(a||0===r||r===q-1)&&(p?u=l._sectionChangerHalfWidth+j:v=l._sectionChangerHalfHeight+k,l._translate(u,v),t))for(b=0;q>b;b++)d=(q+n-s+b)%q,c=m[d].style,l.sectionPositions[d]=b,p?(g=0,h=e(o,m,b)):(g=e(o,m,b),h=0),c.top=g+"px",c.left=h+"px"},_calculateIndex:function(a){var b=this.sections.length;return a=this.options.circular?(b+a)%b:0>a?0:a>b-1?b-1:a},_clear:function(){this._clearTabIndicator(),this._super(),this.sectionPositions.length=0},_destroy:function(){var a=this.element;a.style.height=null,a.style.width=null,this._super()}}),b.widget.core.SectionChanger=d,j.defineWidget("SectionChanger","[data-role='section-changer'], .ui-section-changer",["getActiveSectionIndex","setActiveSection"],d)}(a.document,d),function(a,b,c){function d(a,c){var d=b.createElement("div"),e=a.querySelector("."+j.UI_DIMMER_TEXT),f=a.querySelector("."+j.UI_DIMMER_BULB_LIGHT),g=a.classList;d&&(c?(e.classList.add(j.UI_DIMMER_HIDDEN),f.classList.remove(j.UI_DIMMER_HIDDEN)):(e.classList.remove(j.UI_DIMMER_HIDDEN),f.classList.add(j.UI_DIMMER_HIDDEN))),c?g.add(j.UI_DIMMER_BULB):g.remove(j.UI_DIMMER_BULB)}function e(a){return"none"!==h.getCSSProperty(a,"background-image","none","string")}var f=c.util.object,g=function(){this.options=f.merge({},g.defaults),this.bulbMode=!1,this._observer=null,this._observerCallback=this._checkStyleChange.bind(this),this._refreshCallback=this.refresh.bind(this)},h=c.util.DOM,i={value:50,min:0,max:100,bulb:!1,options:"30:blue; 60:yellow; 100:red"},j={UI_DIMMER:"ui-dimmer",UI_DIMMER_BULB:"ui-dimmer-lightbulb",UI_DIMMER_BULB_LIGHT:"ui-dimmer-lightbulb-light",UI_DIMMER_TEXT:"ui-dimmer-text",UI_DIMMER_HIDDEN:"ui-dimmer-hidden"},k=c.widget.BaseWidget,l=new k;g.prototype=l,g.defaults=i,g.classes=j,l._init=function(a){var b=this,c=new MutationObserver(this._observerCallback);return a.getAttribute("value")||a.setAttribute("value",b.options.value),c.observe(a,{attributes:!0}),b._observer=c,a},l._checkStyleChange=function(a){var b=this,c=b.options,d=b._refreshCallback;a.forEach(function(a){"style"===a.attributeName&&(c.bulb=e(a.target),d())})},l._refresh=function(){var a=this;d(a.element,a.options.bulb),a.value(a.options.value)},l._build=function(a){var c=e(a),f=this.options,g=a.querySelector("."+j.UI_DIMMER_TEXT),h=b.createElement("div");return g||(g=b.createElement("span"),g.classList.add(j.UI_DIMMER_TEXT),a.appendChild(g)),h.classList.add(j.UI_DIMMER_BULB_LIGHT),a.appendChild(h),c||(c=a.classList.contains(j.UI_DIMMER_BULB),f.bulb||(f.bulb=c)),d(a,f.bulb),this._refreshValue(a),a},l._destroy=function(){this._observer.disconnect(),this.element.innerHTML=""},l._refreshValue=function(a){var b,c,d,e,f,g,h=this,i=h.options,k=i.value,l=i.min,m=i.max,n=[],o=[];if(a=a||h.element,b=a.querySelector(".ui-dimmer-text"),!i.bulb)return k=parseInt(k,10),c=k/m,a.style.border="60px solid rgba(0, 151, 216, "+c+")",b.innerHTML=k+"%",!0;if(i.bulb&&i.options)for(d=i.options.replace(/\s+/g,"").split(";").filter(function(a){return a&&a.length>0}),d.forEach(function(a){e=a.split(":"),o.push(e[0]),n.push(e[1])}),f=a.querySelector("."+j.UI_DIMMER_BULB_LIGHT),o.unshift(l),g=0;g<o.length;g++)if(g>0&&k<o[g]&&k>o[g-1])return f.style.backgroundColor=n[g-1],!0;return!1},l._setValue=function(a,b){var c=this,d=c.options;return a instanceof HTMLElement||(b=a,a=c.element),b<d.min?b=d.min:b>d.max&&(b=d.max),d.value=b,a.setAttribute("value",b),c._refreshValue(),!1},l._setBulb=function(a,b){return this.options.bulb=b,!0},l._getValue=function(){return parseInt(this.element.getAttribute("value"),10)},c.widget.core.Dimmer=g,c.engine.defineWidget("Dimmer","."+j.UI_DIMMER,[],g,"core")}(a,a.document,d),function(a,b){var c=b.widget.BaseWidget,d=b.widget.core.BaseKeyboardSupport,e=d.KEY_CODES,f=b.engine,g=b.event,h=function(){this.element=null,d.call(this)},i={checkbox:"ui-checkbox",focus:"ui-checkbox-focus",active:"ui-checkbox-active",backwardAnimation:"ui-checkbox-backward-animation"},j=new c;h.prototype=j,j._build=function(a){return"checkbox"===a.getAttribute("type")&&a.classList.add(i.checkbox),a},j._getValue=function(){return this.element.value},j._setValue=function(a){this.element.value=a},j._focus=function(){var a=this,b=a.element;b.focus()},j._blur=function(){var a=this,b=a.element;b.blur()},j._onFocus=function(){var a=this,c=a.element;b.getConfig("keyboardSupport",!1)&&c.classList.add(i.focus)},j._onBlur=function(){var a=this,c=a.element;b.getConfig("keyboardSupport",!1)&&c.classList.remove(i.focus)},j._onTouchStart=function(){this.element.classList.add(i.active)},j._onTouchEnd=function(){this.element.classList.remove(i.active)},j._onKeyUp=function(a){var b=this,c=b.element;a.keyCode===e.enter&&(g.trigger(c,"input"),c.checked=!c.checked,g.trigger(c,"change"))},j._onAnimationEnd=function(a){a.target.classList.toggle(i.backwardAnimation,a.target.checked)},j._bindEvents=function(a){var b=this;b._focusCallbackBound=b._onFocus.bind(b),b._blurCallbackBound=b._onBlur.bind(b),b._keyupCallbackBound=b._onKeyUp.bind(b),b._onTouchStart=b._onTouchStart.bind(b),b._onTouchEnd=b._onTouchEnd.bind(b),a.addEventListener("focus",b._focusCallbackBound,!1),a.addEventListener("blur",b._blurCallbackBound,!1),a.addEventListener("keyup",b._keyupCallbackBound,!1),a.addEventListener("vmousedown",b._onTouchStart,!1),a.addEventListener("vmouseup",b._onTouchEnd,!1),g.on(a,"animationend animationEnd webkitAnimationEnd",b._onAnimationEnd,!1)},j._unbindEvents=function(a){var b=this;a.removeEventListener("focus",b._focusCallbackBound,!1),a.removeEventListener("blur",b._blurCallbackBound,!1),a.removeEventListener("keyup",b._keyupCallbackBound,!1),a.removeEventListener("vmousedown",b._onTouchStart,!1),a.removeEventListener("vmouseup",b._onTouchEnd,!1)},b.widget.core.Checkbox=h,d.registerActiveSelector("input[type='checkbox'], input.ui-checkbox"),f.defineWidget("Checkbox","input[type='checkbox']:not(.ui-slider-switch-input):not([data-role='toggleswitch']):not([data-role='on-off-switch']):not(.ui-toggleswitch):not(.ui-toggle-switch):not(.ui-on-off-switch), input.ui-checkbox",[],h,"core",!1,!1,HTMLInputElement)}(a.document,d),function(a,b){var c=b.widget.BaseWidget,d=b.engine,e=b.widget.core.BaseKeyboardSupport,f=e.KEY_CODES,g=function(){e.call(self),this.element=null},h={radio:"ui-radio",focus:"ui-radio-focus",backwardAnimation:"ui-radio-backward-animation"},i=b.event,j=new c;g.prototype=j,j._build=function(a){return"radio"===a.getAttribute("type")&&a.classList.add(h.radio),a},j._onFocus=function(){var a=this.element;b.getConfig("keyboardSupport",!1)&&(a.focus(),a.classList.add(h.focus))},j._onBlur=function(){var a=this.element;b.getConfig("keyboardSupport",!1)&&(a.blur(),a.classList.remove(h.focus))},j._onKeyUp=function(a){var c=this.element;b.getConfig("keyboardSupport",!1)&&a.keyCode===f.enter&&(c.checked=!0,i.trigger(c,"change"))},j.handleEvent=function(a){var b=this;switch(a.type){case"focus":b._onFocus(a);break;case"blur":b._onBlur(a);break;case"keyup":b._onKeyUp(a);break;case"animationend":case"animationEnd":case"webkitAnimationEnd":b._onAnimationEnd(a)}},j._onAnimationEnd=function(a){a.target.classList.toggle(h.backwardAnimation,a.target.checked)},j._bindEvents=function(a){i.on(a,"focus blur keyup animationend animationEnd webkitAnimationEnd",this,!1)},j._unbindEvents=function(a){i.off(a,"focus blur keyup animationend animationEnd webkitAnimationEnd",this,!1)},j._getValue=function(){return this.element.value},j._setValue=function(a){this.element.value=a},b.widget.core.Radio=g,d.defineWidget("Radio","input[type='radio'], input.ui-radio",[],g,"core",!1,!1,HTMLInputElement),e.registerActiveSelector("input[type='radio'], input.ui-radio")}(a.document,d),function(a,b,c){var d=function(c,d,e){var f="";d=a.encodeURIComponent(d),f=c+"="+d,e&&e instanceof Date&&(f+=";expires="+e.toUTCString()),b.cookie=f},e=function(c){var d=b.cookie.split(";"),e="";return e=d.filter(function(a){return a.indexOf(c+"=")>-1})[0],e&&(e=a.decodeURIComponent(e.trim().replace(c+"=",""))),e};c.util.cookie={readFromCookie:e,writeToCookie:d}}(a,a.document,d),function(a,b){var c=b.widget.BaseWidget,d=b.engine,e=b.event,f={PANEL:"ui-panel",ACTIVE_PANEL:"ui-panel-active"},g={BEFORE_CREATE:"panelbeforecreate",CREATE:"panelcreate",BEFORE_SHOW:"panelbeforeshow",SHOW:"panelshow",BEFORE_HIDE:"panelbeforehide",HIDE:"panelhide",CHANGE:"panelchange"},h=function(){},i=new c;h.eventType=g,h.classes=f,h.prototype=i,i._build=function(a){var c=b.router.Router.getInstance().getRoute("panel");return a.classList.add(f.PANEL),c.setActive(a),a},i._destroy=function(a){e.trigger(a,g.HIDE)},b.widget.core.Panel=h,d.defineWidget("Panel","[data-role='panel'], .ui-panel",[],h,"core")}(a.document,d),function(a,b){function c(a){var b=this;l.on(a,"vclick",b,!1),l.prefixedFastOn(a,"animationEnd",b,!1)}function d(a){var b=this;l.off(a,"vclick",b,!1),l.prefixedFastOff(a,"animationEnd",b,!1)}var e=b.widget.BaseWidget,f=b.util.selectors,g=b.util.object,h=b.util.cookie,i=b.engine,j=b.widget.core.Page,k=b.widget.core.Panel,l=b.event,m={PANEL_CHANGER:"ui-panel-changer",PAGE:j.classes.uiPage,PANEL:k.classes.PANEL,ACTIVE_PANEL:k.classes.ACTIVE_PANEL,HEADER:"ui-header",FOOTER:"ui-footer",PRE_IN:"pre-in",IN:"-in",OUT:"-out"},n=function(){var a=this;a._ui={},a.options={},a.eventType={},a._animating=!1,a._animationClasses={},a.history=[]},o={ANIMATE:"slide",STORAGE_NAME:"panelhistory"},p=new e;n["default"]=o,n.classes=m,n.prototype=p,p._configure=function(){var a=this;g.merge(a.options,{animationType:o.ANIMATE,manageHistory:!0}),g.merge(a.eventType,k.eventType)},p._build=function(a){return a.classList.add(m.PANEL_CHANGER),a},p._init=function(a){var b=this,c=b._ui;return c.page=f.getClosestByClass(a,m.PAGE),c.header=c.page.querySelector("."+m.HEADER),c.footer=c.page.querySelector("."+m.FOOTER),c.activePanel=c.page.querySelector("."+m.ACTIVE_PANEL),c.activePanel||(c.activePanel=c.page.querySelector("[data-role='panel'], .ui-panel"),c.activePanel.classList.add(m.ACTIVE_PANEL)),c.activePanel.style.display="block",b._direction="forward",h.writeToCookie(o.STORAGE_NAME,JSON.stringify([])),b.history.push(c.activePanel.id),h.writeToCookie(o.STORAGE_NAME,JSON.stringify(b.history)),b._animationType=b.options.animationType,this._initLayout(),a},p._initLayout=function(){var a=this,b=a.element,c=a._ui,d=c.page?c.page.offsetHeight:0,e=c.header?c.header.offsetHeight:0,f=c.footer?c.footer.offsetHeight:0;b.style.height=d-e-f+"px"},p._bindEvents=function(a){c.call(this,a)},p._changePanel=function(a,b,c){var d=this,e=new XMLHttpRequest,f=a?a.split(/[#|?]+/)[0]:null;b&&(d._animationType=b),d._direction=c,e.responseType="document",e.open("GET",f),e.addEventListener("error",d._loadError),e.addEventListener("load",function(b){var e=b.target;4===e.readyState&&(200===e.status||0===e.status&&e.responseXML?d._loadSuccess(a,e.responseXML,c):d._loadError())}),e.send()},p._loadSuccess=function(a,c,d){var e,f,g,j,k=this,n=k.element,p=a.substring(a.lastIndexOf("#")),q=k.eventType,r=k._ui,s=p.length>1?n.querySelector(p):null;if(!s&&p.length>1&&(s=c.querySelector(p)||c.querySelector("[data-role='panel'], .ui-panel")),!s)return void b.warn("Panel is not existed");if(e=s.style,e.display="block",j=e.transform,e.transform="translate(-9999px, -9999px)",n.appendChild(s),r.toPanel=s,l.trigger(s,q.BEFORE_CREATE),i.createWidgets(n),l.trigger(s,q.CREATE),l.trigger(s,q.BEFORE_SHOW),l.trigger(r.activePanel,q.BEFORE_HIDE),s.classList.add(m.PRE_IN),e.display="none",e.transform=j,k.history=JSON.parse(h.readFromCookie(o.STORAGE_NAME)||"[]"),"forward"===d)k.history.push(s.getAttribute("id")),h.writeToCookie(o.STORAGE_NAME,JSON.stringify(k.history));else{for(g=k.history.length-1,f=k.history.indexOf(s.id);g>f;f++)k.history.pop();h.writeToCookie(o.STORAGE_NAME,JSON.stringify(k.history))}k._show()},p._show=function(){var a=this,b=a._ui.toPanel,c=a._ui.activePanel,d=a._animationType,e=a._animationClasses;
+a._animating=!0,c.classList.remove(m.ACTIVE_PANEL),b.style.display="block",e.IN=d+m.IN,e.OUT=d+m.OUT,c.classList.add(e.OUT),b.classList.add(e.IN),"none"===d&&a._onAnimationEnd()},p._loadError=function(){b.warn("We can't load AJAX")},p._bindEvents=function(a){c.call(this,a)},p._onClick=function(a){var b,c=this,d="a"===a.target.tagName.toLowerCase()?a.target:f.getClosestByTag(a.target,"A");!d||c._animating||d.getAttribute("data-rel")||(b=d.getAttribute("href"),c._changePanel(b,c.options.animationType,"forward"),a.preventDefault())},p._onAnimationEnd=function(){var a=this,b=a.element,c=a._ui.toPanel,d=a._ui.activePanel,e=a._animationClasses;a._animating&&(d.style.display="none",d.classList.remove(e.OUT),c.classList.add(m.ACTIVE_PANEL),c.classList.remove(m.PRE_IN),c.classList.remove(e.IN),l.trigger(d,a.eventType.HIDE),l.trigger(c,a.eventType.SHOW),l.trigger(b,a.eventType.CHANGE,{fromPanel:d,toPanel:c,direction:a._direction}),a._ui.activePanel=c,a._animating=!1)},p._onPagebeforeshow=function(){var a=b.router.Router.getInstance().getRoute("panel");a.setActive(this._ui._activePanel)},p.handleEvent=function(a){var b=this;switch(a.type){case"vclick":b._onClick(a);break;case"webkitAnimationEnd":case"mozAnimationEnd":case"msAnimationEnd":case"oAnimationEnd":case"animationend":b._onAnimationEnd(a);break;case"pagebeforeshow":b._onPagebeforeshow(a)}},p.changePanel=function(a,b,c){this._changePanel(a,b,c)},p._destroy=function(){var a=this;a._ui=null,a.options=null,a._eventType=null,d(a.element)},b.widget.core.PanelChanger=n,i.defineWidget("PanelChanger","[data-role='panel-changer'], .ui-panel-changer",["changePanel"],n,"core")}(a.document,d),function(b,d){var e=d.widget.BaseWidget,f=d.engine,g=function(){var a=this;a._activeIndex=null,a.options={}},h={indicator:"ui-page-indicator",indicatorActive:"ui-page-indicator-active",indicatorItem:"ui-page-indicator-item",indicatorDashed:"ui-page-indicator-dashed",linearIndicator:"ui-page-indicator-linear",circularIndicator:"ui-page-indicator-circular"},i={IN_CIRCLE:60,IN_LINEAR:5},j={LINEAR:"linear",CIRCULAR:"circular"},k=8,l=new e;g.classes=h,l._configure=function(){this.options={maxPage:null,numberOfPages:null,layout:"linear",intervalAngle:6,appearance:"dashed"}},l._build=function(a){var b=this,c=b.options;return b._createIndicator(a),c.layout===j.CIRCULAR&&b._circularPositioning(a),"dashed"===c.appearance&&a.classList.add(h.indicatorDashed),a},l._createIndicator=function(a){var c,e,f,g,i=this,k=i.options.numberOfPages;if(null===k)return void d.error("build error: numberOfPages is null");for(i.options.layout=i.options.layout.toLowerCase(),i.options.layout===j.CIRCULAR?(a.classList.remove(h.linearIndicator),a.classList.add(h.circularIndicator)):(a.classList.remove(h.circularIndicator),a.classList.add(h.linearIndicator)),f=i._getMaxPage(),e=f>k?k:f,c=0;e>c;c++)g=b.createElement("span"),g.classList.add(h.indicatorItem),a.appendChild(g)},l._circularPositioning=function(a){var b,c,d,e=this,f=a.children,g=f.length,h=parseFloat(e.options.intervalAngle);for(b=a.offsetWidth/2-k,d=0;g>d;d++)c="rotate("+(d*h-90-(g-1)*h*.5)+"deg) translate("+b+"px) ",f[d].style.transform=c},l._getMaxPage=function(){var a,b=this,c=b.options;return a=c.layout===j.CIRCULAR?c.maxPage||i.IN_CIRCLE:c.maxPage||i.IN_LINEAR},l._removeIndicator=function(a){a.textContent=""},l.setActive=function(b){var e,f,g,i=this,j=b,k=i.element.children,l=parseInt(i.options.numberOfPages,10),m=0,n=h.indicatorActive;if(null!==b&&b!==c){if(i._activeIndex=b,e=i._getMaxPage(),f=a.parseInt(e/2,10),l>e)m=l-e;else{if(isNaN(l))return void d.error("setActive error: numberOfPages is not a number");if(0===l)return}g=i.element.querySelector("."+n),g&&g.classList.remove(n),b>f&&f+m>=b?j=f:b>f+m&&(j=b-m),k[j].classList.add(n)}},l._refresh=function(){var a=this,b=a.element;a._removeIndicator(b),a._createIndicator(b),a.options.layout===j.CIRCULAR&&a._circularPositioning(b)},l._destroy=function(){this._removeIndicator(this.element)},g.prototype=l,d.widget.core.PageIndicator=g,f.defineWidget("PageIndicator","[data-role='page-indicator'], .ui-page-indicator",["setActive"],g,"core")}(a.document,d),function(a,b){function c(a){i.on(a.element,"input change vmouseup vmousedown",a,!1),a.isKeyboardSupport&&i.on(a.element,"focus, blur, keyup",a,!1)}function d(a){i.off(a.element,"input change vmouseup vmousedown",a,!1),a.isKeyboardSupport&&i.off(a.element,"focus, blur, keyup",a,!1)}var e=b.widget.BaseWidget,f=b.widget.core.BaseKeyboardSupport,g=b.engine,h=b.util.object.merge,i=b.event,j={type:"continues",orientation:"horizontal",expand:!1,warning:!1,warningLevel:0,disabled:!1,toggle:"",min:0,max:10,step:1,labels:!1},k=["orientation","expand","warning","warningLevel","toggle"],l=function(){var a=this;a.options=h({},j),f.call(a),a._ui={scale:null}},m={SLIDER:"ui-slider",SLIDER_VALUE:"ui-slider-value",SLIDER_HANDLER:"ui-slider-handler",SLIDER_DISABLED:"ui-disabled",SLIDER_HANDLER_VALUE:"ui-slider-handler-value",SLIDER_FOCUS:"ui-slider-focus",SLIDER_BAR:"ui-slider-bar",SLIDER_ACTIVE:"ui-slider-active",TRACK:"ui-slider-handler-track",SPACE_BEFORE:"ui-slider-before-space",SPACE_AFTER:"ui-slider-after-space",SLIDER_HAS_LABELS:"ui-slider-has-labels",LABEL:"ui-slider-label",LABEL_MIN:"ui-slider-label-min",LABEL_MAX:"ui-slider-label-max"},n=new e;l.prototype=n,l.classes=m,n._updateLevelBar=function(){var b,c,d=this,e=d._ui,f=e.scale,g=d.options,h=Math.round((g.max-g.min)/g.step)+1,i=f.children.length,j=h-i;if(j>0)for(c=0;j>c;c++)b=a.createElement("div"),b.classList.add("ui-slider-scale-dot"),f.appendChild(b);else if(0>j)for(j=-j,c=0;j>c;c++)f.removeChild(f.lastElementChild)},n._setType=function(b,c){var d=this,e=d._ui,f=e.scale,g=e.containerElement;"level-bar"===c?(f||(f=a.createElement("div"),f.classList.add("ui-slider-scale"),g.appendChild(f),e.scale=f),d._updateLevelBar()):f&&(g.remove(f),e.scale=null),g.classList.toggle("ui-slider-level-bar","level-bar"===c),d.options.type=c},n._setLabels=function(a,b){var c=this;b&&(c._ui.labelMin.innerText||(c._ui.labelMin.innerText=c.options.min),c._ui.labelMax.innerText||(c._ui.labelMax.innerText=c.options.max)),c._ui.containerElement.classList.toggle(m.SLIDER_HAS_LABELS,b),c.options.labels=b},n._build=function(b){var c=this,d=c._ui,e=a.createElement("div"),f=a.createElement("div"),g=a.createElement("div"),h=a.createElement("div"),i=a.createElement("div"),j=a.createElement("div"),k=a.createElement("div"),l=a.createElement("div"),n=a.createElement("div");return e.classList.add(m.SLIDER),f.classList.add(m.SLIDER_BAR),g.classList.add(m.SLIDER_VALUE),f.appendChild(g),h.classList.add(m.SLIDER_HANDLER),i.classList.add(m.TRACK),j.classList.add(m.SPACE_BEFORE),k.classList.add(m.SPACE_AFTER),l.classList.add(m.LABEL),n.classList.add(m.LABEL),l.classList.add(m.LABEL_MIN),n.classList.add(m.LABEL_MAX),i.appendChild(j),i.appendChild(h),i.appendChild(k),e.appendChild(i),e.appendChild(f),e.appendChild(l),e.appendChild(n),b.parentNode.appendChild(e),d.barElement=f,d.valueElement=g,d.handlerElement=h,d.containerElement=e,d.beforeSpace=j,d.afterSpace=k,d.labelMin=l,d.labelMax=n,b.parentNode.replaceChild(e,b),e.appendChild(b),c.isKeyboardSupport&&(c.preventFocusOnElement(b),e.setAttribute("data-focus-lock","true"),e.setAttribute("tabindex","0")),b},n._updateProperties=function(){var a=this,b=a.options,c=parseFloat(a.element.getAttribute("value"));a._min=b.min,a._max=b.max,a._minValue=a._min,a._maxValue=a._max,a._interval=a._max-a._min,a._value=c?c:parseFloat(a.element.value),a._previousValue=a._value},n._init=function(a){var b=this;return b._warnAboutUnsupportedOptions(),b._updateProperties(),b._setDisabled(a),b._locked=!1,b._initLayout(),a},n._warnAboutUnsupportedOptions=function(){var a=this.options;k.forEach(function(c){a[c]!==j[c]&&b.warn("The "+c+" option has no effect on Slider widget")})},n._initLayout=function(){var a=this,b=a._ui;a._setType(a.element,a.options.type),a._setLabels(a.element,a.options.labels),a._containerElementWidth=b.containerElement.offsetWidth,a._setValue(a._value)},n._setNormalValue=function(a){var b,c=this,d=c._ui;b=(a-c._min)/(c._max-c._min)*100,d.beforeSpace.style.width=b+"%",d.afterSpace.style.width=100-b+"%",d.valueElement.style.width=b+"%"},n._setValue=function(a){var b,c=this,d=c.element;c._previousValue=c._value,a<c._min?a=c._min:a>c._max&&(a=c._max),b=parseFloat(a),c._setNormalValue(a),c._previousValue!==b&&(d.setAttribute("value",b),d.value=b,c._value=b)},n._getValue=function(){return this._value},n._getContainer=function(){return this._ui.containerElement},n._setDisabled=function(a){var b=this,c=b.options;c.disabled===!0||a.disabled?b._disable(a):b._enable(a)},n._enable=function(a){a&&(this.options.disabled=!1,this._ui.containerElement&&this._ui.containerElement.classList.remove(m.SLIDER_DISABLED))},n._disable=function(a){a&&(this.options.disabled=!0,this._ui.containerElement&&this._ui.containerElement.classList.add(m.SLIDER_DISABLED))},n._bindEvents=function(){c(this)},n.handleEvent=function(a){var b=this,c=a.type;if(!this.options.disabled)switch(c){case"input":case"change":b._setValue(b.element.value);break;case"vmousedown":b._onTouchStart(a);break;case"vmouseup":b._onTouchEnd(a);break;case"keyup":b._onKeyUp(a)}},n._onTouchStart=function(){this._ui.containerElement.classList.add(m.SLIDER_ACTIVE)},n._onTouchEnd=function(){this._ui.containerElement.classList.remove(m.SLIDER_ACTIVE)},n._decreaseValue=function(){var a=this;a._setValue(a._value-(parseFloat(a.element.step)||1))},n._increaseValue=function(){var a=this;a._setValue(a._value+(parseFloat(a.element.step)||1))},n._onKeyUp=function(a){var b=this,c=f.KEY_CODES;if(b._locked)switch(a.keyCode){case c.left:b._decreaseValue();break;case c.right:b._increaseValue()}},n._refresh=function(){var a=this;a._updateProperties(),a._setDisabled(a.element),a._initLayout()},n._destroy=function(){var a=this,b=a._ui.containerElement;d(a),b.parentNode&&b.parentNode.removeChild(b),a._ui=null,a._options=null},b.widget.core.Slider=l,g.defineWidget("Slider","input[data-role='slider'], input[type='range'], input[data-type='range']",["value"],l,"core"),f.registerActiveSelector("input[data-role='slider'], input[type='range'], input[data-type='range'], .ui-slider-handler")}(a.document,d),function(a,b){b.widget.core.progress=b.widget.core.progress||{}}(a.document,d),function(a,b){b.widget.core.progress.type=b.widget.core.progress.type||{}}(a,d),function(a,b){b.widget.core.progress.type["interface"]={build:function(){},init:function(){},refresh:function(){},changeValue:function(){},destroy:function(){}}}(a.document,d),function(a,b){function c(a){var b=a._ui,c=a.options,d=100*c.value/(c.max-c.min);b.indeterminateBarElement.style.width=d+"%"}var d=b.util.object,e=b.widget.core.progress.type,f=e["interface"],g={uiIndeterminatebar:"ui-indeterminate-bar",uiIndeterminatebarIndeterminate:"ui-indeterminate-bar-indeterminate"};e.indeterminatebar=d.merge({},f,{build:function(b,c){var d,e={},f=c;return d=a.createElement("div"),f.classList.add(g.uiIndeterminatebar),d.classList.add(g.uiIndeterminatebarIndeterminate),f.appendChild(d),e.indeterminateBarElement=d,b._ui=e,f},init:function(a,b){var d=a._ui,e=b;d.indeterminateBarElement=d.indeterminateBarElement||e.querySelector("."+g.uiIndeterminatebarActivity),c(a)},refresh:function(a){c(a)},changeValue:function(a){c(a)}})}(a.document,d),function(a,b){function c(a,b){switch(a.classList.contains(g.uiIndeterminateCircle)||a.classList.add(g.uiIndeterminateCircle),a.classList.remove(g.uiIndeterminateCircleSmallTitle),a.classList.remove(g.uiIndeterminateCircleSmall),a.classList.remove(g.uiIndeterminateCircleMedium),a.classList.remove(g.uiIndeterminateCircleLarge),b){case"small-title":a.classList.add(g.uiIndeterminateCircleSmallTitle);break;case"small":a.classList.add(g.uiIndeterminateCircleSmall);break;case"medium":a.classList.add(g.uiIndeterminateCircleMedium);break;case"large":a.classList.add(g.uiIndeterminateCircleLarge);break;default:a.classList.add(g.uiIndeterminateCircleMedium)}}var d=b.util.object,e=b.widget.core.progress.type,f=e["interface"],g={uiIndeterminateCircle:"ui-indeterminate-circle",uiIndeterminateCircleSmallTitle:"ui-indeterminate-circle-small-title",uiIndeterminateCircleSmall:"ui-indeterminate-circle-small",uiIndeterminateCircleMedium:"ui-indeterminate-circle-medium",uiIndeterminateCircleLarge:"ui-indeterminate-circle-large"};e.indeterminatecircle=d.merge({},f,{build:function(){},init:function(a,b){var d=a.options,e=d.size;c(b,e)},refresh:function(a){var b=a.element,d=a.options.size;c(b,d)}})}(a.document,d),function(a,b){function c(a,b){a.setAttribute("aria-valuenow",b.value),a.setAttribute("aria-valuemin",b.min),a.setAttribute("aria-valuemax",b.max)}function d(a){var b=a._ui,c=a.options,d=100*c.value/(c.max-c.min);b.progressBarValueElement.style.width=d+"%"}function e(a){var b=a._ui,c=a.options;b.labelCurrentValue&&(b.labelCurrentValue.textContent=c.value),b.labelMinValue&&(b.labelMinValue.textContent=c.min),b.labelMaxValue&&(b.labelMaxValue.textContent=c.max)}var f=b.util.object,g=b.widget.core.progress.type,h=g["interface"],i={uiProgressbar:"ui-progress-bar",uiProgressbarValue:"ui-progress-bar-value",uiProgressbarValueBg:"ui-progress-bar-value-bg",uiProgressbarLabelsTop:"ui-progress-bar-labels-top",uiProgressbarLabelsBottom:"ui-progress-bar-labels-bottom",labelCurrentValue:"ui-progress-current-value",labelMinValue:"ui-progress-min-value",labelMaxValue:"ui-progress-max-value"},j=function(a,b){return[{start:0,end:800,callback:function(a,c){b.call(this,a,c)}}]};g.bar=f.merge({},h,{build:function(b,c){var d,e,f,g,h={};return c.classList.add(i.uiProgressbar),d=a.createElement("div"),d.classList.add(i.uiProgressbarValue),e=a.createElement("div"),e.classList.add(i.uiProgressbarValueBg),f=a.createElement("div"),f.classList.add(i.uiProgressbarLabelsTop),g=a.createElement("div"),g.classList.add(i.uiProgressbarLabelsBottom),e.appendChild(d),c.appendChild(f),c.appendChild(e),c.appendChild(g),h.progressBarValueElement=d,h.progressBarValueBg=e,h.labelsTop=f,h.labelsBottom=g,b._ui=h,c},init:function(a,b){var f=a._ui,g=a.options,h=[],j=[];h=[].slice.call(b.querySelectorAll(".ui-progress-bar-label-right-top")),j=[].slice.call(b.querySelectorAll(".ui-progress-bar-label-left-bottom, .ui-progress-bar-label-right-bottom")),h=h.concat([].slice.call(b.parentElement.querySelectorAll(".ui-progress ~ .ui-progress-bar-label-right-top"))),j=j.concat([].slice.call(b.parentElement.querySelectorAll(".ui-progress ~ .ui-progress-bar-label-left-bottom, .ui-progress ~ .ui-progress-bar-label-right-bottom"))),h.forEach(function(a){f.labelsTop.appendChild(a)}),j.forEach(function(a){f.labelsBottom.appendChild(a)}),f.progressBarValueElement=f.progressBarValueElement||b.querySelector("."+i.uiProgressbarValue),f.labelCurrentValue=b.querySelector("."+i.labelCurrentValue),f.labelMinValue=b.querySelector("."+i.labelMinValue),f.labelMaxValue=b.querySelector("."+i.labelMaxValue),c(b,g),d(a),e(a)},refresh:function(a){c(a.element,a.options),d(a),e(a)},changeValue:function(a,b,c){var d,f=1850,h=a._ui.progressBarValueElement,i=100*b/(a.options.max-a.options.min),k=100*c/(a.options.max-a.options.min);a._isAnimating||(d=j(f,function(a,b){h.style.width=i+(k-i)*a/b+"%"}),a._animate(f,function(a){d.forEach(function(b){a>=b.start&&a<=b.end?b.callback(a-b.start,b.end-b.start):a>b.end&&b.callback(1,1)})},function(){a.options.value!==c&&g.bar.changeValue(a,c,a.options.value)})),e(a)},destroy:function(a,b){var c=a._ui;return[].slice.call(c.labelsTop.children).forEach(function(a){b.appendChild(a)}),[].slice.call(c.labelsBottom.children).forEach(function(a){b.appendChild(a)}),c.progressBarValueBg.parentElement.removeChild(c.progressBarValueBg),c.labelsTop.parentElement.removeChild(c.labelsTop),c.labelsBottom.parentElement.removeChild(c.labelsBottom),!0}})}(a.document,d),function(a,b){function c(a){var b,c=a.options,d=100*c.value/(c.max-c.min),e=a._ui;d>=50?e.progressValue.classList.add(j.uiProgressCircleHalf):e.progressValue.classList.remove(j.uiProgressCircleHalf),b=360*(d/100),e.progressValueLeft.style.webkitTransform="rotate3d(0.0, 0.0, 1.0, "+b+"deg)"}function d(a){var b=a.options.size,c=parseFloat(b),d=a._ui;if(isNaN(c)){switch(b){case"full":case"large":case"medium":case"small":d.progressContainer.classList.add("ui-progress-circle-"+b)}d.progressContainer.style.fontSize=g.getCSSProperty(d.progressContainer,"width",0,"float")+"px"}else d.progressContainer.style.fontSize=b+"px",d.progressContainer.style.width=b+"px",d.progressContainer.style.height=b+"px"}function e(a){a.progressValue.classList.remove(j.uiProgressbarHalf),a.progressValueLeft.style.webkitTransform=""}var f=b.util.object,g=b.util.DOM,h=b.widget.core.progress.type,i=h["interface"],j={uiProgressCircle:"ui-progress-circle",uiProgressCircleBg:"ui-progress-circle-bg",uiProgressCircleValue:"ui-progress-circle-value",uiProgressCircleValueLeft:"ui-progress-circle-value-left",uiProgressCircleValueRight:"ui-progress-circle-value-right",uiProgressCircleHalf:"ui-progress-circle-half"};h.circle=f.merge({},i,{build:function(b,c){var d,e,f,g,h={},i=c;return h.progressContainer=i,h.progressValueBg=d=a.createElement("div"),h.progressValue=e=a.createElement("div"),h.progressValueLeft=f=a.createElement("div"),h.progressValueRight=g=a.createElement("div"),i.className=j.uiProgressCircle,d.className=j.uiProgressCircleBg,e.className=j.uiProgressCircleValue,f.className=j.uiProgressCircleValueLeft,g.className=j.uiProgressCircleValueRight,e.appendChild(f),e.appendChild(g),i.appendChild(e),i.appendChild(d),b._ui=h,c},init:function(a,b){var e=a._ui;e.progressContainer=e.progressContainer||b,e.progressValueBg=e.progressValueBg||b.querySelector("."+j.uiProgressCircleBg),e.progressValue=e.progressValue||b.querySelector("."+j.uiProgressCircleValue),e.progressValueLeft=e.progressValueLeft||b.querySelector("."+j.uiProgressCircleValueLeft),e.progressValueRight=e.progressValueRight||b.querySelector("."+j.uiProgressCircleValueRight),d(a),c(a)},refresh:function(a){e(a._ui),d(a),c(a)},changeValue:function(a){c(a)}})}(a.document,d),function(a,b){function c(a){a.refresh()}var d=b.widget.BaseWidget,e=b.event,f=b.engine,g=b.util,h=b.util.selectors,i=b.util.object,j=b.widget.core.Page,k={CHANGE:"change"},l={PROGRESS_BAR:"bar",PROGRESS_CIRCLE:"circle",INDETERMINATE_BAR:"indeterminatebar",INDETERMINATE_CIRCLE:"indeterminatecircle"},m={SMALL_HEADER:"small-header",SMALL:"small",MEDIUM:"medium",LARGE:"large",FULL:"full"},n=function(){var a=this;a.options=i.merge({},n.defaults),a._ui={},a._type=null,a._progress=null,a._isAnimating=!1,a._callbacks={}},o={uiProgress:"ui-progress"},p={type:l.PROGRESS_BAR,size:m.MEDIUM,value:100,min:0,max:100},q=new d;return n.prototype=q,n.classes=o,n.events=k,n.defaults=p,q._build=function(a){var c=this,d=c.options;return c._type=d.type,a.classList.add(o.uiProgress),c._progress=b.widget.core.progress.type[d.type],c._progress.build(c,a),a},q._init=function(a){var b=this;return b._progress.init(b,a),a.setAttribute("value",b.options.value),a},q._refresh=function(a){var c=this,d=c.options;return c._type!==d.type?(c._destroy(),b.widget.Progress(a,{type:d.type})):(c._progress.refresh(c),c._setValue(c.options.value),a)},q._setValue=function(a){var b=this,c=b.options,d=b.element;return b._oldValue=c.value,"number"==typeof a?(a=Math.min(c.max,Math.max(c.min,a)),a!==b._oldValue&&(c.value=a,b.isCustomElement||d.setAttribute("data-value",a),d.setAttribute("value",a),e.trigger(d,k.CHANGE),b._progress.changeValue(b,b._oldValue,a)),!0):!1},q._getValue=function(){return parseInt(this.element.getAttribute("value"),10)},q._animate=function(a,b,c){var d=this,e=null,f=function(h){var i=0;null===e&&(e=h),i=h-e,b(i),d._isAnimating&&a>i?g.requestAnimationFrame(f):(d._isAnimating=!1,c())};d._isAnimating=!0,g.requestAnimationFrame(f)},q._bindEvents=function(){var a=this,b=a.element,d=h.getClosestByClass(b,j.classes.uiPage);a._ui.page=d,a._callbacks.onPageBeforeShow=c.bind(null,a),d.addEventListener(j.events.BEFORE_SHOW,a._callbacks.onPageBeforeShow,!1)},q._unbindEvents=function(){var a=this;a._callbacks.onPageBeforeShow&&a._ui.page.removeEventListener(j.events.BEFORE_SHOW,a._callbacks.onPageBeforeShow,!1)},q._destroy=function(){var a=this,b=a.element;if(this._unbindEvents(),!a._progress.destroy(a,b))for(;b.firstChild;)b.removeChild(b.firstChild);return a._ui=null,a._oldValue=null,b},b.widget.core.progress.Progress=n,f.defineWidget("Progress","[data-role='progress'], .ui-progress",[],n,"core"),n}(a.document,d),function(a,b){var c=b.widget.BaseWidget,d=b.engine,e=b.event,f={CARD:"ui-card"},g=function(){this._ui={},this.options={src:""}},h=/([^/])+$/,i={LINKS:"link[href]",IMAGES:"img[src]"},j=new c;g.classes=f,g.prototype=j,j._build=function(a){return a.classList.add(f.CARD),a},j._init=function(a){var c=b.router.Router.getInstance();return""!==this.options.src&&c.open(this.options.src,{rel:"card",card:this}),a},j._include=function(c,d){var e,f,g,j,k,l=this.element;return c.parentNode&&c.ownerDocument===a||(e=c.querySelectorAll(i.LINKS),e.forEach(function(a){0===a.href.indexOf(b.util.path.parseLocation(d.url).domain)&&(k=b.util.path.parseLocation(d.url),j=a.href.replace(k.domain,"").replace(k.directory,""),b.util.load.cssSync(a.href,function(a){b.util.load.addElementToHead(a,!0)},function(a,c){b.warn("There was a problem when loading, status: "+c)})),a.parentElement.removeChild(a)}),c=b.util.importEvaluateAndAppendElement(c,l),d&&d.url&&(k=b.util.path.parseLocation(d.url),g=d.url.replace(h,""),f=c.querySelectorAll(i.IMAGES),f.forEach(function(a){0===a.src.indexOf(b.util.path.parseLocation(d.url).domain)&&(j=a.src.replace(k.domain,"").replace(k.directory,""),a.src=g+j)}))),c},j.changeContent=function(a,c){var d=this;d.element.parentElement?(a=d._include(a,c),b.engine.createWidgets(a),e.trigger(a,"cardcontentchange")):e.trigger(a,"cardcontentabort")},j._destroy=function(){this._unbindEvents()},b.widget.core.Card=g,d.defineWidget("Card",".ui-card",[],g,"core")}(a.document,d),function(a,b,d){var e=d.util.object,f=d.event,g=d.util.selectors,h=d.widget.core.Page,i=Math.min,j=Math.max,k={COLLAPSED:56,EXPANDED:56},l={EXPANDED:"EXPANDED",COLLAPSED:"COLLAPSED",DRAGGING:"DRAGGING"},m=579,n=function(){var a=this;a.options=e.merge({},n.defaults),a._ui={titleContainer:null,leftIconsContainer:null,actionButtonsContainer:null,page:null,selectAll:null,bottomBar:null,instantContainers:[]},a._expandedHeight=k.EXPANDED,a._appbarState=l.COLLAPSED,a._dragStartingHeight=0,a._currentHeight=0,a._instantContainersHeight=0,a._scrolledToTop=!0,a._lockExpanding=!1,a._calculateExtendedHight()},o=d.widget.BaseWidget,p=new o,q="ui-appbar",r={title:q+"-title",leftIconsContainer:q+"-left-icons-container",actionButtonsContainer:q+"-action-buttons-container",instantContainer:q+"-container",titleContainer:q+"-title-container",hasMultilineTitle:q+"-has-multiline",hasSubtitle:q+"-has-subtitle",expanded:q+"-expanded",dragging:q+"-dragging",controlsContainer:q+"-controls-container",expandedTitleContainer:q+"-expanded-title-container",animationFast:q+"-animation-fast",selectAll:"ui-label-select-all",bottomBar:"ui-bottom-bar",hidden:"ui-hidden"},s={leftIconsContainer:{selector:"."+r.leftIconsContainer,"class":r.leftIconsContainer,position:0},titleContainer:{selector:"."+r.titleContainer,"class":r.titleContainer,position:1},actionButtonsContainer:{selector:"."+r.actionButtonsContainer,"class":r.actionButtonsContainer,position:2}},t={IS_CHECKED:".ui-listview li > input[type='checkbox']:checked",IS_NOT_CHECKED:".ui-listview li > input[type='checkbox']:not(:checked)"},u={titleType:"singleLine",expandingEnabled:!0,animation:!0};n.prototype=p,n.defaults=u,n.classes=r,n.selector=".ui-appbar,.ui-header,header,[data-role='header']",p._init=function(a){var b=this;b._initExpandedContainer(a),b._setAnimation(a,b.options.animation),b._appbarState=l.COLLAPSED,b._validateExpanding(),b._ui.page=g.getClosestBySelector(a,h.selector),b._ui.selectAll=a.querySelector("."+r.selectAll+" input[type='checkbox']"),b._ui.bottomBar=b._ui.page.querySelector("."+r.bottomBar)},p._build=function(a){var b=this;return b._createContainers(a),b._findInstantContainers(a),b._readTitleType(a),b._setTitleType(a,b.options.titleType),a},p._calculateInstantContainers=function(a){var b=this,c=0;return a.style.height="auto",b._ui.instantContainers.forEach(function(a){c+=a.offsetHeight}),c},p._updateAppbarDimensions=function(a){var b=this,c=b._instantContainersHeight,d=b._ui.controlsContainer;c>0&&(b._calculateExtendedHight(),b._expandedHeight+=c,b._currentHeight+=c,d&&(d.style.bottom=c+"px"),b._instantContainersHeight=c),a.style.height=k.COLLAPSED+b._instantContainersHeight+"px"},p._findInstantContainers=function(a){var b=this;b._ui.instantContainers=[].slice.call(a.querySelectorAll("."+r.instantContainer)),b._instantContainersHeight=b._calculateInstantContainers(a),b._updateAppbarDimensions(a)},p.addInstantContainer=function(a){var b=this;a&&a instanceof HTMLElement?(a.classList.add(r.instantContainer),b.element.appendChild(a),b.refresh()):d.warn("AppBar: method addInstantContainer needs argument")},p.removeInstantContainer=function(a){var b=this;a&&a instanceof HTMLElement?a.parentElement&&(a.parentElement.removeChild(a),b.refresh()):d.warn("AppBar: method removeInstantContainer needs argument")},p._refresh=function(a){var b=this;a=a||b.element,b._findInstantContainers(a),b._ui.instantContainers.forEach(function(a){d.engine.createWidgets(a)})},p._calculateExtendedHight=function(){var b=this,c=a.screen.height,d=a.screen.width,e=12;c>=580&&960>c&&d>c?b._expandedHeight=.3*c-e:c>=580&&960>c&&c>=d?b._expandedHeight=.3967*c-e:c>=960?b._expandedHeight=.25*c-e:b._expandedHeight=k.EXPANDED},p._initExpandedContainer=function(a){var c=this._ui,d=a.querySelector("."+r.expandedTitleContainer);d||(d=b.createElement("div"),d.classList.add(r.expandedTitleContainer),[].slice.call(c.titleContainer.children).forEach(function(a){d.appendChild(a.cloneNode(!0))})),c.expandedTitleContainer=d,a.insertBefore(d,c.controlsContainer)},p._createContainers=function(a){var c=this._ui;c.controlsContainer=b.createElement("div"),c.controlsContainer.classList.add(r.controlsContainer),a.appendChild(c.controlsContainer),Object.keys(s).forEach(function(d){var e=s[d],f=a.querySelector(e.selector);f||(f=b.createElement("div"),f.classList.add(e["class"]),a.appendChild(f)),c[d]=f}),Object.keys(s).sort(function(a,b){return s[a].position-s[b].position}).forEach(function(a){c.controlsContainer.appendChild(c[a])})},p._bindEvents=function(){var b=this;d.event.enableGesture(b._ui.page,new d.event.gesture.Drag),f.on(b._ui.page,"scrollboundary drag dragstart dragend scrollstart change pagebeforeshow popupshow popuphide",b),a.addEventListener("resize",b,!1)},p.handleEvent=function(a){var b=this;switch(a.type){case"scrollboundary":b._onScrollBoundary(a);break;case"drag":b._onDrag(a);break;case"dragstart":b._onDragStart(a);break;case"dragend":b._onDragEnd(a);break;case"scrollstart":b._onScrollStart(a);break;case"change":b._onChange(a);break;case"pagebeforeshow":b._onPageBeforeShow();break;case"popupshow":b._onPopupShow();break;case"popuphide":b._onPopupHide();break;case"resize":b._onResize()}},p._onPageBeforeShow=function(){var a=this,b=a._ui;b.selectAll&&(a._triggerSelectAll(),b.bottomBar&&a._toggleBottomBar(!!b.page.querySelector(t.IS_CHECKED)),a._updateTitle())},p._onPopupShow=function(){this.options.expandingEnabled=!1},p._onPopupHide=function(){this.options.expandingEnabled=!0},p._onScrollStart=function(){this._scrolledToTop=!1},p._onScrollBoundary=function(a){var b=this,c=a&&a.detail&&a.detail.direction;b._scrolledToTop="top"===c,f.one(b._ui.page,"scrollstart",b._onScrollStart.bind(b))},p._onDragStart=function(a){var b=this;!b._lockExpanding&&b.options.expandingEnabled&&("down"===a.detail.direction&&b._appbarState==l.COLLAPSED&&b._scrolledToTop||"up"===a.detail.direction&&b._appbarState==l.EXPANDED)&&(b._appbarState=l.DRAGGING,b.element.classList.add(r.dragging),b._dragStartingHeight=b.element.getBoundingClientRect().height,b._expandedTitleHeight=0,[].slice.call(b._ui.expandedTitleContainer.children).forEach(function(a){b._expandedTitleHeight+=a.offsetHeight}))},p._setTitlesOpacity=function(a){var b=this,c=b._ui,d=c.titleContainer,e=c.expandedTitleContainer;d.style.opacity=1-a,e.style.opacity=a},p.expand=function(){var a=this,b=a.element;b.style.height=a._expandedHeight+"px",b.classList.add(r.expanded),a._appbarState=l.EXPANDED,a._setTitlesOpacity(1),f.trigger(b,"appbarexpanded")},p._onTransitionEnd=function(){f.trigger(this.element,"appbartransitionend")},p.collapse=function(){var a=this,b=a.element;a._currentHeight=a._instantContainersHeight,b.style.height=k.COLLAPSED+a._instantContainersHeight+"px",b.classList.remove(r.expanded),a._appbarState=l.COLLAPSED,a._setTitlesOpacity(0),f.trigger(b,"appbarcollapsed"),f.one(b,"transitionend transitionEnd webkitTransitionEnd",a._onTransitionEnd.bind(a),!1)},p.lockExpanding=function(a){this._lockExpanding=!!a},p._onDragEnd=function(){var a,b=this;!b._lockExpanding&&b.options.expandingEnabled&&(a=(k.COLLAPSED+b._expandedHeight)/2,b.element.classList.remove(r.dragging),b._currentHeight>a?b.expand():b.collapse())},p._onDrag=function(a){var b=this,d=a&&a.detail&&a.detail.deltaY,e=b._dragStartingHeight+(d!==c?d:0),f=0;b._lockExpanding||b._appbarState!==l.DRAGGING||(e=i(e,b._expandedHeight),e=j(e,k.COLLAPSED),b._currentHeight!==e&&(b._currentHeight=e,b.element.style.height=e+"px",f=e-k.COLLAPSED,f>b._expandedTitleHeight?b._setTitlesOpacity(f/(b._expandedHeight-k.COLLAPSED)):b._setTitlesOpacity(0)))},p._validateExpanding=function(){var b=this;a.screen.height<=m?b._lockExpanding=!0:b._lockExpanding=!1},p._onResize=function(){this._validateExpanding()},p._triggerSelectAll=function(){var a=this;f.trigger(a.element,"select-all",{checked:a._ui.selectAll.checked})},p._toggleSelectAll=function(a){var b=this._ui.selectAll;b&&(b.checked=a,a?b.setAttribute("checked","checked"):b.removeAttribute("checked"))},p._toggleBottomBar=function(a){this._ui.bottomBar.classList.toggle(r.hidden,!a)},p._getNumberOfChecked=function(){return this._ui.page.querySelectorAll(t.IS_CHECKED).length},p._onChange=function(a){var b=a.target,c=this,d=c._ui,e=c._ui.page;d.selectAll&&"INPUT"===b.tagName&&(b===d.selectAll?c._triggerSelectAll():c._toggleSelectAll(!e.querySelector(t.IS_NOT_CHECKED)),d.bottomBar&&c._toggleBottomBar(!!e.querySelector(t.IS_CHECKED)),d.selectAll&&c._updateTitle())},p._updateTitle=function(){var a=[].slice.call(this.element.querySelectorAll("."+r.title)),b=this._getNumberOfChecked();a.forEach(function(a){a.textContent=0===b?"Select items":b+" selected"})},p._unbindEvents=function(){var b=this;f.off(b._ui.page,"scrollboundary drag dragstart dragend scrollstart change pagebeforeshow popupshow popuphide",b),a.removeEventListener("resize",b,!1)},p._destroy=function(){var a=this;a._unbindEvents()},p._readTitleType=function(){var a=this,b=a._ui.titleContainer;b.classList.contains(r.hasMultilineTitle)&&(a.options.titleType="multiline"),b.classList.contains(r.hasSubtitle)&&(a.options.titleType="subtitle")},p._setTitleType=function(a,b){var c=this,d=c._ui.titleContainer;switch(d.classList.remove(r.hasMultilineTitle,r.hasSubtitle),b){case"multiline":d.classList.add(r.hasMultilineTitle);break;case"subtitle":d.classList.add(r.hasSubtitle);break;case"singleLine":}},p._setExpandingEnabled=function(a,b){var c=this;c.options.expandingEnabled!==b&&(c.options.expandingEnabled=b,b||c._appbarState===l.COLLAPSED||c.collapse())},p._setAnimation=function(a,b){this.options.animation=b,a.classList.toggle(r.animationFast,!b)},d.widget.core.Appbar=n,d.engine.defineWidget("Appbar",n.selector,[],n,"core")}(a,a.document,d),function(a,b,c){var d=c.widget.BaseWidget,e=c.engine,f=function(){this._ui={}},g=["width","height","position","scale","rotation","controls","autoplay","light","src","show","hide","mtl"],h=new d;f.prototype=h,h._init=function(a){var b=this;return b.observer=new MutationObserver(b._attributeChange.bind(this)),b.observer.observe(a,{attributes:!0}),a},h._attributeChange=function(a){
+var b=this;a.forEach(function(a){var c,d=a.attributeName;-1!==g.indexOf(d)&&(c=a.target,c.hasAttribute(d)?b._ui.rType.setAttribute(d,c.attributes[d].value):b._ui.rType.removeAttribute(d))})},h._build=function(a){var c,d=b.createElement("r-type"),e=a.attributes;for(c=0;c<e.length;c++)-1!==g.indexOf(e[c].name)&&d.setAttribute(e[c].name,e[c].value);return this._ui.rType=d,a.appendChild(d),a},h._destroy=function(){var a=this,b=a._ui,c=b.rType;c&&c.parentNode&&c.parentNode.removeChild(c),this.observer.disconnect()},c.widget.core.Interactive3D=f,e.defineWidget("Interactive3D",".ui-i3d",[],f,"core")}(a,a.document,d),function(a,b,c){var d=c.util.object,e=function(){this.options=d.merge({},e.defaults),this.observer=null},f={value:"coverflow"},g=c.widget.BaseWidget,h=new g;e.prototype=h,e.defaults=f,h._init=function(a){var b=this;return a.getAttribute("value")||a.setAttribute("value",b.options.value),b.observer=new MutationObserver(b._checkEffectChange.bind(this)),b.observer.observe(a,{attributes:!0}),a},h._checkEffectChange=function(a){a.forEach(function(a){"data-effect"===a.attributeName&&this.element.getAttribute("data-effect")&&(this.options.value=this.element.getAttribute("data-effect"),this._refresh())}.bind(this))},h._refresh=function(){var a=this;a._setValue(a.options.value)},h._setValue=function(b){this.ui={},this.ui.$element=a.jQuery(this.element).flipster({style:b,spacing:-.5})},h._build=function(b){return b.getAttribute("data-effect")&&(this.options.value=b.getAttribute("data-effect")),this.ui={},a.jQuery&&"function"==typeof a.jQuery.fn.flipster?this.ui.$element=a.jQuery(b).flipster({style:this.options.value,spacing:-.5}):c.warn("JQuery or flipster.js not exists"),b},h._destroy=function(){this.observer.disconnect()},c.engine.defineWidget("CoverFlow",".ui-coverflow",[],e,"core")}(a,a.document,d),function(a,b,d){var e=d.util.object,f="intermittent",g="continuous",h="x",i="y",j=h,k=i,l="none",m={stackedBar:"stacked-bar",line:"line",stackedArea:"stacked-area",scatterplot:"scatterplot",bar:"bar"},n={graph:m.line,color:"#0097D8",xlabel:"",ylabel:"",axisXType:"time",axisYType:"linear",mode:f,value:[],timeAxis:j,groupKey:"label",legend:!1},o=function(){var a=this;a.options=e.merge({},o.defaults),a.data=[],a.size="",a._initialData=!0,a.split="formula",a.guide={color:{brewer:[n.color]},showGridLines:"xy",x:{nice:!1,label:{text:n.xlabel}},y:{nice:!1,label:{text:n.ylabel}}},a.dimensions={x:{type:"order",scale:"time"},y:{type:"order",scale:"linear"}},a.chart=null},p={graphContainer:"ui-graph"},q=d.widget.BaseWidget,r=new q;o.prototype=r,o.defaults=n,o.MODE={INTERMITTENT:f,CONTINUOS:g},o.TIME_AXIS={X:j,Y:k,NONE:l},r._newChart=function(b){var c=this,d=null;c.element.innerHTML="",c._rebuildCache(),d=c._prepareChartData(),c.chart=new a.tauCharts.Chart({data:[],type:c.options.graph,x:h,y:i,color:"label",size:c.size,split:c.split,guide:c.guide,dimensions:c.dimensions,plugins:c.options.legend?[a.tauCharts.api.plugins.get("legend")]:[]}),c.chart.renderTo(b),c._updateChart(d)},r._setChartAxis=function(a){var b=this,c=b.dimensions[a],d=b.options["axis"+a.toUpperCase()+"Type"];switch(c.type="order",d){case"time":case"index":c.scale="time",b.guide[a].tickFormat="day";break;case"order":c.scale="ordinal";break;case"linear":c.scale="linear"}},r._init=function(a){var b=this,c=[],d=b.guide;if(b.options.color="string"==typeof b.options.color?b.options.color.split(","):b.options.color,d.color.brewer=b.options.color,d.x.label.text=b.options.xlabel,d.y.label.text=b.options.ylabel,b._setChartAxis("x"),b._setChartAxis("y"),b.data.length=0,b.options.value){try{c=JSON.parse(b.options.value)}catch(e){}c.length>0&&(c.forEach(function(a){b._addData(a)}),b._initialData=!0)}else b._addData(0),b._initialData=!0;return b._newChart(a),a},r._build=function(b){var c=this;return a.tauCharts?(c._createDivElement(b,p.graphContainer),b):null},r._addData=function(a){var b=Date.now(),c={time:b,value:a,cache:null},d=this;d._initialData&&(d.data=[],d._initialData=!1),c.cache=d._map(c,d.data.length),d.data.push(c)},r._map=function(a,b){var d,e=[],f=a.value,g=a.time,h=this.options.timeAxis,i=this.options.axisXType,l=this.options.groupKey,m=0,n=0;if("object"==typeof f?f.x!==c?(e.push(f.x),f.y!==c&&e.push(f.y),f[l]!==c&&e.push(f[l])):Object.keys(f).forEach(function(a){e.push(f[a])}):e=[f],1===e.length){switch(i){case"time":h===j?(n=parseFloat(e[0])||0,m=g):(m=parseFloat(e[0])||0,h===k&&(n=g));break;case"index":m=b,n=parseFloat(e[0])||0}d="Series 1"}else{switch(i){case"index":m=b,n=parseFloat(e[0])||0;break;default:m=parseFloat(e[0])||0,n=parseFloat(e[1])||0}d=e[e.length-1]}return{x:m,y:n,label:d}},r._rebuildCache=function(){var a=this;a.data.forEach(function(b,c){b.cache=a._map(b,c)})},r._prepareChartData=function(){return this.data.map(function(a){return a.cache})},r._updateChart=function(a){var b=this;b.options.mode===f&&(a.length=0),b.chart.setData(a),b.element.setAttribute("data-value",JSON.stringify(a))},r._setOneValue=function(a){var b=this;return b._addData(a),b._updateChart(b._prepareChartData()),!1},r._setValue=function(a){var b=Array.isArray(a)?a:[a],c=!0,d=this;return b.forEach(function(a){!d._setOneValue(a)&&c&&(c=!1)}),c},r._getValue=function(){return this.data},r._createDivElement=function(a,c){var d=b.createElement("div");d.classList.add(c),a.appendChild(d)},r._refresh=function(){var a=this;a.guide={color:{brewer:"string"==typeof a.options.color?a.options.color.split(","):a.options.color},x:{label:{text:a.options.xlabel}},y:{label:{text:a.options.ylabel}}},a._newChart(a.element)},d.widget.core.Graph=o,d.engine.defineWidget("Graph",".ui-graph",[],o,"core")}(a,a.document,d),function(){function c(a,b,c){var d=a.element,e=d.classList,f=a._ui.overlay,g=a._callbacks.animationEnd;d.removeEventListener("animationend",g,!1),d.removeEventListener("webkitAnimationEnd",g,!1),d.removeEventListener("mozAnimationEnd",g,!1),d.removeEventListener("oAnimationEnd",g,!1),d.removeEventListener("msAnimationEnd",g,!1),b.split(" ").forEach(function(a){a=a.trim(),a.length>0&&(e.remove(a),f&&f.classList.remove(a))}),"pending"===c.state()&&c.resolve()}function e(a,b){var c=new i;return c.then(function(){c===a._callbacks.transitionDeferred&&b()}),a._callbacks.transitionDeferred=c,c}var f=d.widget.BaseWidget,g=d.engine,h=d.util.object,i=d.util.deferred,j=d.util.selectors,k=d.event,l=d.router&&d.router.Router,m=d.widget.core.BaseKeyboardSupport,n=d.widget.core.Page,o="[data-role='popup'], .ui-popup",p={transition:"none",dismissible:!0,overlay:!0,header:!1,footer:!1,content:null,overlayClass:"",closeLinkSelector:"[data-rel='back']",history:null,closeAfter:null},q={DURING_OPENING:0,OPENED:1,DURING_CLOSING:2,CLOSED:3},r="ui-popup",s={popup:r,active:r+"-active",overlay:r+"-overlay",header:r+"-header",footer:r+"-footer",content:r+"-content",wrapper:r+"-wrapper",toast:r+"-toast",toastSmall:r+"-toast-small",build:"ui-build",overlayShown:r+"-overlay-shown"},t={header:"."+s.header,content:"."+s.content,footer:"."+s.footer},u="popup",v={show:u+"show",hide:u+"hide",before_show:u+"beforeshow",transition_start:u+"transitionstart",before_hide:u+"beforehide"},w=function(){var a=this,b={};a.selectors=t,a.options=h.merge({},w.defaults),a.storedOptions=null,a.state=q.CLOSED,b.overlay=null,b.header=null,b.footer=null,b.content=null,b.container=null,b.wrapper=null,a._ui=b,a._callbacks={}},x=new f;w.classes=s,w.events=v,w.defaults=p,w.selector=o,x._buildContent=function(a){var c,d,e=this,f=e._ui,g=e.selectors,h=e.options,i=f.content||a.querySelector(g.content),j=f.footer||a.querySelector(g.footer),k=[].slice.call(a.childNodes),l=k.length;if(!i){for(i=b.createElement("div"),i.className=s.content,c=0;l>c;++c)d=k[c],d!==f.footer&&d!==f.header&&i.appendChild(d);"string"==typeof h.content&&(i.innerHTML=h.content),a.insertBefore(i,j)}i.classList.add(s.content),f.content=i},x._buildHeader=function(a){var c=this,d=c._ui,e=c.options,f=c.selectors,g=d.content||a.querySelector(f.content),h=d.header||a.querySelector(f.header);h||e.header===!1||(h=b.createElement("div"),h.className=s.header,"boolean"!=typeof e.header&&(h.innerHTML=e.header),a.insertBefore(h,g)),h&&h.classList.add(s.header),d.header=h},x._setHeader=function(a,b){var c=this,d=c._ui,e=d.header;e&&(e.parentNode.removeChild(e),d.header=null),c.options.header=b,c._buildHeader(d.container)},x._buildFooter=function(a){var c=this,d=c._ui,e=c.options,f=d.footer||a.querySelector(c.selectors.footer);f||e.footer===!1||(f=b.createElement("div"),f.className=s.footer,"boolean"!=typeof e.footer&&(f.innerHTML=e.footer),a.appendChild(f)),f&&f.classList.add(s.footer),d.footer=f},x._setFooter=function(a,b){var c=this,d=c._ui,e=d.footer;e&&(e.parentNode.removeChild(e),d.footer=null),c.options.footer=b,c._buildFooter(d.container)},x._build=function(a){var c,d=this,e=d._ui,f=a.firstChild,g=a.classList;for(g.add(s.popup),g.contains(s.toastSmall)&&g.add(s.toast),c=b.createElement("div"),c.classList.add(s.wrapper),e.wrapper=c,e.container=c;f;)c.appendChild(f),f=a.firstChild;return a.appendChild(c),d._buildHeader(e.container),d._buildFooter(e.container),d._buildContent(e.container),d._setOverlay(a,d.options.overlay),a},x._setOverlay=function(a,c){var e=this,f=e.options.overlayClass,g=e._ui,h=g.overlay;a.classList.contains("ui-slider-popup")||a.classList.contains(s.toast)||(h||(h=b.createElement("div"),a.parentNode?a.parentNode.insertBefore(h,a):d.warn("Popup is creating on element outside DOM"),g.overlay=h),h.className=s.overlay+(f?" "+f:""),c?h.style.opacity="":h.style.opacity=0)},x._isActive=function(){var a=this.state;return a===q.DURING_OPENING||a===q.OPENED},x._isOpened=function(){return this.state===q.OPENED},x._init=function(b){var c=this,d=c.selectors,e=c._ui,f=c.options,g=c.element.classList;e.header=e.header||b.querySelector(d.header),e.footer=e.footer||b.querySelector(d.footer),e.content=e.content||b.querySelector(d.content),e.wrapper=e.wrapper||b.querySelector("."+s.wrapper),e.container=e.wrapper||b,e.page=j.getClosestByClass(b,n.classes.uiPage)||a,e.pageContent="function"==typeof e.page.querySelector?e.page.querySelector("."+n.classes.uiContent):null,g.contains(s.toast)&&(f.closeAfter=f.closeAfter||2e3),null===f.history&&(f.history=!g.contains(s.toast))},x._setActive=function(a){var b,c=this,d=s.active,e=c.element.classList,f=l&&l.getInstance().getRoute("popup");b=h.merge({},c.options,{positionTo:null,link:null}),a?(f&&f.setActive(c,b),e.add(d),c.state=q.OPENED):(f&&f.setActive(null,b),e.remove(d),c.state=q.CLOSED),c._ui.content.scrollHeight>c._ui.content.clientHeight&&c._ui.footer.classList.add("bottomDivider")},x._onScroll=function(){var a=this,b=a._ui.content;0===b.scrollTop?(a._ui.header.classList.remove("topDivider"),a._ui.footer.classList.add("bottomDivider")):b.scrollHeight-b.clientHeight===b.scrollTop?(a._ui.header.classList.add("topDivider"),a._ui.footer.classList.remove("bottomDivider")):(a._ui.header.classList.add("topDivider"),a._ui.footer.classList.add("bottomDivider"))},x._bindEvents=function(){var c=this;k.on(c._ui.page,"pagebeforehide",c,!1),k.on(a,"resize",c,!1),k.on(b,"vclick",c,!1),k.on(c._ui.content,"scroll",c,!1)},x._unbindEvents=function(){var c=this;k.off(c._ui.page,"pagebeforehide",c,!1),k.off(a,"resize",c,!1),k.off(b,"vclick",c,!1),k.off(c._ui.content,"scroll",c,!1)},x._layout=function(){},x.open=function(b){var c,e=this,f=e.close.bind(e);e._isActive()||(e._storeOpenOptions(b),c=h.merge(e.options,b),c.dismissible||d.router.Router.getInstance().lock(),c.closeAfter>0?(e.element.classList.contains(s.toast)&&(c.transition="fade"),e._show(c),e._closeTimeout=a.setTimeout(f,c.closeAfter)):e._show(c))},x.close=function(a){var b=this,c=h.merge(b.options,a);b._isActive()&&(clearTimeout(b._closeTimeout),c.dismissible||d.router.Router.getInstance().unlock(),b._hide(c))},x._storeOpenOptions=function(a){var b,c=this,d=c.options,e={};for(b in a)a.hasOwnProperty(b)&&(e[b]=d[b]);c.storedOptions=e},x._restoreOpenOptions=function(){var a=this,b=a.options,c=["x","y","fromHashChange"];b=h.merge(b,a.storedOptions),h.removeProperties(b,c)},x._show=function(a){var b=this,c=h.merge({},a),d=b._ui.overlay,e=b._ui.pageContent;b._layout(b.element),b.state=q.DURING_OPENING,c.ext=" in ",b.trigger(v.before_show),d&&d.classList.toggle(s.overlayShown,!0),e&&e.classList.toggle(n.classes.uiContentUnderPopup,!0),b._transition(c,b._onShow.bind(b)),b.trigger(v.transition_start)},x._onShow=function(){var a=this;a._setActive(!0),a.isKeyboardSupport&&(a.disableFocusableElements(this._ui.page),a.enableDisabledFocusableElements(this.element),m.focusElement(this.element)),a.trigger(v.show)},x._hide=function(a){var b=this,c=b._isOpened(),d=b._callbacks,e=b._ui.pageContent;b.state=q.DURING_CLOSING,b.trigger(v.before_hide),e&&e.classList.toggle(n.classes.uiContentUnderPopup,!1),c?(a.ext=" out ",b._transition(a,b._onHide.bind(b))):(d.transitionDeferred&&d.transitionDeferred.reject(),d.animationEnd&&d.animationEnd(),b._onHide())},x._onHide=function(){var a=this,b=a._ui.overlay;a._setActive(!1),a.isKeyboardSupport&&a.enableDisabledFocusableElements(this._ui.page),b&&b.classList.toggle(s.overlayShown,!1),a._restoreOpenOptions(),a.trigger(v.hide)},x.handleEvent=function(a){var b=this,c=d.router.Router.getInstance();switch(a.type){case"pagebeforehide":c.close(null,{transition:"none",rel:"popup"});break;case"resize":b._onResize(a);break;case"vclick":a.target===b._ui.overlay&&b._onClickOverlay(a);break;case"scroll":b._onScroll(a)}},x._refresh=function(){var a=this;a._setOverlay(a.element,a.options.overlay)},x._onClickOverlay=function(a){var b=this.options;a.preventDefault(),a.stopPropagation(),b.dismissible&&d.router.Router.getInstance().close(null,{rel:"popup"})},x._onResize=function(){this._isOpened()&&this._refresh()},x._transition=function(b,f){var g,h,i,j=this,k=b.transition||j.options.transition||"none",l=k+b.ext,m=j.element,n=m.classList;return j._ui.overlay&&(g=j._ui.overlay.classList),h=e(j,f),"none"!==k?(i=c.bind(null,j,l,h),j._callbacks.animationEnd=i,m.addEventListener("animationend",i,!1),m.addEventListener("webkitAnimationEnd",i,!1),m.addEventListener("mozAnimationEnd",i,!1),m.addEventListener("oAnimationEnd",i,!1),m.addEventListener("msAnimationEnd",i,!1),l.split(" ").forEach(function(a){a=a.trim(),a.length>0&&(n.add(a),g&&g.add(a))})):d.getConfig("noAsync",!1)?h.resolve():a.setTimeout(h.resolve,0),h},x._destroy=function(){var a,b=this,c=b.element,d=b._ui,e=d.wrapper;if(e){for(a=e.firstChild;a;)c.appendChild(a),a=e.firstChild;e.parentNode&&e.parentNode.removeChild(e)}b._unbindEvents(c),b._setOverlay(c,!1),d.wrapper=null},w.prototype=x,d.widget.core.Popup=w,g.defineWidget("Popup",o,["open","close","reposition"],w,"core")}(),function(a,b,c){function d(b,c){var d,e,f,g=b.options,h=g.arrow.split(","),i=b.element,j=a.innerWidth,l=a.innerHeight,m=k.getElementWidth(i,"outer"),n=k.getElementHeight(i,"outer"),o=c.getBoundingClientRect(),p=o.left,q=o.top,r=Math.min(o.width,j-p),s=Math.min(o.height,l-q),t={l:{dir:"l",fixedPositionField:"x",fixedPositionFactor:1,size:m,max:p},r:{dir:"r",fixedPositionField:"x",fixedPositionFactor:-1,size:m,max:j-p-r},b:{dir:"b",fixedPositionField:"y",fixedPositionFactor:-1,size:n,max:q},t:{dir:"t",fixedPositionField:"y",fixedPositionFactor:1,size:n,max:l-q-s}};return d=t[h[0]]||t.t,h.forEach(function(a){var b=t[a],c=b.max;e||(b.size<c?e=b:c>d.max&&(d=b))}),e||(e=d,"x"===e.fixedPositionField?m=e.max:n=e.max),f={x:p+r/2-m/2,y:q+s/2-n/2,w:m,h:n,dir:e.dir},f[e.fixedPositionField]+=("x"===e.fixedPositionField?(m+r)*e.fixedPositionFactor:(n+s)*e.fixedPositionFactor)/2+g.distance*e.fixedPositionFactor,f.x=f.x<0?0:f.x+f.w>j?j-f.w:f.x,f.y=f.y<0?0:f.y+f.h>l?l-f.h:f.y,f}function e(b,c,d,e){var f,g,h,i=b._ui,j=i.wrapper,l=i.arrow,m=b.element,n=l.style,o=a.innerWidth,p=a.innerHeight,q=j.getBoundingClientRect(),r=l.offsetWidth/2,s={"padding-top":0,"padding-bottom":0,"padding-left":0,"padding-right":0,"border-top-width":0,"border-left-width":0,"box-sizing":null},t={"margin-top":0,"margin-bottom":0,"margin-left":0,"margin-right":0,"padding-top":0,"padding-bottom":0,"padding-left":0,"padding-right":0},u={t:{pos:d,min:"left",max:"right",posField:"x",valField:"w",styleField:"left"},b:{pos:d,min:"left",max:"right",posField:"x",valField:"w",styleField:"left"},l:{pos:e,min:"top",max:"bottom",posField:"y",valField:"h",styleField:"top"},r:{pos:e,min:"top",max:"bottom",posField:"y",valField:"h",styleField:"top"}},v=u[c.dir];return k.extractCSSProperties(m,s),k.extractCSSProperties(j,t),h="border-box"===s["box-sizing"],f={t:s["padding-top"]+t["margin-top"]+t["padding-top"],b:s["padding-bottom"]+t["margin-bottom"]+t["padding-bottom"],l:s["padding-left"]+t["margin-left"]+t["padding-left"],r:s["padding-right"]+t["margin-right"]+t["padding-right"]},q={left:f.l+c.x,right:f.l+q.width+c.x,top:f.t+c.y,bottom:q.height+f.t+c.y},q[v.min]>v.pos-r?(g=c[v.posField],g>0?(c[v.posField]=Math.max(v.pos-r,0),v.pos=c[v.posField]+r):v.pos=q[v.min]+r):q[v.max]<v.pos+r&&(g=("w"===v.valField?o:p)-(c[v.posField]+c[v.valField]),g>0?(c[v.posField]+=Math.min(g,v.pos+r-q[v.max]),v.pos=c[v.posField]+c[v.valField]-r):v.pos=q[v.max]-r),n[v.styleField]=v.pos-r-c[v.posField]-(h?s["border-"+v.styleField+"-width"]:0)+"px",c}function f(a,b){var c=b.getBoundingClientRect(),d={};switch(a){case"l":d.x=c.right,d.y=c.top+c.height/2;break;case"r":d.x=c.left,d.y=c.top+c.height/2;break;case"t":d.x=c.left+c.width/2,d.y=c.bottom;break;case"b":d.x=c.left+c.width/2,d.y=c.top}return d}var g=c.widget.core.Popup,h=g.prototype,i=c.engine,j=c.util.object,k=c.util.DOM,l={arrow:"l,b,r,t",positionTo:"window",positionOriginCenter:!1,distance:0,link:null},m=function(){var a,b=this;g.call(b),b.options=j.merge(b.options,l),a=b._ui||{},a.arrow=null,b._ui=a},n="ui-popup",o=j.merge({},g.classes,{context:"ui-ctxpopup",contextOverlay:"ui-ctxpopup-overlay",arrow:"ui-arrow",arrowDir:n+"-arrow-"}),p=j.merge({},g.events,{before_position:"beforeposition"}),q={WINDOW:"window",ORIGIN:"origin",ABSOLUTE:"absolute"},r=new g;m.defaults=j.merge({},g.defaults,l),m.classes=o,m.events=p,m.positionTypes=q,r._build=function(a){var c,d=this,e=d._ui;return h._build.call(d,a),a.classList.add(o.popup),c=b.createElement("div"),c.appendChild(b.createElement("span")),c.classList.add(o.arrow),e.arrow=c,a.appendChild(c),a},r._init=function(a){var b=this,c=b._ui;h._init.call(this,a),c.arrow=c.arrow||a.querySelector("."+o.arrow)},r._layout=function(a){var b=this;this._reposition(),h._layout.call(b,a)},r._reposition=function(a){var b=this,c=b.element,d=b._ui,e=c.classList;a=j.merge({},b.options,a),b.trigger(p.before_position,null,!1),e.add(o.build),b._setContentHeight(),"origin"===a.positionTo&&d.overlay&&d.overlay.classList.add(o.contextOverlay),b._placementCoords(a),e.remove(o.build)},r._placementCoordsWindow=function(a){var b=a.style,c=a.offsetWidth;b.bottom="0px",b.left="50%",b.marginLeft=-(c/2)+"px"},r._placementCoordsAbsolute=function(a,b,c){var d=a.style,e=a.offsetWidth,f=a.offsetHeight;d.top=c+"px",d.left=b+"px",d.marginTop=-(f/2)+"px",d.marginLeft=-(e/2)+"px"},r._findClickedElement=function(a,c){return b.elementFromPoint(a,c)},r._placementCoordsOrigin=function(a,b){var c,g,h,i,j=this,k=j.element,l=k.style,m=k.classList,n=b.x,p=b.y;m.add(o.context),i=k.offsetHeight,c=d(j,a),h=c.dir,m.add(o.arrowDir+h),j._ui.arrow.setAttribute("type",h),("number"!=typeof n&&"number"!=typeof p||j.options.positionOriginCenter)&&(g=f(h,a),n=g.x,p=g.y),c=e(j,c,n,p),i>c.h&&j._setContentHeight(c.h),l.left=c.x+"px",l.top=c.y+"px"},r._placementCoordsElement=function(a){var b,c,e=this,f=e.element,g=f.style;f.classList.add(o.context),c=f.offsetHeight,b=d(e,a),c>b.h&&e._setContentHeight(b.h),g.left=b.x+"px",g.top=b.y+"px"},r._placementCoords=function(a){var c,d,e=this,f=a.positionTo,g=a.x,h=a.y,i=e.element;switch(f){case q.ORIGIN:if(d=a.link,d?"string"==typeof d?c=b.getElementById(d):"object"==typeof d&&(c=d):"number"==typeof g&&"number"==typeof h&&(c=e._findClickedElement(g,h)),c)return void e._placementCoordsOrigin(c,a);break;case q.WINDOW:return void e._placementCoordsWindow(i);case q.ABSOLUTE:if("number"==typeof g&&"number"==typeof h)return void e._placementCoordsAbsolute(i,g,h);break;default:if("string"==typeof f)try{c=b.querySelector(a.positionTo)}catch(j){}else"object"==typeof f&&(c=f);if(c)return void e._placementCoordsElement(c,a)}e._placementCoordsWindow(i)},r._setContentHeight=function(b){var c,d,e,f=this,g=f.element,h=f._ui.content;h&&(c=h.style,(c.height||c.minHeight)&&(c.height="",c.minHeight=""),b=b||a.innerHeight,d=h.offsetHeight,e=g.offsetHeight,e>b&&(d-=e-b,c.height=d+"px",c.minHeight=d+"px"))},r._onHide=function(){var a=this,b=a._ui,c=a.element,d=c.classList,e=b.arrow;d.remove(o.context),["l","r","b","t"].forEach(function(a){d.remove(o.arrowDir+a)}),c&&c.removeAttribute("style"),e&&e.removeAttribute("style"),h._onHide.call(a)},r._destroy=function(){var a=this,b=a._ui,c=b.arrow;h._destroy.call(a),c&&c.parentNode&&c.parentNode.removeChild(c),b.arrow=null},r.reposition=function(a){this._isActive()&&this._reposition(a)},r._refresh=function(){this._isActive()&&(h._refresh.call(this),this.reposition(this.options))},m.prototype=r,c.widget.core.ContextPopup=m,i.defineWidget("Popup","[data-role='popup'], .ui-popup",["open","close","reposition"],m,"core",!0),c.widget.popup=c.widget.Popup}(a,a.document,d),function(a,b){var c=b.widget.BaseWidget,d=b.engine,e=function(){},f={LISTVIEW:"ui-listview",DETAILS:"ui-details"},g=new c;e.classes=f,g._build=function(a){return a.classList.add(f.LISTVIEW),a},e.prototype=g,b.widget.core.Listview=e,d.defineWidget("Listview","[data-role='listview'], .ui-listview",[],e,"core")}(a.document,d),function(a,b){function d(b){var c=null;return(b.children.length>1||1===b.children.length&&!b.firstElementChild.classList.contains(k.BUTTON_CONTENT))&&(c=a.createElement("div"),c.classList.add(k.BUTTON_CONTENT),[].slice.call(b.children).forEach(function(a){c.appendChild(a)}),b.appendChild(c)),c}function e(a,c){b.event.trigger(a.element,"vclick",c)}var f=b.widget.BaseWidget,g=b.widget.core.Page,h=b.widget.core.BaseKeyboardSupport,i=b.engine,j=b.util.DOM,k={BTN:"ui-btn",DISABLED:"ui-state-disabled",INLINE:"ui-inline",BTN_ICON:"ui-btn-icon",ICON_PREFIX:"ui-icon-",BTN_CIRCLE:"ui-btn-circle",BTN_NOBG:"ui-btn-nobg",BTN_ICON_ONLY:"ui-btn-icon-only",BTN_TEXT:"ui-btn-text",BTN_FAB:"ui-btn-fab",BTN_FLAT:"ui-btn-flat",BTN_CONTAINED:"ui-btn-contained",BTN_TEXT_LIGHT:"ui-btn-text-light",BTN_TEXT_DARK:"ui-btn-text-dark",FOCUS:"ui-btn-focus",BTN_ICON_POSITION_PREFIX:"ui-btn-icon-",BTN_ICON_MIDDLE:"ui-btn-icon-middle",BUTTON_CONTENT:"ui-btn-content",HIDDEN:"ui-hidden"},l=32,m=230,n={CIRCLE:"circle",TEXTLIGHT:"light",TEXTDARK:"dark",NOBG:"nobg",ICON_MIDDLE:"icon-middle",FLOATING:"fab",FLAT:"flat",CONTAINED:"contained"},o={inline:!0,icon:null,disabled:!1,style:n.CONTAINED,iconpos:"left",size:null,middle:!1,value:null,enabledIcon:!1},p=function(){var a=this;h.call(a),a.options={},a._ui={fab:null},a._callbacks={onFABClick:null},a._classesPrefix=k.BTN+"-"},q=new f;p.classes=k,p.prototype=q,q._configure=function(){this.options=b.util.object.copy(o)},q._readWidgetSpecyficOptionFromElementClassname=function(a,b){var c=this.options,d=a.classList;switch(b){case"enabledIcon":if(d.contains(k.BTN_ICON))return c.enabledIcon=!0,!0}return!1},q._setStyle=function(a,b){var c=this,d=c.options,e=a.classList,f=!1,g=c._ui;switch(b=b||d.style,b!==n.FLOATING&&null!==g.fab&&c._revertFromFAB(a),e.remove(k.BTN_CIRCLE),e.remove(k.BTN_NOBG),e.remove(k.BTN_TEXT_LIGHT),e.remove(k.BTN_TEXT_DARK),e.remove(k.BTN_FLAT),e.remove(k.BTN_CONTAINED),b){case n.CIRCLE:e.add(k.BTN_CIRCLE),f=!0;break;case n.NOBG:e.add(k.BTN_NOBG),f=!0;break;case n.TEXTLIGHT:e.add(k.BTN_TEXT_LIGHT),f=!0;break;case n.TEXTDARK:e.add(k.BTN_TEXT_DARK),f=!0;break;case n.FLOATING:this._changeToFAB(a),f=!0;break;case n.FLAT:e.add(k.BTN_FLAT),f=!0;break;case n.CONTAINED:e.add(k.BTN_CONTAINED),f=!0}f&&(d.style=b,c._saveOption("style",b))},q._setInline=function(a,b){var d=this.options;b===c&&(b=a.getAttribute("data-inline"),null===b&&(b=this._readCommonOptionFromElementClassname(a,"inline")),b="false"===b?!1:!!b),a.classList.toggle(k.INLINE,b),d.inline=b,this._saveOption("inline",b)},q._setIcon=function(a,b){var c,d=this,e=a.classList,f=d.options,g={},h=d._iconCSSRule;a.className=a.className.replace(RegExp("(\\"+k.ICON_PREFIX+"([a-z-]*))","g"),""),b=b||f.icon,f.icon=b,b&&(f.enabledIcon=!0),d._saveOption("icon",b),f.enabledIcon?(e.add(k.BTN_ICON),b&&(-1===b.indexOf(".")?(e.add(k.ICON_PREFIX+b),d._setTitleForIcon(a),h&&j.removeCSSRule(h)):(c='url("'+b+'")',g["-webkit-mask-image"]=c,g["mask-image"]=c,d._iconCSSRule=j.setStylesForPseudoClass("#"+a.id,"after",g))),a.textContent.trim()||e.remove(k.BTN_TEXT)):(e.remove(k.BTN_ICON),h&&j.removeCSSRule(h))},q._removeIconposClass=function(a){var b=this;a=a||b.element,a.classList.remove(k.BTN_ICON_POSITION_PREFIX+"left"),a.classList.remove(k.BTN_ICON_POSITION_PREFIX+"top"),a.classList.remove(k.BTN_ICON_ONLY)},q._addIconposClass=function(a){var b,c=this;a=a||c.element,b=a.textContent.trim().length||(a.value?a.value.length:0),b>0?a.classList.add(k.BTN_ICON_POSITION_PREFIX+c.options.iconpos):a.classList.add(k.BTN_ICON_ONLY)},q._setIconpos=function(a,b){var c=this,d=c.options,e=d.style;c._removeIconposClass(a),b=b||d.iconpos,d.icon&&e!==n.CIRCLE&&e!==n.NOBG&&e!==n.FLOATING&&(d.iconpos=b,c._addIconposClass(a),c._saveOption("iconpos",b))},q._setTitleForIcon=function(a){var c=this.options,d=a.textContent;"notext"!==c.iconpos||a.getAttribute("title")||(a.setAttribute("title",d),b.warn("iconpos='notext' is deprecated."))},q._focus=function(){var a;b.getConfig("keyboardSupport",!1)&&(a=this.element.classList,a.add(k.FOCUS),this.element.focus())},q._blur=function(){var a;b.getConfig("keyboardSupport",!1)&&(a=this.element.classList,a.remove(k.FOCUS),this.element.blur())},q._setDisabled=function(a,b){var c=this,d=c.options,e=a.classList;b===!0||d.disabled===!0||a.disabled||e.contains(k.DISABLED)?(d.disabled=!0,c._disable(a)):d.disabled=!1,c._saveOption("disabled",d.disabled)},q._build=function(a){var b=this,c=a.classList;return c.contains(k.BTN)||c.add(k.BTN),b._content=d(a),b._setStyle(a),b._setInline(a),b._setIconpos(a),b._setIcon(a),b._setSize(a),b._setDisabled(a),b._setTextButton(a),a.hasAttribute("tabindex")||a.setAttribute("tabindex",0),a},q._refresh=function(){var a=this,b=this.element;return a.options=a._getCreateOptions(b),a._build(b),null},q._getValue=function(){return this.element.textContent},q._setSize=function(a,b){var c=a.style,d=this.options,e=b||d.size;e&&(e=parseInt(e,10),l>e&&(e=l),e>m&&(e=m),c.height=e+"px",c.width=e+"px",d.size=e)},q._setTextButton=function(a){a.textContent.trim()?a.classList.add(k.BTN_TEXT):a.classList.remove(k.BTN_TEXT)},q._setValue=function(a){this.element.textContent=a},q._enable=function(a){var b=this,c=b.options;a&&("button"===a.tagName.toLowerCase()&&(a.disabled=!1),this.isCustomElement||a.removeAttribute("disabled"),a.classList.remove(k.DISABLED),c.disabled=!1,b._saveOption("disabled",!1))},q._bindEvents=function(a){var b=this;b._focusCallback=b._focus.bind(b),b._blurCallback=b._blur.bind(b),a.addEventListener("focus",b._focusCallback),a.addEventListener("blur",b._blurCallback)},q._unbindEvents=function(a){var b=this;a.removeEventListener("focus",b._focusCallback),a.removeEventListener("blur",b._blurCallback)},q._disable=function(a){var b=this.options;a&&("button"===a.tagName.toLowerCase()&&(a.disabled=!0),this.isCustomElement||a.setAttribute("disabled","disabled"),a.classList.add(k.DISABLED),b.disabled=!0,this._saveOption("disabled",!0))},q._saveOption=function(a,b){var c=this,d=c.element,e=o[a];d&&(e!==b?d.dataset[a]=b:delete d.dataset[a])},q._getDefaultOption=function(a){return o[a]},q._bindEventsFAB=function(){var a=this,b=a._ui.fab;a._callbacks.onFABClick=e.bind(null,a),b.addEventListener("vclick",a._callbacks.onFABClick)},q._unbindEventsFAB=function(){var a=this,b=a._ui.fab;b.removeEventListener("vclick",a._callbacks.onFABClick),a._callbacks.onFABClick=null},q._changeToFAB=function(c){var d=this,e=d._ui,f=a.createElement("button"),h=b.util.selectors.getClosestBySelector(c,g.selector);e.fab=f,f.classList.add(k.BTN),f.classList.add(k.BTN_FAB),d.options.icon&&(f.classList.add(k.BTN_ICON),f.classList.add(k.ICON_PREFIX+d.options.icon)),c.classList.add(k.HIDDEN),h&&h.appendChild(f),d._bindEventsFAB()},q._revertFromFAB=function(a){var b=this,c=b._ui.fab;b._unbindEventsFAB(),c&&(c.parentElement.removeChild(c),b._ui.fab=null),a.classList.remove(k.HIDDEN)},b.widget.core.Button=p,p.defaultOptions=o,i.defineWidget("Button","button, [data-role='button'], .ui-btn, input[type='button']",[],p,"core"),i.defineWidget("inputButton","",[],p,"core",!1,!1,HTMLInputElement),i.defineWidget("formButton","",[],p,"core",!1,!1,HTMLButtonElement),h.registerActiveSelector("[data-role='button'], button, [type='button'], [type='submit'], [type='reset'], .ui-button, .ui-btn")}(a.document,d),function(a,b){b.widget.mobile=b.widget.mobile||{}}(a,d),function(a,b,c){var d=c.widget.core.ContextPopup,e=d.prototype,f=c.widget.core.Listview,g=c.engine,h=c.util.DOM,i="[data-role='popup'], .ui-popup",j=c.util.object,k=c.util.selectors,l=function(){var a=this;d.call(this),a.options=j.merge(a.options,l.defaults),a._positionCallback=null};l.classes=d.classes,l.defaults=j.merge({},d.defaults,{closeLinkSelector:"a[data-rel='back']",transition:"pop",directionPriority:["bottom","top","right","left"],arrow:"b,t,r,l",positionTo:"origin"}),l.events=j.merge({},d.events,{AFTER_OPEN:"popupafteropen",AFTER_CLOSE:"popupafterclose"}),l.selector=i,l.prototype=new d,l.prototype._build=function(a){var c,d,f,g=k.getClosestByClass(a,"ui-page")||b.body,h=a.classList,i=this,j=DOMTokenList.prototype;if(a.parentNode!==g&&g.appendChild(a),a=e._build.call(i,a),d=i._ui.content.classList,d.contains("ui-popup-activity")){for(f=[],c=0;c<d.length;c++)-1!==d[c].indexOf("ui-popup-activity")&&f.push(d[c]);for(j.remove.apply(d,f),c=0;c<f.length;c++)h.add(f[c])}return a},l.prototype._setDirectionPriority=function(a,b){b&&(this.options.arrow=b.map(function(a){return a.charAt(0).toLowerCase()}).join(","))},l.prototype._refresh=function(){var a=this;this._isActive()&&("function"==typeof a._positionCallback&&a._positionCallback(),e._refresh.call(this))},l.prototype._setContentHeight=function(){var b=a.innerHeight-h.getCSSProperty(this.element,"margin-top",0,"float");e._setContentHeight.call(this,b)},l.prototype._findClickedElement=function(a,b){var c=e._findClickedElement.call(this,a,b),d=k.getClosestBySelector(c,g.getWidgetDefinition("Button").selector);return d||c},l.prototype._show=function(){var a,b,c=this;"window"!==c.options.positionTo&&(a=c.element.querySelector("."+f.classes.LISTVIEW),a&&(b=g.getBinding(a),b&&b.option("coloredBackground",!1))),e._show.call(c)},l.prototype._onShow=function(){e._onShow.call(this),this.trigger(l.events.AFTER_OPEN)},l.prototype._onHide=function(){e._onHide.call(this),this.trigger(l.events.AFTER_CLOSE)},l.prototype.setPositionCallback=function(a){this._positionCallback=a},c.widget.mobile.Popup=l,g.defineWidget("Popup",i,["open","close","reposition","setPositionCallback","setPositionCB"],l,"mobile",!0)}(a,a.document,d),function(a,b,c){var d=c.widget.core.Scrollview;c.widget.mobile.Scrollview=d,c.engine.defineWidget("Scrollview",".ui-content:not([data-scroll='none']):not([data-handler='true']):not(.ui-scrollview-clip):not(.ui-scrolllistview):not(.ui-scrollhandler), [data-scroll]:not([data-scroll='none']):not([data-handler='true']):not(.ui-scrollhandler), .ui-scrollview:not([data-scroll='none']):not([data-handler='true']):not(.ui-scrollhandler)",["scrollTo","ensureElementIsVisible","centerToElement","getScrollPosition","skipDragging","translateTo"],d,"tizen",!0)}(a,a.document,d),function(a,b){var c=function(){this.options={}},d=b.widget.BaseWidget,e=d.prototype,f=e.configure,g=e.disable,h=e.enable,i=new d,j=[].slice;c.classes=d.classes,i.configure=function(a,c,d){var e,g,h=this;return c=f.call(h,a,c,d),a&&(e=a.name,g=e&&e.toLowerCase(),h.widgetName=g,h.widgetBaseClass=h.namespace+"-"+g,h.uuid=b.getNumberUniqueId(),
+h.eventNamespace="."+g+(h.uuid||""),h.defaultElement="<div>"),c},i.disable=function(){var a=this,b=a.element,c=b.classList,d=j.call(arguments);g.apply(a,d),c.add(a.widgetFullName+"-disabled")},i.enable=function(){var a=this,b=a.element,c=b.classList,d=j.call(arguments);h.apply(a,d),c.remove(a.widgetFullName+"-disabled")},i.raise=function(a){throw"Widget ["+this.widgetName+"]: "+a},i.widget=function(){return this.element},c.prototype=i,b.widget.mobile.BaseWidgetMobile=c}(a.document,d),function(a,b){function c(a,b,c){var d,e,f=a._ui,g=b.classList,h=f.heading,j=f.expandableContent,l="collapse"===c.type;c.defaultPrevented||(c.preventDefault(),f.expandFrom?l?f.expandFrom.classList.remove(k.uiExpandableExpanded):f.expandFrom.classList.add(k.uiExpandableExpanded):(d=h.classList,e=j.classList,l?(g.add(k.uiExpandableCollapsed),d.add(k.uiExpandableHeadingCollapsed),e.add(k.uiExpandableContentCollapsed)):(g.remove(k.uiExpandableCollapsed),d.remove(k.uiExpandableHeadingCollapsed),e.remove(k.uiExpandableContentCollapsed)),j.setAttribute("aria-hidden",l)),i.trigger(b,l?"collapsed":"expanded"))}function d(a,b){var c,d=a._ui.heading;d&&(c=a._ui.heading.classList,b?c.add(k.uiExpandableHeadingActive):c.remove(k.uiExpandableHeadingActive))}function e(a,b){var c,d=a.element,e=a._ui,f=e.heading,g=e.expandFrom;f?c=f.classList.contains(k.uiExpandableHeadingCollapsed)?"expand":"collapse":g&&(c=g.classList.contains(k.uiExpandableExpanded)?"collapse":"expand"),i.trigger(d,c),b.preventDefault(),i.stopPropagation(b)}var f=b.widget.mobile.BaseWidgetMobile,g=b.engine,h=b.util.selectors,i=b.event,j=b.util.DOM,k={uiExpandable:"ui-expandable",uiExpandableContent:"ui-expandable-content",uiExpandableContentCollapsed:"ui-expandable-content-collapsed",uiExpandableCollapsed:"ui-expandable-collapsed",uiExpandableExpanded:"ui-expandable-expanded",uiExpandableHeading:"ui-expandable-heading",uiExpandableHeadingCollapsed:"ui-expandable-heading-collapsed",uiExpandableHeadingToggle:"ui-expandable-heading-toggle",uiExpandableHeadingActive:"ui-expandable-heading-active",expandButton:"ui-expand-button",expandFrom:"ui-expandable-from",expandTo:"ui-expandable-to"},l={HEADING:"h1,h2,h3,h4,h5,h6,legend,li",BUTTON:"."+k.expandButton},m=function(){var a=this;a.options={collapsed:!0,heading:l.HEADING,expander:"heading"},a._eventHandlers={},a._ui={heading:null,expandableHeadingContent:null,expandButton:null,expandFrom:null,expandTo:null}},n=new f;m.prototype=n,m.classes=k,m.selectors=l,n._getExpandableHeading=function(b){var c,d=this.options,e=h.getChildrenBySelector(b,d.heading)[0];return e||(e=a.createElement("h1"),b.appendChild(e)),"legend"===e.tagName.toLowerCase()&&(c=a.createElement("div"),c.setAttribute("role","heading"),c.innerHTML=e.innerHTML,b.replaceChild(c,e),e=c),e},n._getExpandableContent=function(a,b){var c=a.querySelector("."+k.uiExpandableContent);return c||(j.wrapInHTML(a.childNodes,"<div class='"+k.uiExpandableContent+"'></div>"),a.insertBefore(b,a.firstChild),j.wrapInHTML(b.childNodes,"<a class='"+k.uiExpandableHeadingToggle+"' tabindex='0'></a>"),c=b.nextElementSibling),c},n._createExpandTo=function(b){var c=b.parentElement.querySelector("."+k.expandTo);return c||(c=a.createElement("li"),c.classList.add(k.expandTo),c.setAttribute("data-expander","button"),b.parentElement.appendChild(c)),c},n._createExpandButton=function(b){var c=b.querySelector(l.BUTTON);return c||(c=a.createElement("a"),c.classList.add("ui-btn"),b.appendChild(c),c.setAttribute("href","#")),c.setAttribute("data-icon","down"),c.setAttribute("data-style","flat"),c.classList.add(k.expandButton),c},n._build=function(a){var c,d,e=this,f=e._ui,g=a.classList;return a.classList.contains(k.expandFrom)?(f.expandFrom=a,f.expandTo=e._createExpandTo(a),f.expandButton=a.querySelector(l.BUTTON)||f.expandTo.querySelector(l.BUTTON),f.expandButton||(f.expandButton=e._createExpandButton(f.expandTo))):(a.parentNode&&"ul"===a.parentNode.tagName.toLowerCase()&&"div"===a.tagName.toLowerCase()&&b.warn("Don't make the Expandable list using <div>. It violates standard of HTML rule. Instead of, please use <li>."),g.add(k.uiExpandable),c=e._getExpandableHeading(a),c.classList.add(k.uiExpandableHeading),d=e._getExpandableContent(a,c),f.heading=c,f.expandableContent=d),a},n._init=function(a){var c=this,d=c._ui;return d.heading=d.heading||h.getChildrenByClass(a,k.uiExpandableHeading)[0],d.expandableContent=d.expandableContent||a.querySelector("."+k.uiExpandableContent),d.expandTo?(d.expandButton=d.expandButton||d.expandTo.querySelector(l.BUTTON),b.widget.Button(d.expandButton),c.options.collapsed&&a.classList.remove(k.uiExpandableExpanded)):(d.expandButton=d.expandButton||a.querySelector(l.BUTTON),c.options.collapsed&&(a.classList.add(k.uiExpandableCollapsed),d.heading&&d.heading.classList.add(k.uiExpandableHeadingCollapsed),d.expandableContent&&d.expandableContent.classList.add(k.uiExpandableContentCollapsed))),a},n._bindEvents=function(a){var b=this,f=b._eventHandlers,g=b._ui,h=g.heading;f.toggleExpandable=c.bind(null,b,a),f.removeActiveClass=d.bind(null,b,!1),f.addActiveClass=d.bind(null,b,!0),f.toggleEventType=e.bind(null,b),i.on(a,"expand collapse",f.toggleExpandable,!1),h?(i.on(h,"vmousedown",f.addActiveClass,!1),i.on(h,"vmousemove vmousecancel vmouseup",f.removeActiveClass,!1),i.on(h,"vclick",f.toggleEventType,!1)):g.expandTo&&i.on(g.expandButton,"vclick",f.toggleEventType,!1)},n._refresh=function(){},n._destroy=function(){var b=this,c=b.element,d=b._ui,e=d.heading,f=b._eventHandlers,g=c.parentNode;i.off(c,"expand collapse",f.toggleExpandable,!1),e?(i.off(e,"vmousedown",f.addActiveClass,!1),i.off(e,"vmousemove vmousecancel vmouseup",f.removeActiveClass,!1),i.off(e,"vclick",f.toggleEventType,!1)):d.expandTo&&i.off(d.expandButton,"vclick",f.toggleEventType,!1),b._ui=null,b._eventHandlers=null,i.trigger(a,"destroyed",{widget:"Expandable",parent:g})},b.widget.mobile.Expandable=m,g.defineWidget("Expandable","[data-role='expandable'], .ui-expandable, .ui-expandable-from",[],m,"mobile")}(a.document,d),function(a,b,c){function d(b){b._topOffset=a.innerHeight,b._previousVisibleElement=null,b._canvasWidth=0,b._canvasHeight=0,b._dragMode=!1,b.originalListPosition=0,b.indexDraggingElement=0,b._ui={helper:{},holder:{}},b._snapshotItems=[],b._liElements=[],b.topValue=0,b.isScrolling=null,b._reorderElements=[]}function e(a,b){return a[0]+=b[0],a[1]+=b[1],a[2]+=b[2],a[3]+=b[3],a[0]=A(B(0,a[0]),255),a[1]=A(B(0,a[1]),255),a[2]=A(B(0,a[2]),255),a[3]=A(B(0,a[3]),1),a[3]}function f(a,b){b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3]}function g(a){var b=parseFloat(a);return b===b?b:0}function h(a){var b=w.getClosestByTag(a,"li");b&&(a.checked?b.classList.add(M.ITEM_SELECTED):b.classList.remove(M.ITEM_SELECTED))}function i(a){var b=a.target;"INPUT"===b.tagName&&"checkbox"===b.type&&h(b)}function j(a,b){return C(a?a.getBoundingClientRect().top-b.top:b.height)}function k(a){for(var b=a.shift();b;){if(b.offsetHeight)return b;b=a.shift()}return null}function l(a){var b=a.getBoundingClientRect();return{top:b.top,height:b.height,left:b.left,width:b.width}}function m(a,b){a.fillStyle="rgba("+H[0]+","+H[1]+","+H[2]+","+H[3]+")",a.fillRect(b.left,b.top,b.width,b.height)}function n(a,b,c,d){return a.height+=b,a.left-=c,a.top=d,a}var o=c.widget.core.Page,p=c.widget.mobile.Popup,q=c.widget.mobile.Scrollview,r=c.widget.core.Listview,s=r.prototype,t=c.widget.core.BaseKeyboardSupport,u=c.util,v=u.object,w=u.selectors,x=c.event,y=Date.now,z=new RegExp("[^0-9-.:,]+","gi"),A=Math.min,B=Math.max,C=Math.round,D=Math.ceil,E=[].slice,F=c.event,G=u.isNumber,H=[0,0,0,0],I=3e3,J={PREV:-1,HOLD:0,NEXT:1},K=function(){var a=this,b={coloredBackground:!1,colorRestOfTheScreenBellow:!0,colorRestOfTheScreenAbove:!0,firstColorStep:0,lastColorStep:0,multipleSelection:!1};r.call(a),t.call(a),a.options=a.options?v.fastMerge(a.options,b):b,a._async=u.requestAnimationFrame,a._context=null,a._canvasStyle=null,a._scrollableContainer=null,a._pageContainer=null,a._popupContainer=null,a._drawCallback=null,a._scrollCallback=null,a._backgroundRenderCallback=null,a._running=!1,a._redraw=!1,a._colorBase=[250,250,250,1],a._colorStep=[0,0,0,-.04],a._lastChange=0,a._siblingListsBellow=[],a._siblingListsAbove=[],d(a)},L="[data-role='listview'], .ui-listview",M={BACKGROUND_LAYER:"ui-listview-background",GRADIENT_BACKGROUND_DISABLED:"ui-listview-background-disabled",GROUP_INDEX:"ui-group-index",POPUP_LISTVIEW:"ui-popup-listview",DRAG_ACTIVE:"ui-drag-active",EXPANDABLE:"ui-expandable",ITEM:"ui-listview-item",ITEM_ACTIVE:"ui-listview-item-active",ITEM_SELECTED:"ui-li-selected",HELPER:"ui-listview-helper",HOLDER:"ui-listview-holder",SNAPSHOT:"ui-snapshot",HANDLER:"ui-listview-handler",DRAG_MODE:"ui-drag-mode",ACTIVATE_HANDLERS:"ui-activate-handlers",CANCEL_ANIMATION:"ui-cancel-animation",DEACTIVATE_HANDLERS:"ui-deactivate-handlers",FOCUS:"ui-listview-focus",ITEMFOCUS:"ui-listview-item-focus"},N={BACKGROUND_RENDER:"event-listview-background-render",REORDER:"listviewreorder"},O=c.engine,P=new r;K.classes=v.fastMerge(M,r.classes),K.events=N,P._setMultipleSelection=function(a,b){b?a.addEventListener("change",i,!0):a.removeEventListener("change",i,!0),this.options.multipleSelection=b},P._setFirstColorStep=function(a,b){return b=parseInt(b,10),this.options.firstColorStep=b,!0},P._setColoredBackground=function(a,b){a.classList.toggle(M.GRADIENT_BACKGROUND_DISABLED,!b),this.options.coloredBackground=b},P._addCanvas=function(a){var c=b.createElement("canvas"),d=c.getContext("2d");return c.classList.add(M.BACKGROUND_LAYER),a.insertBefore(c,a.firstElementChild),this._context=d,c},P._build=function(a){var b=this,c=s._build.call(b,a),d=a&&w.getClosestByClass(a.parentElement,"ui-listview");return b._isChildListview=d,d||b._addCanvas(c),c},P._getCanvas=function(){var a,b=this;return b._context&&(a=b._context.canvas),a&&a.parentElement||(a=b.element.querySelector("."+M.BACKGROUND_LAYER),a||(a=b._addCanvas(b.element)),b._context=a.getContext("2d")),a},P._prepareColors=function(){var b,c,d,e,h,i=this,j=i._getCanvas();j&&(b=a.getComputedStyle(j,":before"),c=b.getPropertyValue("content"),c.length>0&&(c=c.replace(z,""),h=c.split("::"),2===h.length&&(d=h[0].split(",").filter(G).map(g),e=h[1].split(",").filter(G).map(g),d.length>0&&f(d,i._colorBase),e.length>0&&f(e,i._colorStep))))},P._refreshBackgroundCanvas=function(b,c){var d,e,f,g,h=this,i=h._getCanvas();i&&(d=i.style,e=c.getBoundingClientRect(),f=0,g=e.width,b&&(f=b.getBoundingClientRect().height),f=Math.max(e.height,f)+h._topOffset,f=Math.min(f,4*a.innerHeight),h._canvasHeight=f,h._canvasWidth=g,i.setAttribute("width",g),i.setAttribute("height",f),d.width=g+"px",d.height=f+"px")},P._findContainers=function(a){var b=this;b._pageContainer=w.getClosestByClass(a,o.classes.uiPage),b._popupContainer=w.getClosestByClass(a,p.classes.popup),b._scrollableContainer=w.getClosestByClass(a,q.classes.clip)||w.getClosestByTag(a,"section")},P._checkClosestPopup=function(){var a,b=this,c=b._popupContainer;c&&(c.classList.add(M.POPUP_LISTVIEW),a=c.querySelector("."+p.classes.content),a&&(b._scrollableContainer=a))},P._refreshColoredBackground=function(){var a,b=this,c=b.element;b._checkClosestPopup(),b._redraw=!0,b._lastChange=Date.now(),b._previousVisibleElement=null,b._prepareColors(),b._refreshBackgroundCanvas(b._scrollableContainer,c),a=b._getCanvas(),a&&(c.firstElementChild&&"canvas"!==c.firstElementChild.tagName.toLowerCase()?c.insertBefore(a,c.firstElementChild):c.firstElementChild instanceof HTMLElement||c.appendChild(a),"function"==typeof b._frameCallback&&b._frameCallback())},P._refresh=function(){var a=this,b=a.element,c=w.getClosestByClass(b,p.classes.popup);a._findContainers(b),a.options.coloredBackground?a._refreshColoredBackground():c&&(c.classList.remove(M.POPUP_LISTVIEW),a._popupContainer=c)},P._init=function(a){var b,c,d,e=this,f=e._context,g=!1;e.options.firstColorStep=parseInt(e.options.firstColorStep,10),e._isChildListview||(f?b=f.canvas:(b=a.querySelector("."+M.BACKGROUND_LAYER),b&&(f=b.getContext("2d"))),f&&(e._canvasStyle=b.style,e._frameCallback=e._handleFrame.bind(e),e.refresh())),c=[].slice.call(e.element.parentElement.querySelectorAll(L)),d=[].slice.call(e.element.querySelectorAll(L)),e._siblingListsBellow=c.filter(function(a){return d.indexOf(a)>-1?!1:g?!0:(g=a===e.element,!1)}),g=!1,e._siblingListsAbove=c.filter(function(a){return d.indexOf(a)>-1?!1:g||a===e.element?(g=!0,!1):!0}),e._siblingListsBellow.length>0&&(e.options.colorRestOfTheScreenBellow=!1),e._siblingListsAbove.length>0&&(e.options.colorRestOfTheScreenAbove=!1),e._setMultipleSelection(e.element,e.options.multipleSelection)},P._handleScroll=function(){var a=this;a._lastChange=y(),a._running||(a._running=!0,a._async(a._frameCallback))},P._handleTouchStart=function(a){var b=this,c=b._scrollableContainer;b._dragMode&&a.srcElement.classList.contains(M.HANDLER)&&x.off(c,"scroll",b._reorderCallback)},P._handleTouchEnd=function(a){var b=this,c=b._scrollableContainer;b._dragMode&&a.srcElement.classList.contains(M.HANDLER)&&x.on(c,"scroll",b._reorderCallback)},P._handleReorderScroll=function(){x.trigger(this.element,N.REORDER)},P._backgroundRender=function(){this.refresh()},P._selectAll=function(a){var b=[].slice.call(this.element.querySelectorAll("input[type='checkbox']"));b.forEach(function(b){var c=a.detail.checked;b.checked=c,c?b.setAttribute("checked","checked"):b.removeAttribute("checked"),h(b)})},P._handleFrame=function(){var a,b,c,d,e=this,f=e.element,g=E.call(f.querySelectorAll("li")),h=e._scrollableContainer,i=h?h.scrollTop:0,m=null,n=0,o=f.getBoundingClientRect().top,p=e._previousVisibleElement,q=e._topOffset,r=k(g);for(h&&(m=h.getBoundingClientRect(),n=m.top),m&&n>o&&0!==e.options.firstColorStep&&(e.options.firstColorStep=0,e._redraw=!0);r;)b=l(r),c=b.top-o,a=k(g),d=j(a,b),c+d-(n-o-i)>=i?(r!==p&&e._context&&(e._previousVisibleElement=r,e._context.canvas.style.transform="translateY("+(c-q)+"px)",e._redraw=!0),r=null):r=a;e._redraw&&e._context&&e._handleDraw(),e._running&&e._context&&e._async(e._frameCallback),y()-e._lastChange>=I&&(e._running=!1)},P._prepareCanvas=function(){var a,b=this;for(f(b._colorBase,H),a=0;a<b.options.firstColorStep;a++)e(H,b._colorStep);b.options.lastColorStep=b.options.firstColorStep,b._context.clearRect(0,0,b._canvasWidth,b._canvasHeight)},P._drawLiElements=function(){var a,b,c,d=this,f=d.element,g=E.call(f.querySelectorAll("li")),h=g[0],i=k(g),o=d._context,p=d._colorStep,q=f.getBoundingClientRect(),r=q.left,s=d._scrollableContainer,t=s?s.getBoundingClientRect().top:0,u=null,v=0,w=d._topOffset,x=[],y=null,z=null,A=!1;for(h&&(a=h.getBoundingClientRect(),a.top+a.height>=t&&(A=!0));i;)c=!i.classList.contains(M.GROUP_INDEX)&&!i.classList.contains(M.EXPANDABLE),u=l(i),b=k(g),u.height=j(b,u),!c&&b&&(b.classList.contains(M.GROUP_INDEX)||b.classList.contains(M.EXPANDABLE))&&(c=!0),D(u.top+u.height)>=t&&(u=n(u,w,r,v),w=0,x.push({rectangle:u,changeColor:c}),v+=u.height),i=b;return y=x[0],y&&(z=y.rectangle,(!d.options.colorRestOfTheScreenAbove||A)&&(d._context.clearRect(z.left,z.top,z.width,z.height),z.top+=d._topOffset,z.height-=d._topOffset)),x.forEach(function(a){m(o,a.rectangle),a.changeColor&&(e(H,p),d.options.lastColorStep++)}),u},P._drawEndOfList=function(a,b){var c;null!==a&&(c=b.canvas.getBoundingClientRect(),a.height+a.top<c.height&&(a.top+=a.height,a.height=c.height-a.top,m(b,a)))},P._handleDraw=function(){var a,b,d=this;d._prepareCanvas(),a=d._drawLiElements(),d.options.colorRestOfTheScreenBellow&&d._drawEndOfList(a,d._context),d._siblingListsBellow.forEach(function(a){b=c.engine.getBinding(a),b&&b.option("firstColorStep",d.options.lastColorStep)}),d._redraw=!1},P._focusItem=function(a){var b=a.detail.element,d=w.getClosestByTag(b,"li");c.getConfig("keyboardSupport")&&"A"===b.tagName&&d.classList.add(M.ITEMFOCUS)},P._blurItem=function(a){var b=a.detail.element,d=w.getClosestByTag(b,"li");c.getConfig("keyboardSupport")&&"A"===b.tagName&&d.classList.remove(M.ITEMFOCUS)},P._focus=function(a){c.getConfig("keyboardSupport")&&a.classList.add(M.FOCUS)},P._blur=function(a){c.getConfig("keyboardSupport")&&a.classList.remove(M.FOCUS)},P._bindEvents=function(){var b=this,c=b._scrollableContainer,d=b._pageContainer,e=b._popupContainer;b._bindEventMouse(),b._isChildListview||(c&&(b._scrollableContainer=c,b._scrollCallback=b._handleScroll.bind(b),b._reorderCallback=b._handleReorderScroll.bind(b),b._touchStartCallback=b._handleTouchStart.bind(b),b._touchEndCallback=b._handleTouchEnd.bind(b),x.on(c,"touchstart",b._scrollCallback),x.on(c,"touchmove",b._scrollCallback),x.on(c,"touchstart",b._touchStartCallback),x.on(c,"touchend",b._touchEndCallback),x.on(c,"scroll",b._scrollCallback)),b._backgroundRenderCallback=b._backgroundRender.bind(b),b._selectAllCallback=b._selectAll.bind(b),b.on("expand collapse",b._backgroundRenderCallback,!1),x.on(a,"resize",b._backgroundRenderCallback,!1),d&&(x.on(d,o.events.BEFORE_SHOW,b._backgroundRenderCallback),x.on(d,"select-all",b._selectAllCallback,!0)),e&&x.on(e,p.events.transition_start,b._backgroundRenderCallback),F.on(b.element,"animationend webkitAnimationEnd",b,!0),F.on(b.element,"taufocus",b._focusItem,!0),F.on(b.element,"taublur",b._blurItem,!0))},P._destroy=function(b){var c=this;b&&(F.off(b,"animationend webkitAnimationEnd",c,!0),F.off(b,"focus",c._focus,!0),F.off(b,"blur",c._blur,!0)),c._context&&(c._context.canvas.parentElement&&c._context.canvas.parentElement.removeChild(c._context.canvas),c._context=null),c._scrollCallback&&(c._scrollableContainer&&(x.off(c._scrollableContainer,"touchstart",c._scrollCallback),x.off(c._scrollableContainer,"touchmove",c._scrollCallback),x.off(c._scrollableContainer,"scroll",c._scrollCallback),x.off(c._scrollableContainer,"touchstart",this._touchStartCallback),x.off(c._scrollableContainer,"touchend",this._touchEndCallback),c._scrollableContainer=null),c._scrollCallback=null),c._backgroundRenderCallback&&(c.off("expand collapse",c._backgroundRenderCallback,!1),x.off(a,"resize",c._backgroundRenderCallback,!1),b&&x.off(b,N.BACKGROUND_RENDER,c._backgroundRenderCallback),c._pageContainer&&(x.off(c._pageContainer,o.events.BEFORE_SHOW,c._backgroundRenderCallback),x.off(c._pageContainer,"select-all",c._selectAllCallback,!0),c._pageContainer=null),c._popupContainer&&(c._popupContainer.classList.remove(M.POPUP_LISTVIEW),x.off(c._popupContainer,p.events.transition_start,c._backgroundRenderCallback),c._popupContainer=null),c._backgroundRenderCallback=null)},P._createHolder=function(){var a=b.createElement("li"),c=a.classList;return c.add(M.ITEM),c.add(M.HOLDER),a},P._setDirection=function(a,b){var c=this;b>a?c._direction=J.PREV:a===b?c._direction=J.HOLD:c._direction=J.NEXT},P._changeLocationDown=function(a,b,c,d){var e,f=1,g=this,h=g.element;for(a+=c.height;d>f;f++)e=h.children[f],c.element!==e&&b!==e&&a>g._snapshotItems[f-1]+70*e.offsetHeight/100&&g._snapshotItems[f-1]>b.offsetTop+15&&(g._snapshotItems[f-1]=g._snapshotItems[f-2]+e.offsetHeight,g._appendLiStylesToElement(e,g._snapshotItems[f-2]),g._appendLiStylesToElement(b,g._snapshotItems[f-1]),h.insertBefore(b,h.children[f].nextSibling))},P._changeLocationUp=function(a,b,c,d){for(var e,f=this,g=d-1,h=f.element;g>0;g--)e=h.children[g],c.element!==e&&b!==e&&a<f._snapshotItems[g-1]+30*e.offsetHeight/100&&f._snapshotItems[g-1]+e.offsetHeight<b.offsetTop+b.offsetHeight-15&&(f._snapshotItems[g]=f._snapshotItems[g-1]+b.offsetHeight,h.insertBefore(b,h.children[g]),f._appendLiStylesToElement(b,f._snapshotItems[g-1]),f._appendLiStylesToElement(e,f._snapshotItems[g]))},P._prepare=function(){var a=this,b=a.element,c=b.parentElement;b.classList.contains(M.SNAPSHOT)||(a._recalculateTop(),a.originalListPosition=c.getBoundingClientRect().top-55,a._styleHeightBackup=b.style.height,b.style.height=b.getBoundingClientRect().height+"px",b.classList.add(M.SNAPSHOT),c.scrollTop=-a.originalListPosition)},P._start=function(b){var c,d,e=this,f=e.element,g=e._ui.helper,h=b.detail.srcEvent.srcElement.parentElement,i=a.getComputedStyle(h,null),j=h.style;c=parseInt(i.getPropertyValue("top"),10),h.classList.add(M.HELPER),d=e._createHolder(),d.style.height=parseFloat(i.getPropertyValue("height"))+"px",d.style.top=h.style.top,f.insertBefore(d,h),f.appendChild(h),e._appendLiStylesToElement(h,c),g.element=h,g.style=j,g.height=parseFloat(i.getPropertyValue("height"))||0,g.startY=b.detail.estimatedY-55-g.height/2,g.position={startTop:c,moveTop:g.startY,startIndex:[].indexOf.call(f.children,d)},e._ui.holder=d,g.element=h,e._ui.helper=g,e.topValue=b.detail.estimatedY,g.move=0},P._move=function(a){var c,d,e=this,f=e._ui,g=f.helper,h=f.holder,i=e.element,j=g.position,k=g.element,l=i.childElementCount-1,m=b.querySelector(".ui-page-active .ui-header");d=m?m.offsetHeight:0,c=a.detail.estimatedY-d-g.height/2+-e.originalListPosition,e._appendLiStylesToElement(k,c),e._setDirection(c,j.moveTop),k.classList.add("ui-listview-item-moved"),j.moveTop=c,e._direction>0?e._changeLocationDown(c,h,g,l):e._direction<0&&e._changeLocationUp(c,h,g,l)},P._end=function(){var a=this,b=a.element,c=a._ui.helper,d=a._ui.holder,e=c.element;e.classList.remove("ui-listview-item-moved"),e.classList.remove(M.HELPER),a._appendLiStylesToElement(e,d.offsetTop),b.insertBefore(e,d),b.removeChild(d),a._ui.helper={},a._removeTopOffsets(),b.classList.remove(M.SNAPSHOT),b.style.height=a._styleHeightBackup,b.parentElement.parentElement.scrollTop=-a.originalListPosition,a._liElements=E.call(b.querySelectorAll("li")),a.trigger("scroll")},P._click=function(){var a=this,b=a.element;a._removeTopOffsets(),b.classList.remove(M.SNAPSHOT),b.style.height=a._styleHeightBackup,b.parentElement.parentElement.scrollTop=-a.originalListPosition},P._animationEnd=function(a){var b=this,c=a.target.parentElement.parentElement,d=c.classList;d.contains(M.ACTIVATE_HANDLERS)?(d.remove(M.ACTIVATE_HANDLERS),d.add(M.CANCEL_ANIMATION)):d.contains(M.DEACTIVATE_HANDLERS)&&(b._removeHandlers(),d.remove(M.DEACTIVATE_HANDLERS),d.remove(M.DRAG_MODE)),a.stopImmediatePropagation(),a.preventDefault()},P.handleEvent=function(a){var b=this,c=a.detail&&a.detail.srcEvent&&a.detail.srcEvent.srcElement||a.srcElement;if(c.classList.contains(M.HANDLER))switch(a.type){case"click":b._click(a),a.preventDefault();break;case"dragprepare":b._prepare(a);break;case"dragstart":b._start(a),a.preventDefault();break;case"drag":b._move(a);break;case"dragend":b._end(a);break;case"animationend":case"webkitAnimationEnd":b._animationEnd(a)}},P._appendHandlers=function(){for(var a,c,d=0,e=this,f=e._liElements,g=f.length;g>d;d++)c=f[d],a=b.createElement("div"),a.classList.add(M.HANDLER),a.classList.add("ui-icon-reorder"),a.classList.add("ui-icon"),c.appendChild(a)},P._removeHandlers=function(){for(var a,b,c=0,d=this,e=d._liElements,f=e.length;f>c;c++)b=e[c],a=b.querySelector("."+M.HANDLER),b.removeChild(a)},P._recalculateTop=function(){for(var a,b,c=0,d=this,e=d._liElements,f=e.length;f>c;c++)b=e[c],a=b.offsetTop,d._snapshotItems.push(a),d._appendLiStylesToElement(e[c],d._snapshotItems[c])},P._removeTopOffsets=function(){for(var a=0,b=this,c=b._liElements,d=c.length;d>a;a++)c[a].style.top=""},P._appendLiStylesToElement=function(a,b){a.style.top=b+"px"},P.toggleDragMode=function(){var a=this,b=a.element,c=a._scrollableContainer;a._dragMode=!a._dragMode,a._dragMode?(b.classList.add(M.DRAG_MODE),a._liElements=E.call(b.querySelectorAll("li")),a._appendHandlers(),b.classList.add(M.ACTIVATE_HANDLERS),F.on(b,"click drag dragstart dragend dragcancel dragprepare",a,!0),x.on(c,"scroll",a._reorderCallback),a.trigger("scroll"),F.enableGesture(b,new F.gesture.Drag({blockVertical:!1}))):(b.classList.remove(M.CANCEL_ANIMATION),b.classList.add(M.DEACTIVATE_HANDLERS),F.off(b,"click drag dragstart dragend dragcancel dragprepare",a,!0),F.disableGesture(b))},K.prototype=P,c.widget.mobile.Listview=K,O.defineWidget("Listview",L,[],K,"mobile",!0,!0,HTMLUListElement)}(a,a.document,d),function(b,d){var e=0,f=+new Date,g=[].slice,h="",i="",j=function(a){var b=new Date;a.unshift("["+h+"]["+b.toLocaleString()+"]")},k=a.ns||a.tau||{},l=a.nsConfig||a.tauConfig||{},m=function(a){this.message=a};k.info=k.info||{profile:"custom"},k.tauPerf=k.tauPerf||{},a.ns=k,a.nsConfig=l,a.tau=k,a.tauConfig=l,h=l.rootNamespace,i=l.fileName,m.prototype.toString=function(){return this.message},k.getUniqueId=function(){return h+"-"+k.getNumberUniqueId()+"-"+f},k.getNumberUniqueId=function(){return e++},k.log=function(){var a=g.call(arguments);j(a),d&&d.log.apply(d,a)},k.warn=function(){var a=g.call(arguments);j(a),d&&d.warn.apply(d,a)},k.error=function(){var a=g.call(arguments);j(a),d&&d.error.apply(d,a)},k.getConfig=function(a,b){return l[a]===c?b:l[a]},k.setConfig=function(a,b,d){d&&l[a]!==c||(l[a]=b)},k.getFrameworkPath=function(){var a,c,d,e,f=b.getElementsByTagName("script"),g=f.length;for(a=0;g>a;a++)if(c=f[a].src,d=c.split("/"),e=d.length,d[e-1]===i+".js"||d[e-1]===i+".min.js")return d.slice(0,e-1).join("/");return null},k._TAUException=m,k["throws"]=function(a){throw"string"!=typeof a&&k["throws"]("Wrong parameter type. Message must be a string!"),new k._TAUException(a)}}(a.document,a.console),function(a,b,c){function d(a,b){var c,d=new XMLHttpRequest;return d.open("get",a,!1),b&&d.overrideMimeType(b),d.send(),4===d.readyState&&(c=d.status,200===c||0===c&&d.responseText)?d.responseText:null}function e(a){for(var b,c=m.call(a.querySelectorAll("script[src]")),d=c.length;--d>=0;)b=c[d],b.parentNode.removeChild(b);return c}function f(b){return function(){try{a.eval(b)}catch(d){d.stack?c.error(d.stack):d.name&&d.message?c.error(d.name,d.message):c.error(d)}}}function g(a){var b,c=a.length;for(b=0;c>b;++b)a[b]()}function h(a,c){var d,e,f,g,h=[];for(f=0,g=a.length;g>f;++f)e=k.fetchSync(a[f].src,"text/plain"),e&&(d=b.adoptNode(a[f]),d.setAttribute("data-src",a[f].src),d.removeAttribute("src"),h.push(k.safeEvalWrap(e)),c&&c.appendChild(d));return h}function i(a){var c,d=[];return m.call(a.querySelectorAll("script:not([data-src]):not([type]):not([id]):not([src])")).forEach(function(a){c=b.createElement("script"),c.innerText=a.textContent,m.call(a.attributes).forEach(function(b){c.setAttribute(b.name,a.getAttribute(b.name))}),a.parentNode.removeChild(a),d.push(c)}),d}var j=null,k=c.util||{},l=[],m=[].slice,n=!1;k._requestAnimationFrameOnSetTimeout=function(b){"function"!=typeof b&&c["throws"]("Parameter is not a function!"),j=a.setTimeout(b.bind(b,+new Date),1e3/60)},k._loop=function(){var a=m.call(l),b=a.shift(),c=performance.now();for(l=[];b;)b(c),b=performance.now()-c<15?a.shift():null;a.length||l.length?(l.unshift.apply(l,a),k.windowRequestAnimationFrame(k._loop)):n=!1},k._getRequestAnimationFrame=function(){return(a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||k._requestAnimationFrameOnSetTimeout).bind(a)},k.windowRequestAnimationFrame=k._getRequestAnimationFrame(),k.requestAnimationFrame=function(a){l.push(a),n||(k.windowRequestAnimationFrame(k._loop),n=!0)},k._cancelAnimationFrameOnSetTimeout=function(){a.clearTimeout(j)},k.cancelAnimationFrames=function(a){var b=0,d=l.length,e=0;if(a)for(;d>0&&b>-1;){for(b=-1;d>e;e++)if(l[e].animationId===a){b=e;break}b>-1&&(l.splice(b,1),d--)}else c.warn("cancelAnimationFrames() require one parameter for request identify")},k._getCancelAnimationFrame=function(){return(a.cancelAnimationFrame||a.webkitCancelAnimationFrame||a.mozCancelAnimationFrame||a.oCancelAnimationFrame||a.msCancelAnimationFrame||k._cancelAnimationFrameOnSetTimeout).bind(a)},k.cancelAnimationFrame=k._getCancelAnimationFrame(),k.fetchSync=d,k._removeExternalScripts=e,k.safeEvalWrap=f,k.batchCall=g,k._createScriptsSync=h,k._removeInlineScripts=i,k.async=k.requestAnimationFrame,k.importEvaluateAndAppendElement=function(a,c){var d=k._createScriptsSync(k._removeExternalScripts(a),a),e=k._removeInlineScripts(a),f=b.importNode(a,!0);return c.appendChild(f),e.forEach(function(a){c.appendChild(a)}),k.batchCall(d),f},k.isNumber=function(a){var b=parseFloat(a);return!isNaN(b)&&isFinite(b)},k.runScript=function(c,d){var e,f,g,h=b.createElement("script"),i=m.call(d.attributes),j=d.getAttribute("src");for(null!==j&&(j=k.path.makeUrlAbsolute(j,c)),f=i.length;--f>=0;)g=i[f],"src"!==g.name?h.setAttribute(g.name,g.value):h.setAttribute("data-src",g.value);e=j?k.fetchSync(j,"text/plain"):d.textContent,e&&(h.src=a.URL.createObjectURL(new Blob([e],{type:"text/javascript"})),h.textContent=e),d.parentNode.replaceChild(h,d)},c.util=k}(a,a.document,d),function(){function a(a,b){return 1-3*b+3*a}function b(a,b){return 3*b-6*a}function c(a){return 3*a}function e(d,e,f){return((a(e,f)*d+b(e,f))*d+c(e))*d}function f(d,e,f){return 3*a(e,f)*d*d+2*b(e,f)*d+c(e)}function g(a,b,c,d,f){var g,h,i=0;do h=b+(c-b)/2,g=e(h,d,f)-a,g>0?c=h:b=h;while(Math.abs(g)>m&&++i<n);return h}function h(a,b,c,d){for(var g=0;k>g;++g){var h=f(b,c,d);if(0===h)return b;var i=e(b,c,d)-a;b-=i/h}return b}function i(a){if(!a||4!==a.length)throw new Error("BezierEasing: points must contains 4 values");for(var b=0;4>b;++b)if("number"!=typeof a[b]||isNaN(a[b])||!isFinite(a[b]))throw new Error("BezierEasing: points should be integers.");if(a[0]<0||a[0]>1||a[2]<0||a[2]>1)throw new Error("BezierEasing x values must be in [0, 1] range.")}function j(a,b,c,d){return 4===arguments.length?new j([a,b,c,d]):this instanceof j?(i(a),this._str="BezierEasing("+a+")",this._css="cubic-bezier("+a+")",this._p=a,this._mSampleValues=q?new Float32Array(o):[],this._precomputed=!1,this.get=this.get.bind(this),this):new j(a)}var k=4,l=.001,m=1e-7,n=10,o=11,p=1/(o-1),q="function"==typeof Float32Array;j.prototype={get:function(a){var b=this._p[0],c=this._p[1],d=this._p[2],f=this._p[3];return this._precomputed||this._precompute(),b===c&&d===f?a:0>=a?0:a>=1?1:e(this._getTForX(a),c,f)},_precompute:function(){var a=this._p[0],b=this._p[1],c=this._p[2],d=this._p[3];this._precomputed=!0,(a!==b||c!==d)&&this._calcSampleValues()},_calcSampleValues:function(){for(var a=this._p[0],b=this._p[2],c=0;o>c;++c)this._mSampleValues[c]=e(c*p,a,b)},_getTForX:function(a){for(var b=this._p[0],c=this._p[2],d=this._mSampleValues,e=0,i=1,j=o-1;i!==j&&d[i]<=a;++i)e+=p;--i;var k=(a-d[i])/(d[i+1]-d[i]),m=e+k*p,n=f(m,b,c);return n>=l?h(a,m,b,c):0===n?m:g(a,e,e+p,b,c)}},j.css={ease:j.ease=new j(.25,.1,.25,1),easeIn:j.easeIn=new j(.42,0,1,1),easeOut:j.easeOut=new j(0,0,.58,1),easeInOut:j.easeInOut=new j(.42,0,.58,1)},d&&d.util&&(d.util.bezierCurve=j)}(),function(a,b,d){function e(){for(var a,b=[].slice.call(arguments),d=0,e=b.length;e>d;d++)if(a=b[d],a!==c)return a;return null}function f(a,b){var c,d,e,f=a.steps,g=a.from,h=null,i=0,j=100;for(c in f)f.hasOwnProperty(c)&&(d=f[c],e=c/100,b>=e?(g=d,i=e):null===h&&(h=d,j=e));return g+(b-i)/(j-i)*(h-g)}function g(a,b,c){var d,g,h=c.steps||a.steps;c.duration=e(c.duration,a.duration),c.delay=e(c.delay,a.delay,0),d=e(c.object,this._object),c.simpleProperty=c.property,c.property.split(".").forEach(function(a){"object"==typeof d[a]&&null!==d[a]?(d=d[a],c.propertyObject=d):c.simpleProperty=a}),c.propertyObject=d,h?(c.calculate=f.bind(null,c),h[0]=e(h[0],c.from,d[c.simpleProperty]),c.from=h[0],c.to=e(h[100],c.to),c.diff=0,c.current=h[0],c.direction=c.from<c.to?1:-1):(c.calculate=c.calculate||o,g=e(c.from,d[c.simpleProperty]),c.from=g,c.diff=c.to-g,c.current=g,c.direction=g<c.to?1:-1),c.startTime=Date.now()+c.delay,this._pausedTimeDiff>0&&(c.startTime=Date.now()-this._pausedTimeDiff,this._pausedTimeDiff=0),c.lastCalculationTime=c.startTime,c.timing=e(c.timing,a.timing,o),b.push(c)}function h(a,b){a._animate&&(a._animate.chain=[].slice.call(b),a.start())}function i(a,b){var c=[].slice.call(b),d=[];c.forEach(function(a){d.unshift(a),a.forEach(function(a){a.timing=p})}),a._animate.chain=d,a._animate.callback=null,a.start()}function j(a){var b,c;if(a)for(c=a.length,b=0;c>b;b++)a[b].startTime=Date.now()}function k(a,b){var c,d=null;if(a&&a.startTime<=b){if(c=b-a.startTime,c>=a.duration&&(c=a.duration,a.callback&&a.callback()),a.duration>0&&(a.progress=c/a.duration,d=a.calculate(a.timing(c/a.duration),a.diff,a.from,a.current)),
+null!==d)return a.current=d,a.propertyObject[a.simpleProperty]=a.current,c>=a.duration?2:1;if(c>=a.duration)return 2}return 0}var l=d.util,m=l.requestAnimationFrame,n=function(a){var b=this;b._object=a,b._animate={chain:[],chainIndex:0},b._pausedTimeDiff=0,b._animateConfig=null},o=function(a,b,d){return b=b===c?1:b,d=d===c?0:d,a*(b||0)+(d||0)},p=function(a){return 1-a},q={};l.bezierCurve=l.bezierCurve||bezierCurve,n.prototype=q,n.timing={linear:o,ease:l.bezierCurve.ease.get,easeInOut:l.bezierCurve.easeInOut.get,easeIn:l.bezierCurve.easeIn.get,easeOut:l.bezierCurve.easeOut.get},q.destroy=function(){var a=this;a._object=null,a._animate=null,a._animateConfig=null},q.setProgress=function(a){var b,c=this,d=c._animate;b=d.chainIndex>0?d.chain[d.chainIndex-1]:d.chain[0],b&&b.forEach(function(b){b.progress=a,0===c._pausedTimeDiff?b.startTime=Date.now()-b.duration*a:c._pausedTimeDiff=b.duration*a})},q.getProgress=function(){var a,b=this,c=b._animate;return a=c.chainIndex>0?c.chain[c.chainIndex-1]:c.chain[0],a?a[0].progress:0},q._initAnimate=function(){var a=this,b=[],c=a._animate.chain[a._animate.chainIndex++];c?(c.forEach(g.bind(a,a._config,b)),a._animateConfig=b):a._animateConfig=null},q.set=function(a){var b,c,d=this,e=[].slice.call(arguments);return b=e.pop(),Array.isArray(b)?(e.push(b),b=null):d._animate.config=b,d._config=b,c=[].slice.call(e),b&&(b.loop&&b.duration>0?d._animate.callback=h.bind(null,d,c):b.withRevert?d._animate.callback=i.bind(null,d,c):d._animate.callback=a.callback||b.callback),d._animate.chain=e,d},q.start=function(a){var b=this;return b.active=!0,b._initAnimate(),b._animate.callback=b._animate.callback||a,a=b._animate.callback,b._animate.chainIndex<b._animate.chain.length?b._animationTimeout=b._calculateAnimate.bind(b,b.start.bind(b,a)):b._animationTimeout=b._calculateAnimate.bind(b,a),b._animationId=Math.random()+Date.now(),b._animationTimeout.animationId=b._animationId,b._calculateAnimate(a),b},q.stop=function(){var a=this;return a.active=!1,a._animate.chainIndex=0,a._animateConfig=null,d.util.cancelAnimationFrames(a._animationId),a._animationTimeout=null,a},q.pause=function(){var a=this;a.active=!1,a._animateConfig&&(a._pausedTimeDiff=Date.now()-a._animateConfig[0].startTime,a.stop())},q.reset=function(){var a=this,b=a.active;b&&a.stop(),a._initAnimate(),j(a._animateConfig),a._pausedTimeDiff=0,a._animate.chainIndex=0,a._calculateAnimate(),b&&a.start()},q._calculateAnimate=function(a){var b,c,d,e=this,f=e._animateConfig,g=!1,h=0,i=Date.now();if(f){for(b=f.length,c=f.length;c>h;)f[h].duration>0?(d=k(f[h],i),2===d?(b--,f.splice(h,1),c--,h--,g=!0):1===d&&(g=!0)):b--,h++;g&&e._tickFunction&&e._tickFunction(e._object),b?e._animationTimeout&&m(e._animationTimeout):(e.stop(),a&&a())}},q.tick=function(a){var b=this._tickFunction;return b?this._tickFunction=function(c){b(c),a(c)}:this._tickFunction=a,this},l.Animate=n}(a,a.document,d),function(a,b){function c(a){var b=a._animation,c=a.state;a.options.currentIteration++<a.options.iteration||"infinite"===a.options.iteration?(b.set(c.animation,c.animationConfig),b.stop(),b.start()):(a.options.marqueeStyle===n.ENDTOEND&&a._ui.content.classList.remove("ui-visible"),a.reset(),a.options.animation=h.STOPPED,a.trigger(l.MARQUEE_END))}var d=b.widget.BaseWidget,e=b.engine,f=b.util.object,g=b.util.Animate,h={RUNNING:"running",STOPPED:"stopped",IDLE:"idle"},i=function(){this.options=f.copy(i.defaults),this._callbacks={},this._ui={content:null}},j=new d,k="ui-marquee",l={MARQUEE_START:"marqueestart",MARQUEE_END:"marqueeend",MARQUEE_STOPPED:"marqueestopped"},m={MARQUEE_CONTENT:k+"-content",MARQUEE_GRADIENT:k+"-gradient",MARQUEE_ELLIPSIS:k+"-ellipsis",ANIMATION_RUNNING:k+"-anim-running",ANIMATION_STOPPED:k+"-anim-stopped",ANIMATION_IDLE:k+"-anim-idle"},n={SCROLL:"scroll",SLIDE:"slide",ALTERNATE:"alternate",ENDTOEND:"endToEnd"},o={GRADIENT:"gradient",ELLIPSIS:"ellipsis",NONE:"none"},p=function(a){return Math.round(100*a)/100},q={marqueeStyle:n.SLIDE,speed:60,iteration:"1",currentIteration:1,delay:0,timingFunction:"linear",ellipsisEffect:o.GRADIENT,runOnlyOnEllipsisText:!0,animation:h.STOPPED,autoRun:!0},r={LEFT:"-webkit-linear-gradient(left, transparent 0, rgb(255, 255, 255) 15%, rgb(255, 255, 255) 100%)",BOTH:"-webkit-linear-gradient(left, transparent 0, rgb(255, 255, 255) 15%, rgb(255, 255, 255) 85%, transparent 100%",RIGHT:"-webkit-linear-gradient(left, rgb(255, 255, 255) 0, rgb(255, 255, 255) 85%, transparent 100%)"};i.classes=m,i.defaults=q,j._calculateTranslateFunctions={scroll:function(a,b,c,d,e){var f,g=d+b*c;return f="translateX("+(-1*p(g)||0)+"px)",e===f?null:f},slide:function(a,b,c,d,e){var f,g,h,i=a._stateDOM,j=i.offsetWidth,k=i.children[0].offsetWidth;return g=15*j/100/2,f=b*(k-j+g),h="translateX("+(-1*p(f)||0)+"px)",e===h?null:h},alternate:function(a,b,c,d,e){var f,g=a._stateDOM,h=g.offsetWidth,i=g.children[0].offsetWidth,j=d+b*c;return j>i/2?j=i-2*(j-i/2):j*=2,j=j/i*(i-h),f="translateX("+(-1*p(j)||0)+"px)",e===f?null:f},endToEnd:function(a,b,c,d,e){var f,g=d+b*c;return f="translateX("+(-1*p(g)||0)+"px)",e===f?null:f}},j._calculateEndToEndGradient=function(a){var b,c=this,d=c._stateDOM,e=d.children[0].offsetWidth,f=(e-50)/e;return"none"===c.options.ellipsisEffect?null:b=a>0&&c.options.currentIteration<c.options.iteration?r.BOTH:a>f?r.RIGHT:a>0?r.BOTH:r.LEFT},j._calculateStandardGradient=function(a){var b;return isNaN(a)?null:"none"===this.options.ellipsisEffect?null:b=1===a?r.LEFT:a>0?r.BOTH:r.RIGHT},j._build=function(c){var d=c.querySelector("."+m.MARQUEE_CONTENT);if(c.classList.add(k),c.classList.contains(m.MARQUEE_ELLIPSIS)&&b.warn("Class '"+m.MARQUEE_ELLIPSIS+"' for option 'ellipsisEffect' in Marquee widget has been deprecated. Allowed values: none, '"+m.MARQUEE_GRADIENT+"' (default)"),!d){for(d=a.createElement("div");c.hasChildNodes();)d.appendChild(c.removeChild(c.firstChild));d.classList.add(m.MARQUEE_CONTENT),c.appendChild(d)}return this._ui.content=d,c},j._initStateDOMstructure=function(){this._stateDOM={classList:[],offsetWidth:null,style:{webkitMaskImage:null},children:[{offsetWidth:null,style:{webkitTransform:null}}]}},j._initAnimation=function(){var a=this,b=a._stateDOM,c=b.children[0],d=c.offsetWidth+(a.options.marqueeStyle===n.ENDTOEND?100:0),e=new g({}),f={hasEllipsisText:d>0,animation:[{object:c.style,property:"webkitTransform",calculate:a._calculateTranslateFunctions.scroll.bind(null,a),from:0,to:d},{object:b.style,calculate:a._calculateStandardGradient.bind(a),property:"webkitMaskImage",from:0,to:1}],animationConfig:{duration:d/a.options.speed*1e3,timing:g.timing.linear}};a.state=f,e.tick(a._render.bind(a,!0)),a._animation=e},j._init=function(a){var b=this;return b._initStateDOMstructure(),b._initDOMstate(),b._initAnimation(),b.option(b.options),a},j._setEllipsisEffect=function(a,c){return"ellipsis"===c&&b.warn("Marquee: option value 'ellipsis' for 'ellipsisEffect' is deprecated. Allowed values: 'none', 'gradient' (default)"),this._togglePrefixedClass(this._stateDOM,k+"-",c)},j._updateDuration=function(){var a=this,b=a._stateDOM,c=a.state,d=b.children[0],e=d.offsetWidth,f=e-b.offsetWidth,g=c.animationConfig;g.duration=f>0?e/a.options.speed*1e3:0,a._animation.set(c.animation,g)},j._setSpeed=function(a,b){var c=this;return c.options.speed=parseInt(b,10),c._updateDuration(),!1},j._setIteration=function(a,b){var d=this,e=d.state,f=e.animationConfig;return"infinite"===b?(f.loop=!0,f.callback=function(){d.options.animation=h.STOPPED,d.trigger.bind(d,l.MARQUEE_END)}):(b=parseInt(b,10),d.options.currentIteration=1,f.loop=!1,f.callback=c.bind(null,d)),d._animation.set(e.animation,f),d.options.iteration=b,!1},j._setDelay=function(a,b){var c=this,d=c.state,e=d.animationConfig;return b=parseInt(b,10),e.delay=b,c._animation.set(d.animation,e),c.options.delay=b,!1},j._setTimingFunction=function(a,b){var c=this,d=c.state,e=d.animationConfig;return e.timing=g.timing[b],c._animation.set(d.animation,e),c.options.timing=b,!1},j._setAutoRun=function(a,b){return b&&this.start(),!1},j._setAnimation=function(a,b){var c=this,d=c._animation,e=c._stateDOM,f=c.options,g=e.children[0].offsetWidth-e.offsetWidth,i=f.runOnlyOnEllipsisText;return b!==f.animation&&(b===h.RUNNING?(i&&g>0||!i)&&(c._ui.content.setAttribute("title",c._ui.content.textContent.trim()),c.options.marqueeStyle===n.ENDTOEND&&c._ui.content.classList.add("ui-visible"),d.start(),f.animation=b,c.trigger(l.MARQUEE_START)):(c.options.marqueeStyle===n.ENDTOEND&&c._ui.content.classList.remove("ui-visible"),d.pause(),f.animation=b,c.trigger(l.MARQUEE_STOPPED))),!1},j._setMarqueeStyle=function(a,b){var c=this,d=c.state.animation;return d[0].calculate=c._calculateTranslateFunctions[b].bind(null,c),"endToEnd"===b?d[1].calculate=c._calculateEndToEndGradient.bind(c):d[1].calculate=c._calculateStandardGradient.bind(c),c.options.marqueeStyle=b,!1},j._destroy=function(){var a,b=this;if(b.state=null,b._animation&&(b._animation.stop(),b._animation.destroy(),b._animation=null),b.element.style.webkitMaskImage="",a=b.element.querySelector("."+m.MARQUEE_CONTENT)){for(;a.hasChildNodes();)b.element.appendChild(a.removeChild(a.firstChild));b._stateDOM.children=[],a.parentElement===b.element&&b.element.removeChild(a)}b._stateDOM=null},j.start=function(){this.option("animation","running")},j.stop=function(){this.option("animation","stopped")},j.reset=function(){var a=this,b=a._animation;b.reset(),a.element.style.webkitMaskImage="none"===a.options.ellipsisEffect?"":r.RIGHT},i.prototype=j,b.widget.core.Marquee=i,e.defineWidget("Marquee",".ui-marquee",["start","stop","reset"],i,"core")}(a.document,d),function(b,c){var d=c.widget.core.Tab,e=d.prototype,f=c.engine,g=c.util.DOM,h=c.widget.core.BaseKeyboardSupport,i=function(){var a=this;h.call(this),a._type={orientation:"portrait",withIcon:!1,withTitle:!1,"static":!1},a._ui={tabs:[],links:[]},a.options={active:0,autoChange:!0,autoPositionSet:!0},a._marqueeOptions={ellipsisEffect:"none",marqueeStyle:"endToEnd",iteration:"infinite",delay:1e3},a._actualActiveTab=null},j="ui-sub-tab",k={SUBTAB:j,TAB_ACTIVE:"ui-tab-active",TAB_NO_TEXT:"ui-tab-no-text",TITLE:"ui-title",SUBTAB_PORTRAIT:j+"-portrait",SUBTAB_LANDSCAPE:j+"-landscape",SUBTAB_TEXT:j+"-text",SUBTAB_STATIC:j+"-static",ANCHOR:j+"-anchor",INACTIVE_TOO_LONG_TEXT:j+"-inactive-text-overflow"},l=c.event,m=new d;i.prototype=m,i.classes=k,i.selector="."+j+",[data-role='tabbar'],.ui-tabbar",m._configure=function(a){var b=a.querySelectorAll("li a"),c=-1;[].forEach.call(b,function(a,b){a.classList.contains(k.TAB_ACTIVE)&&(c=b)}),c>-1&&(this.options.active=c)},m._buildTabsAndLinks=function(a){var d,e,f,g,h,i,j,l,m=this,n=m._ui,o=a.querySelectorAll("li"),p=a.querySelectorAll("li a");if(0===p.length&&(p=a.querySelectorAll("li div")),0===p.length)return c.warn("There is no tab element, SubTab wasn't build."),!1;for(e=0,f=p.length;f>e;e++)g=p[e],h=g.firstChild,h?(d=b.createElement("span"),d.classList.add(k.SUBTAB_TEXT),d.appendChild(g.firstChild),g.appendChild(d),l=d.style.overflowX,j=d.getBoundingClientRect().width,d.style.overflowX="visible",i=d.getBoundingClientRect().width,d.style.overflowX=l,i>j&&g.classList.add(k.INACTIVE_TOO_LONG_TEXT)):g.classList.add(k.TAB_NO_TEXT),g.classList.add(k.ANCHOR);return n.links=p,n.tabs=o,!0},m._build=function(a){var b=this;return a.classList.add(k.SUBTAB),b._buildTabsAndLinks(a)?a:null},m._initOrientation=function(b){var c=this._type,d=b.classList;a.innerWidth<a.innerHeight?(d.remove(k.SUBTAB_LANDSCAPE),d.add(k.SUBTAB_PORTRAIT),c.orientation="portrait"):(d.remove(k.SUBTAB_PORTRAIT),d.add(k.SUBTAB_LANDSCAPE),c.orientation="landscape")},m._initStaticAndWidths=function(a){var b,c,d,e=this,f=e._ui.tabs,h=a.getBoundingClientRect().width,i=f.length,j=0;if(h){for(b=a.classList.contains(k.SUBTAB_STATIC),!b&&f[0]&&(c=g.getElementWidth(f[0]),c===c&&h>c*i&&(b=!0)),e._type["static"]=b,d=0;i>d;d++)b?(c=parseInt(h/i,10)||0,f[d].style.width=c+"px"):c=g.getElementWidth(f[d]),j+=c;e._wholeWidth=j}},m._init=function(a){var b=this;return b._initOrientation(a),b._initStaticAndWidths(a),b._translatedX=0,b._lastX=0,b._setActive(b.options.active),a},m._bindEvents=function(){var b=this,c=b._ui.tabs;l.on(c,"vclick",b,!1),a.addEventListener("resize",b,!1)},m._unBindEvents=function(){var b=this,c=b._ui.tabs;l.off(c,"vclick",b,!1),a.removeEventListener("resize",b,!1)},m.handleEvent=function(a){var b=this;switch(a.type){case"vclick":b._onClick(a);break;case"resize":b._init(b.element)}},m._onClick=function(a){var b,c,d,e=this,f=e._ui,g=e.options,h=a.currentTarget.querySelector("A");for(c=0,d=f.links.length;d>c;c++){if(f.links[c]===h){b=c;break}b=0}g.autoChange&&e._setActive(b)},m._setActive=function(a){var b,d,f,g,h,i,j=this,l=j.options,m=j._ui;0!==m.links.length&&a!==j._actualActiveTab&&(b=m.links[l.active],b.classList.remove(k.TAB_ACTIVE),d=b.querySelector("."+k.SUBTAB_TEXT),d&&(f=c.engine.getBinding(d),f&&(f.reset(),c.engine.destroyWidget(d),b.classList.add(k.INACTIVE_TOO_LONG_TEXT))),j.isKeyboardSupport===!0&&m.links[a].focus(),b=m.links[a],b.classList.add(k.TAB_ACTIVE),l.active=a,d=b.querySelector("."+k.SUBTAB_TEXT),d&&(g=d.style.overflowX,h=d.getBoundingClientRect().width,d.style.overflowX="visible",i=d.getBoundingClientRect().width,d.style.overflowX=g,i>h&&(b.classList.remove(k.INACTIVE_TOO_LONG_TEXT),c.widget.Marquee(d,j._marqueeOptions))),e._setActive.call(j,a),j._actualActiveTab=a)},m._destroy=function(){var a=this;a._unBindEvents(),a._type=null,a._ui=null,a.options=null},c.widget.core.SubTab=i,f.defineWidget("SubTab",i.selector,["setActive","getActive"],i)}(a.document,d),function(a,b){var c=b.widget.BaseWidget,d=b.engine,e=b.util.selectors,f=/[^\/]+$/,g={MAIN_TAB:"ui-main-tab",VISIBLE:"ui-main-tab-visible",ACTIVE_TAB:"ui-tab-active"},h=function(){this._ui={}},i=new c;h.classes=g,h.prototype=i,i._build=function(a){return a.classList.add(g.MAIN_TAB),a},i._init=function(c){var d=this,f=null;return d._ui.parentPage=e.getClosestBySelector(c,".ui-page"),d._ui.links=[].slice.call(c.querySelectorAll("li > a")),d._ui.links.forEach(function(c){var d=a.createElement("span"),e=c.textContent.trim();d.textContent=e,c.textContent="",c.appendChild(d),b.widget.Marquee(d,{iteration:1,delay:0,marqueeStyle:"endToEnd",autoRun:!1}),c.setAttribute("data-rel","maintab")}),c.classList.add(g.VISIBLE),f=e.getClosestBySelector(c,".ui-page-container"),f.appendChild(c),c},i.handleEvent=function(a){var b=this;switch(a.type){case"pagebeforeshow":b._onPageBeforeShow(a)}},i._bindEvents=function(){a.addEventListener("pagebeforeshow",this,!0)},i._unbindEvents=function(){a.removeEventListener("pagebeforeshow",this,!0)},i._onPageBeforeShow=function(a){var c,d,e,h,i=this,j=a.target,k=i.element,l=i._ui.links;i._ui.parentPage===j?(d=l.filter(function(a){return a.classList.contains(g.ACTIVE_TAB)})[0]||k.querySelector("a"),d?(k.classList.add(g.VISIBLE),c=b.router.Router.getInstance(),c.open(d.getAttribute("href"),{rel:"maintab"})):b.warn("MainTab: The widget requires at least one tab with link")):k.classList.contains(g.VISIBLE)&&(e=j.getAttribute("data-url"),h=e.match(f)[0],h&&(d=l.filter(function(a){return a.getAttribute("href").indexOf(h)>-1})[0],d?(d.classList.contains(g.ACTIVE_TAB)||l.forEach(function(a){a.classList.toggle(g.ACTIVE_TAB,a.getAttribute("href").indexOf(h)>-1)}),i._disableTopRounds(j)):k.classList.remove(g.VISIBLE)))},i._disableTopRounds=function(a){var b,c=a.querySelector(".ui-appbar");c||(b=a.querySelector(".ui-content-area"),b.classList.add("ui-content-area-disabled-top-rounding"))},i._destroy=function(){this._unbindEvents()},b.widget.core.MainTab=h,d.defineWidget("MainTab","[data-role='main-tab'], .ui-main-tab",[],h,"core")}(a.document,d),function(a,b,c){function d(a){var b;return a?(b=Object.keys(a).join(":"),b.indexOf("__impl")>-1||b.indexOf("__upgraded__")>-1||b.indexOf("__attached__")>-1):!1}function e(b){var c=a.ShadowDOMPolyfill&&a.ShadowDOMPolyfill.wrap;return b&&c?c(b):b}function f(b){var d=a.ShadowDOMPolyfill&&a.ShadowDOMPolyfill.unwrap;return b&&d?d(b):(c.error("Unwrap method not available"),b)}function g(a){for(var b,c=a.attributes,d=c.length,e=0,f=a.tagName.toLowerCase();d>e;++e)b=c.item(e),f+="["+b.name+'="'+b.value+'"]';return f}function h(a){for(var c=g(a),d=a.parentNode;d;)c=g(d)+">"+c,d=d.parentNode,d===b&&(d=null);return c}function i(a){for(;a.firstChild;)a.removeChild(a.firstChild)}function j(a,b){for(;a.firstChild;)b.appendChild(a.firstChild)}function k(a,c){var d=b.createElement("div"),e=!1;return a.appendChild(d),d.innerHTML=c.replace(o,function(){return e=!0,"<span id='temp-container-"+ ++l+"'></span>"}),{container:d,contentFlag:e}}var l=0,m=[].slice,n=c.util.DOM,o=/(\$\{content\})/gi;n.getNodeSelector=g,n.getNodeSelectorPath=h,n.isNodeEqual=function(c,e){var f,g,i=c,j=e,k=a.ShadowDOMPolyfill&&a.ShadowDOMPolyfill.unwrap;return null===c||null===e?!1:(f=d(c),g=d(e),f&&(i=k?k(c):b.querySelector(h(c))),g&&(j=k?k(e):b.querySelector(h(e))),i===j)},n.isNodeWebComponentPolyfilled=d,n.unwrapWebComponentPolyfill=f,n.wrapWebComponentPolyfill=e,n.isElement=function(a){var b=a;return b?"string"==typeof b.localName&&b.localName.length>0?!0:(a instanceof Element||d(a)&&(b=f(a)),b instanceof Element):!1},n.appendNodes=function(a,b){var c,d,e;if(a){if(b instanceof Array||b instanceof NodeList||b instanceof HTMLCollection)for(e=m.call(b),c=0,d=e.length;d>c;c+=1)a.appendChild(e[c]);else a.appendChild(b),e=b;return e}throw"Context empty!"},n.replaceWithNodes=function(a,b){var c=null;return a.parentNode&&(b instanceof Array||b instanceof NodeList||b instanceof HTMLCollection?(c=this.insertNodesBefore(a,b),a.parentNode.removeChild(a)):(a.parentNode.replaceChild(b,a),c=b)),c},n.removeAllChildren=function(a){a.innerHTML=""},n.insertNodesBefore=function(a,b){var c,d,e,f;if(a){if(e=a.parentNode,b instanceof Array||b instanceof NodeList||b instanceof HTMLCollection)for(f=m.call(b),c=0,d=f.length;d>c;++c)e.insertBefore(f[c],a);else e.insertBefore(b,a),f=b;return f}throw"Context empty!"},n.insertNodeAfter=function(a,b){if(a)return a.parentNode.insertBefore(b,a.nextSibling),b;throw"Context empty!"},n.wrapInHTML=function(a,c){var d,e,f,g=b.createDocumentFragment(),h=b.createDocumentFragment(),m=a.length,n=m?a[0].parentNode:a.parentNode,o=m?a[m-1].nextSibling:a.nextSibling;return f=k(g,c),f.contentFlag===!0?(d=f.container.querySelector("span#temp-container-"+l),e=this.replaceWithNodes(d,a)):(d=f.container.children[0],e=this.appendNodes(d||f.container,a)),j(g.firstChild,h),i(g),n?n.insertBefore(h,o):i(h),e},n.isChildElementOf=function(a,b){if(b)for(;a&&a.parentElement;){if(b===a.parentElement)return!0;a=a.parentElement}return!1}}(a,a.document,d),function(b,c){function d(a){var b=a.element;b.selectedIndex=a._ui.input.checked?1:0,"select"===a._type&&p.trigger(b,"change")}function e(a){return b.createElement(a)}function f(){var a=e("input");return a.type="checkbox",a.setAttribute("data-role","none"),a}function g(a,b,c){var d;a.style.display="none",a.parentNode.insertBefore(c,a),d=f(),a.hasAttribute("disabled")&&d.setAttribute("disabled","disabled"),d.className=r.toggleInput,c.className=o.removeExactTags(a.className,r.toggleContainer,d.className),c.className=r.toggleContainer,c.appendChild(d),c.appendChild(b),c.appendChild(a)}function h(a,b,c){c.className=r.toggleContainer,a.classList.add(r.toggleInput),b.classList.add(r.toggleHandler),a.parentNode.insertBefore(c,a),c.appendChild(a),c.appendChild(b)}function i(a,b){var c=a.from,d=a.to;return[b*Math.abs(d.r-c.r),b*Math.abs(d.g-c.g),b*Math.abs(d.b-c.b),b*Math.abs(d.a-c.a)]}function j(a){a.removeAttribute("data-tau-name"),a.removeAttribute("aria-disabled"),a.removeAttribute("data-tau-bound"),a.removeAttribute("data-tau-built")}var k=function(){var a=this;a.options={appearance:"slider"},a._ui={},a._callbacks={},a._transform={bgColor:{from:{r:0,g:0,b:0,a:0},to:{r:3,g:129,b:254,a:1}},borderColor:{from:{r:143,g:143,b:143,a:1},to:{r:0,g:0,b:0,a:0}}}},l=c.widget.BaseWidget,m=c.widget.core.BaseKeyboardSupport,n=c.engine,o=c.util.string,p=c.event,q="ui-on-off-switch",r={toggleContainer:q+"-container",toggle:q,toggleHandler:q+"-button",toggleInput:q+"-input",onDrag:q+"-button-on-drag",moveToOff:q+"-button-move-to-off",moveToOn:q+"-button-move-to-on",toggleContainerFocus:q+"-focus"},s={HOME:36,END:35,PAGE_UP:33,PAGE_DOWN:34,UP:38,RIGHT:39,DOWN:40,LEFT:37,ENTER:13,SPACE:32},t="";k.prototype=new l,k.classes=r,k.keyCode=s,k.prototype._build=function(a){var b=e("div"),c=e("div"),d=a.nodeName.toLowerCase();return"input"===d&&h(a,b,c),"select"===d&&g(a,b,c),b.className=r.toggleHandler,this._type=d,this._ui.handler=b,this._ui.toggleContainer=c,a},k.prototype._init=function(a){var b=this;b._ui.input=a.parentElement.querySelector("input"),"select"===b._type&&(b._ui.input.checked=!!a.selectedIndex,a.hasAttribute("disabled")&&b._disable())},k.prototype._disable=function(){this._ui.input.setAttribute("disabled","true")},k.prototype._enable=function(){this._ui.input.removeAttribute("disabled")},k.prototype._getValue=function(){var a=this,b=a.element;return["checkbox","radio"].indexOf(b.type)>-1?b.checked:b.selectedIndex},k.prototype._setValue=function(a){var b=this,c=b.element;"input"===b._type&&(c.value=a),["checkbox","radio"].indexOf(c.type)>-1&&(c.checked=!!a),"select"===b._type&&(c.selectedIndex=a,b._ui.input.checked=!!a)},k.prototype._onDragStart=function(){var b,c,d,e=this,f=e._ui,g=f.input,h=f.handler;e.element.disabled||(b=g.getBoundingClientRect(),c=h.getBoundingClientRect(),d=a.getComputedStyle(g),e._moveWidth=b.width-c.width+parseInt(d.borderLeftWidth,10)+parseInt(d.borderRightWidth,10),h.classList.add(r.onDrag))},k.prototype._onDragEnd=function(a){var b,c,e=this,f=e._ui,g=f.input,h=f.handler,i=e._moveWidth,j=g.checked?i:0;e.element.disabled||(b=j+a.detail.deltaX,b=Math.min(Math.max(b,0),i),h.classList.remove(r.onDrag),c=b>i/2,c?h.classList.add(r.moveToOn):h.classList.add(r.moveToOff),f.input.style.backgroundColor=null,f.input.style.borderColor=null,f.input.style.borderWidth=null,c!==g.checked&&(e._setValue(c?1:0),d(e)))},k.prototype._onDrag=function(a){var b,c,d=this,e=d._ui,f=d._moveWidth,g=e.input.checked?f:0;d.element.disabled||(b=g+a.detail.deltaX,b=Math.min(Math.max(b,0),f),e.handler.style.transform="translateX("+b+"px)",c=f?b/f:1,e.input.style.backgroundColor="rgba("+i(d._transform.bgColor,c).join(",")+")",e.input.style.borderColor="rgba("+i(d._transform.borderColor,1-c).join(",")+")",e.input.style.borderWidth=1-c+"px")},k.prototype._onAnimationEnd=function(a){var b=a.target.classList;b.remove(r.moveToOff),b.remove(r.moveToOn),this._ui.handler.style.transform=null},k.prototype.handleEvent=function(a){var b=this;switch(a.type){case"change":d(b);break;case"focus":b._focus(a);break;case"blur":b._blur(a);break;case"keyup":b._keyUp(a);break;case"drag":b._onDrag(a);break;case"dragstart":b._onDragStart(a);break;case"dragend":b._onDragEnd(a);break;case"animationend":case"animationEnd":case"webkitAnimationEnd":b._onAnimationEnd(a)}},k.prototype._bindEvents=function(){var a=this,b=a._ui.input;c.event.enableGesture(b,new c.event.gesture.Drag({threshold:0})),b.addEventListener("change",a,!0),b.addEventListener("focus",a,!0),b.addEventListener("blur",a,!0),b.addEventListener("keyup",a,!0),b.addEventListener("dragstart",a,!0),b.addEventListener("drag",a,!0),b.addEventListener("dragend",a,!0),p.on(a._ui.handler,"animationend animationEnd webkitAnimationEnd",a,!1)},k.prototype._unbindEvents=function(){var a=this,b=a._ui.input;b.removeEventListener("change",a,!0),b.removeEventListener("focus",a,!0),b.removeEventListener("blur",a,!0),b.removeEventListener("keyup",a,!0),b.removeEventListener("drag",a,!0),b.removeEventListener("dragstart",a,!0),b.removeEventListener("dragend",a,!0),p.off(a._ui.handler,"animationend animationEnd webkitAnimationEnd",a,!1),c.event.disableGesture(b)},k.prototype._destroy=function(){var a=this,c=a.element,d=a._type,e=c.parentElement;a._ui.input.removeEventListener("change",a._onChangeValue,!0),j(c),("input"===d||"select"===d)&&e.parentElement&&(e.parentElement.insertBefore(c,e),e.parentElement.removeChild(e)),"input"===d&&c.classList.remove(r.toggle),p.trigger(b,"destroyed",{widget:"OnOffSwitch",parent:c.parentNode})},k.prototype._focus=function(){var a;c.getConfig("keyboardSupport",!1)&&(a=this.element.parentElement.classList,a.add(r.toggleContainerFocus),this.element.focus())},k.prototype._blur=function(){var a;c.getConfig("keyboardSupport",!1)&&(a=this.element.parentElement.classList,a.remove(r.toggleContainerFocus),this.element.blur())},k.prototype._keyUp=function(a){a.keyCode===s.ENTER&&(this._ui.input.checked=!this._ui.input.checked)},k.prototype._getContainer=function(){return this._ui.toggleContainer},t="input[data-role='on-off-switch'],select[data-role='on-off-switch'],select.ui-on-off-switch,input.ui-on-off-switch",k.widgetSelector=t,c.widget.core.OnOffSwitch=k,n.defineWidget("OnOffSwitch",t,[],k,"core"),m.registerActiveSelector(t)}(a.document,d),function(a,b){function c(a){var b=a._ui.onOff,c=a._ui.labelOnOff,d=a._ui.labelTextOnOff;b.checked?(c.classList.add("ui-on-off-label-on"),d.innerHTML="On"):(c.classList.remove("ui-on-off-label-on"),d.innerHTML="Off"),a._disableAllOnOff(!b.checked)}function d(a){a._ui.labelOnOff.classList.add("ui-on-off-label-active")}function e(a){a._ui.labelOnOff.classList.remove("ui-on-off-label-active")}var f=function(){var a=this;a.options={target:null},a._ui={},a._onChangeMasterOnOff=null},g=b.widget.BaseWidget,h=b.widget.core.BaseKeyboardSupport,i=b.engine,j="ui-master-on-off-switch",k={WIDGET:j},l={ENTER:13,SPACE:32},m=".ui-master-on-off-switch",n=new g;f.prototype=n,f.classes=k,f.keyCode=l,n._build=function(c){var d=this,e=a.createElement("label"),f=a.createElement("span"),g=a.createElement("input");return g.classList.add("ui-on-off-switch"),g.type="checkbox",e.classList.add("ui-on-off-label"),f.innerHTML="Off",e.appendChild(f),e.appendChild(g),c.appendChild(e),c.classList.add(k.WIDGET),d._ui.onOff=g,d._ui.labelOnOff=e,d._ui.labelTextOnOff=f,b.widget.OnOffSwitch(g),c},n._init=function(a){var b=this;b._ui.input=a.querySelector("input.ui-on-off-switch"),c(b)},n._bindEvents=function(){var a=this,b=a._ui.onOff,f=a._ui.labelOnOff,g=c.bind(null,a),h=d.bind(null,a),i=e.bind(null,a);b.addEventListener("change",g),f.addEventListener("vmousedown",h),f.addEventListener("vmouseup",i),a._onChangeMasterOnOff=g},n._unbindEvents=function(){var a=this,b=a._ui.onOff;b.removeEventListener("change",a._onChangeMasterOnOff),b.removeEventListener("vmousedown",a._onTouchStart),b.removeEventListener("vmouseup",a._onTouchEnd),a._onChangeMasterOnOff=null,a._onTouchStart=null,a._onTouchEnd=null},n._disableAllOnOff=function(c){var d=a.getElementById(this.options.target),e=[],f=this._ui,g=null;d?(e=[].slice.call(d.querySelectorAll(".ui-on-off-switch")),e.filter(function(a){return a!==f.onOff}).forEach(function(a){g=b.widget.OnOffSwitch(a),c?g.disable():g.enable()})):b.warn("MasterOnOffSwitch: indicated target element ("+this.options.target+") not found")},n._destroy=function(){this._unbindEvents()},n._keyUp=function(a){a.keyCode===l.ENTER&&(this._ui.onOff.checked=!this._ui.onOff.checked)},f.widgetSelector=m,b.widget.core.MasterOnOffSwitch=f,i.defineWidget("MasterOnOffSwitch",m,[],f,"core"),h.registerActiveSelector(m)}(a.document,d),function(a,b){function c(a){a.setAttribute("role","textinput"),a.setAttribute("aria-label","Keyboard opened")}function d(b,c,d){var e=a.createElement("span");return c&&e.classList.add(c),d&&(e.innerHTML=d),i.insertNodeAfter(b,e),e}var e=b.widget.mobile.BaseWidgetMobile,f=b.widget.core.BaseKeyboardSupport,g=b.engine,h=b.util,i=h.DOM,j=h.selectors,k=h.object,l=b.event,m=function(){var a=this;a.options=k.merge({},m.defaults),a._ui={textLineElement:null,textClearButtonElement:null,errorMessageElement:null},a._callbacks={},f.call(a)},n=b.widget.core.Button.classes,o=b.widget.core.Listview.classes,p=b.widget.core.Popup.classes,q=new e,r="ui-text-input",s={uiTextInput:r,uiTextInputClear:r+"-clear",uiTextInputClearHidden:r+"-clear-hidden",uiTextInputClearActive:r+"-clear-active",uiTextInputTextLine:r+"-textline",uiTextInputErrorMessage:r+"-error-message",uiTextInputDisabled:r+"-disabled",uiTextInputFocused:r+"-focused",HEADER_WITH_SEARCH:"ui-header-searchbar",SEARCHINPUT:"ui-search-input",HEADER:"ui-header",CONTAINER:r+"-container",WIDGET_FOCUSED:r+"-widget-focused"},t={uiTextInput:"."+s.uiTextInput,uiTextInputClearButton:"."+s.uiTextInputClear,uiTextInputTextLine:"."+s.uiTextInputTextLine},u={clearBtn:!1,textLine:!0,maxHeight:null,outsideDiv:!1,errorMessageString:"Enter a valid email address"},v={SEARCH:"search",ANIMATIONEND:"animationend"};m.prototype=q,m.classes=s,m.defaults=u,q._resizeTextArea=function(a){var b,c,d,e,f=h.selectors.getClosestByClass(a,p.popup),i=parseInt(this.options.maxHeight,10),j=a.style,k=j.height;j.height="auto",e=a.scrollHeight,a.scrollTop=e,i&&e>i&&(e=i),j.height=e+"px",k!==e+"px"&&f&&""!==k&&(d=g.getBinding(f),d.refresh()),b=h.selectors.getClosestByClass(a,o.LISTVIEW),b&&(c=g.getBinding(b),c&&c.refresh())},q._toggleClearButton=function(a,b){a&&(b.classList.contains(s.uiTextInputFocused)?(a.classList.remove(s.uiTextInputClearHidden),b.classList.add(s.uiTextInputClearActive)):a.classList.contains("ui-btn-active")||a.classList.add(s.uiTextInputClearHidden))},q._onClearBtnClick=function(a){a.element.focus(),a.element.value="",a.trigger(v.SEARCH)},q._onClearBtnAnimationEnd=function(a,b){"btn_pressup_animation"===b.animationName&&""===a.element.value&&b.target.classList.add(s.uiTextInputClearHidden)},q._onFocus=function(a){var b=a.element,c=b.value.length;b.classList.add(s.uiTextInputFocused),""!==b.value&&a._ui.textClearButtonElement&&a._ui.textClearButtonElement.classList.remove(s.uiTextInputClearHidden),b.selectionStart=c,b.selectionEnd=c},q._onInput=function(a){var b=a.element,c=a._ui.textClearButtonElement;""===b.value&&c?(c.classList.add(s.uiTextInputClearHidden),b.classList.remove(s.uiTextInputClearActive)):a._toggleClearButton(a._ui.textClearButtonElement,b),"textarea"===b.nodeName.toLowerCase()&&a._resizeTextArea(b)},q._onBlur=function(a){var b=a.element;b.classList.remove(s.uiTextInputFocused),a._toggleClearButton(a._ui.textClearButtonElement,b)},q._createClearButton=function(b,c){var d=a.createElement("a");return d.classList.add(n.BTN),d.classList.add(n.BTN_ICON),d.classList.add(n.BTN_NOBG),d.classList.add(s.uiTextInputClear),d.classList.add(s.uiTextInputClearHidden),d.tabindex=0,c?b.parentNode.appendChild(d):b.parentNode.insertBefore(d,b.nextSibling.nextSibling),d},q._build=function(a){var b,e=this,f=e.options,g=a.type,h=a.pattern,i=e._ui;switch(e._setOutsideDiv(a,f.outsideDiv),g){case"text":case"password":case"number":case"email":case"url":case"tel":case"search":c(a),i.textLineElement=d(a,s.uiTextInputTextLine);break;default:"textarea"===a.tagName.toLowerCase()&&(c(a),f.textLine&&(i.textLineElement=d(a,s.uiTextInputTextLine)))}return a.classList.add(s.uiTextInput),a.tabindex=0,f.clearBtn&&(i.textClearButtonElement=e._createClearButton(a)),"search"===g&&(b=j.getClosestByClass(a,s.HEADER),a.classList.add(s.SEARCHINPUT),b&&(b.classList.add(s.HEADER_WITH_SEARCH),a.nextElementSibling.classList.contains(s.uiTextInputTextLine)&&a.parentElement.removeChild(a.nextElementSibling)),f.clearBtn||(i.textClearButtonElement=e._createClearButton(a,b)),a.getAttribute("placeholder")||a.setAttribute("placeholder","Search")),("email"===g||h)&&(i.errorMessageElement=d(i.textLineElement,s.uiTextInputErrorMessage,f.errorMessageString)),a},q._setOutsideDiv=function(b,c){var d=a.createElement("div"),e=this._ui;c&&(d.className=s.CONTAINER,b.parentElement.replaceChild(d,b),d.classList.add(r+"-type-"+b.type),d.appendChild(b),e.container=d),this.options.outsideDiv=c},q._init=function(a){var b=this,c=b._ui,d=b.options,e=a.type,f=a.parentNode;if(d.clearBtn&&(c.textClearButtonElement=c.textClearButtonElement||f.querySelector(t.uiTextInputClearButton)),d.textLine)switch(e){case"text":case"password":case"number":case"email":case"url":case"tel":c.textLineElement=c.textLineElement||f.querySelector(t.uiTextInputTextLine);break;default:"textarea"===a.nodeName.toLowerCase()&&(c.textLineElement=c.textLineElement||f.querySelector(t.uiTextInputTextLine));
+}return"textarea"===a.nodeName.toLowerCase()&&(a.hasAttribute("rows")===!1&&(a.rows=1),b._resizeTextArea(a)),a},q._bindEvents=function(){var a=this,b=a.element,c=a._ui.textClearButtonElement,d=a._onInput.bind(null,a),e=a._onFocus.bind(null,a),f=a._onBlur.bind(null,a),g=a._onClearBtnClick.bind(null,a),h=a._onClearBtnAnimationEnd.bind(null,a);a._callbacks={onInputCallback:d,onFocusCallback:e,onBlurCallback:f,onClearBtnClickCallback:g,onClearBtnAnimationEndCallback:h},l.on(b,"input",d),l.on(b,"focus",e),l.on(b,"blur",f),c&&(l.on(c,"click",g),l.on(c,v.ANIMATIONEND,h))},q._unbindEvents=function(){var a=this,b=a.element,c=a._ui.textClearButtonElement,d=a._callbacks;l.off(b,"input",d.onInputCallback),l.off(b,"focus",d.onFocusCallback),l.off(b,"blur",d.onBlurCallback),c&&(l.off(c,"click",d.onClearBtnClickCallback),l.off(c,v.ANIMATIONEND,d.onClearBtnAnimationEndCallback))},q._enable=function(){var a=this.element;a&&(a.removeAttribute("disabled"),a.classList.remove(s.uiTextInputDisabled))},q._disable=function(){var a=this.element;a&&(a.setAttribute("disabled","disabled"),a.classList.add(s.uiTextInputDisabled))},q._getValue=function(){var a=this.element;return a?a.value:null},q._setValue=function(a){var b=this.element;return b&&(b.value=a),this},q._destroy=function(){var a=this,b=a._ui,c=b.textLineElement,d=b.textClearButtonElement,e=b.errorMessageElement;a._unbindEvents(),c&&c.parentElement&&c.parentElement.removeChild(b.textLineElement),d&&d.parentElement.removeChild(b.textClearButtonElement),e&&e.parentElement.removeChild(b.errorMessageElement)},q._getContainer=function(){var a=this,b=a._ui,c=b.container,d=a.element;return c?c:d},q._focus=function(a){var b=a.classList;b.add(s.WIDGET_FOCUSED)},q._blur=function(a){var b=a.classList;b.remove(s.WIDGET_FOCUSED),a.blur()},q._actionEnter=function(a){var b=this;b._blur(a),a.focus()},q._actionEscape=function(a){var b=this;a.blur(),b.focus()},f.registerActiveSelector("input[type='text']:not([data-role]), input[type='number']:not([data-role]), input[type='password']:not([data-role]), input[type='email']:not([data-role]), input[type='url']:not([data-role]), input[type='tel']:not([data-role]), input[type='search']:not([data-role]), .ui-search-input, textarea, input:not([type])."+s.uiTextInput),b.widget.mobile.TextInput=m,g.defineWidget("TextInput","input[type='text']:not([data-role]), input[type='number']:not([data-role]), input[type='password']:not([data-role]), input[type='email']:not([data-role]), input[type='url']:not([data-role]), input[type='tel']:not([data-role]), input[type='search']:not([data-role]), .ui-search-input, textarea, input:not([type])."+s.uiTextInput,[],m,"mobile",!1,!1,HTMLInputElement),b.widget.mobile.TextArea=m,g.defineWidget("TextArea",null,[],m,"mobile",!1,!1,HTMLTextAreaElement),g.defineWidget("SearchInput","",[],m,"mobile")}(a.document,d),function(b,c){function d(a,b){a._toggleSelect(b),v.stopPropagation(b),v.preventDefault(b)}function e(a,b){var c=b.target,d=c.tagName,e=c.classList;"LI"!==d||e.contains(C.optionGroup)||e.contains(C.disabled)||(a._selectedIndex=z.call(a._ui.elOptions,c),a._changeOption(),a._toggleSelect(b)),b.stopPropagation(),b.preventDefault()}function f(a){var b=a._ui,c=b.elSelect[b.elSelect.selectedIndex];b.elPlaceHolder.textContent=c.textContent}function g(a,b){a._isOpen===!0&&(a._isOpen=!a._isOpen,a._toggleSelect(b),b.stopPropagation(),b.preventDefault())}function h(a,b){var d=a._ui,e=b.target;c.getConfig("keyboardSupport")&&(e===d.elSelectWrapper||e.parentNode===d.elOptionContainer)&&e.classList.add(C.focus)}function i(a,b){b.stopPropagation()}function j(a,b){var d=a._ui,e=b.target;c.getConfig("keyboardSupport")&&(e===d.elSelectWrapper||e.parentNode===d.elOptionContainer)&&e.classList.remove(C.focus)}function k(a,b){var c=a.classList;b?(c.add(C.disabled),c.add(C.widgetDisabled),c.add(r.classes.disable)):(c.remove(C.disabled),c.remove(C.widgetDisabled),c.remove(r.classes.disable))}function l(a){var b,c=a,d=0,e=0,f=[];for(c=c.split(","),d=c.length,e=0;d>e;e++)b=c[e].split(":"),f.push({textContent:b[0],value:b[1]});return f}function m(a,b){var c=l(b),d=c.length,e=0,f=0;for(a.innerHTML="",f=0;d>f;f++)e="undefined"!=typeof c[f].value?c[f].value:f+1,a.innerHTML+='<option value="'+e+'">'+c[f].textContent+"</option>"}function n(a,b){for(var c,d=a.offsetTop;a.offsetParent&&(c=a.offsetParent,d+=c.offsetTop,a!==b);)a=c;return d}function o(a){var b=a._ui;b.elOptionWrapper.classList.add(C.opened),v.prefixedFastOff(b.elOptionContainer,"animationEnd",a._callbacks.showAnimationEnd,!1),b.elOptionWrapper.classList.remove(C.opening)}function p(a){var b=a._ui.elOptionWrapper,c=b.classList,d=a._ui.elOptionContainer;c.remove(C.active),b.removeAttribute("style"),v.prefixedFastOff(d,"animationEnd",a._callbacks.hideAnimationEnd,!1),c.remove(C.closing),c.remove(C.top),c.remove(C.bottom)}function q(a){return a.offsetWidth}var r=c.widget.mobile.BaseWidgetMobile,s=c.widget.core.BaseKeyboardSupport,t=c.engine,u=c.util.DOM,v=c.event,w=c.util.selectors,x=[].slice,y=c.widget.core.Page,z=[].indexOf,A=function(){var a=this;a._isOpen=!1,a._isClosing=!1,a._selectedIndex=null,a._ui={elSelectWrapper:null,elPlaceHolder:null,elSelect:null,screenFilter:null,elOptionContainer:null,elOptions:null,elPage:null,elContent:null,elDefaultOption:null},a._horizontalPosition=null,a.options={nativeMenu:!0,inline:!1,hidePlaceholderMenuItems:!0,items:""},a._toggleMenuBound=null,a._changeOptionBound=null,a._onResizeBound=null,a._nativeChangeOptionBound=null,a._focusBound=null,a._blurBound=null,a._callbacks={},s.call(a)},B="select:not([data-role='slider']):not([data-role='range']):not([data-role='toggleswitch']):not(.ui-toggleswitch):not(.ui-slider):not([data-role='on-off-switch']):not(.ui-on-off-switch),select.ui-select-menu:not([data-role='slider']):not([data-role='range']):not([data-role='toggleswitch']):not([data-role='on-off-switch']):not(.ui-on-off-switch),.ui-dropdownmenu",C={selectWrapper:"ui-dropdownmenu",optionGroup:"ui-dropdownmenu-optiongroup",placeHolder:"ui-dropdownmenu-placeholder",optionList:"ui-dropdownmenu-options",optionsWrapper:"ui-dropdownmenu-options-wrapper",selected:"ui-dropdownmenu-selected",active:"ui-dropdownmenu-active",opening:"ui-dropdownmenu-options-opening",closing:"ui-dropdownmenu-options-closing",opened:"ui-dropdownmenu-options-opened",filter:"ui-dropdownmenu-overlay",filterHidden:"ui-dropdownmenu-overlay-hidden",disabled:"ui-dropdownmenu-disabled",widgetDisabled:"ui-disabled",inline:"ui-dropdownmenu-inline","native":"ui-dropdownmenu-native",top:"ui-dropdownmenu-options-top",bottom:"ui-dropdownmenu-options-bottom",focus:s.classes.focus,verticalMargins:"ui-dropdownmenu-options-vertical-margins"},D=new r;A.prototype=D,A.classes=C,D._convertOptionToHTML=function(a,b,c){var d=b.className;return a&&u.getNSData(b,"placeholder")?"":(c&&(d+=" "+C.disabled),"<li data-value='"+b.value+"'"+(d?" class='"+d+"'":"")+(c?"":" tabindex='0'")+">"+b.textContent+"</li>")},D._constructOption=function(){for(var a,b,c,d,e,f,g=this,h=0,i="",j=x.call(g._ui.elSelect.children),k=j.length,l=g.options.hidePlaceholderMenuItems;k>h;h++)if(b=j[h],f=b.disabled,c=b.tagName,"OPTION"===c)i+=g._convertOptionToHTML(l,b,f);else if("OPTGROUP"===c)for(i+="<li class='"+C.optionGroup+(f?" "+C.disabled+"'":"'")+">"+b.label+"</li>",d=x.call(b.children),a=0,e=d.length;e>a;a++)f=b.disabled||d[a].disabled,i+=g._convertOptionToHTML(l,d[a],f);return i},D._setInline=function(a,b){var c=this._ui;c.elSelectWrapper.classList.toggle(C.inline,b),b&&c.elPlaceHolder.removeAttribute("style"),this.options.inline=b},D._configure=function(a){return a.webkitMatchesSelector("."+C.selectWrapper)&&(a=a.querySelector(A.widgetSelector))?a:null},D._getContainer=function(){return this._ui.elSelectWrapper},D._build=function(a){return this._generate(a,!0)},D._generate=function(a,c){var d,e=this,f=e.options,g=a.id,h=e._ui,i=y.classes;return e.options.items&&m(a,e.options.items),h.elSelect=a,h.page=w.getParentsByClass(a,i.uiPage)[0]||b.body,h.content=w.getParentsByClass(a,i.uiContent)[0]||w.getParentsByClass(a,i.uiHeader)[0],h.elDefaultOption=a.querySelector("option[data-placeholder='true']"),h.elDefaultOption&&a.selectedIndex>h.elDefaultOption.index?e._selectedIndex=a.selectedIndex-1:e._selectedIndex=a.selectedIndex,c&&(d=h.elDefaultOption||a[a.selectedIndex]||a.options.item(a.selectedIndex),e._buildWrapper(a),e._buildPlaceholder(a,h.elSelectWrapper,g,d?d.textContent:"")),e._setNativeMenu(a,f.nativeMenu),e._setInline(a,f.inline),a},D._buildWrapper=function(a){var b=this,c=b._createWrapper();c.className=C.selectWrapper,c.id=a.id+"-dropdownmenu",c.setAttribute("tabindex","0"),c.setAttribute("data-role","none"),u.insertNodesBefore(a,c),c.appendChild(a),b._ui.elSelectWrapper=c},D._buildPlaceholder=function(a,c,d,e){var f=b.createElement("span");f.id=d+"-placeholder",f.className=C.placeHolder,f.textContent=e,c.insertBefore(f,a),this._ui.elPlaceHolder=f},D._buildFilter=function(a,c){var d=this._ui,e=d.screenFilter,f=d.elOptionWrapper,g=d.elOptionContainer,h=b.createDocumentFragment();e||(e=b.createElement("div"),e.classList.add(C.filter,C.filterHidden),e.id=c+"-overlay",h.appendChild(e)),f||(f=b.createElement("div"),f.className=C.optionsWrapper,f.id=c+"-options-wrapper",h.appendChild(f)),g||(g=b.createElement("ul"),g.className=C.optionList,g.id=c+"-options",f.appendChild(g)),d.page.appendChild(h),d.elOptionContainer=g,d.elOptionWrapper=f,d.screenFilter=e},D._setNativeMenu=function(a,b){var c,d,e,f=this,g=f._ui,h=g.elSelectWrapper;b?(c=a.querySelectorAll("option"),h.classList.add(C["native"])):(f._buildFilter(a,a.id),d=g.elOptionContainer,e=f._constructOption(),d.innerHTML=e,c=d.querySelectorAll("li[data-value]"),c[f._selectedIndex]&&c[f._selectedIndex].classList.add(C.selected)),g.elOptions=c,f.options.nativeMenu=b},D._init=function(a){var c=this,d=c._ui,e=a.id;d.elSelectWrapper||(d.elSelectWrapper=b.getElementById(e+"-dropdownmenu"),d.elPlaceHolder=b.getElementById(e+"-placeholder"),d.elOptionWrapper=b.getElementById(e+"-options-wrapper"),d.elSelect=a,c.options.nativeMenu||(d.screenFilter=b.getElementById(e+"-overlay"),d.elOptionContainer=b.getElementById(e+"-options"),d.elOptions=d.elOptionContainer.querySelectorAll("li[data-value]")))},D._refresh=function(){var a=this;a._generate(a.element,!1)},D._enable=function(){k(this._ui.elSelectWrapper,!1),u.removeAttribute(this.element,"disabled")},D._disable=function(){k(this._ui.elSelectWrapper,!0),u.setAttribute(this.element,"disabled",!0)},D.open=function(){var a=this;a._isOpen===!1&&a._toggleSelect()},D.close=function(){var a=this;a._isOpen===!0&&a._toggleSelect()},D._bindEvents=function(){var b=this,c=b._ui,k=c.elOptionContainer,l=c.elSelectWrapper;b._toggleMenuBound=d.bind(null,b),b._changeOptionBound=e.bind(null,b),b._onResizeBound=g.bind(null,b),b._nativeChangeOptionBound=f.bind(null,b),b._focusBound=h.bind(null,b),b._blurBound=j.bind(null,b),b._touchMoveBound=i.bind(null,b),l.addEventListener("focus",b._focusBound),l.addEventListener("blur",b._blurBound),b.options.nativeMenu?c.elSelect.addEventListener("change",b._nativeChangeOptionBound):(l.addEventListener("vclick",b._toggleMenuBound),k.addEventListener("touchmove",b._touchMoveBound),k.addEventListener("vclick",b._changeOptionBound),k.addEventListener("focusin",b._focusBound),k.addEventListener("focusout",b._blurBound),c.screenFilter&&c.screenFilter.addEventListener("vmousedown",b._toggleMenuBound),a.addEventListener("throttledresize",b._onResizeBound,!0))},D._coordinateOption=function(){var b,c,d,e,f,g,h,i=this,j=i._ui,k=j.elOptionContainer.offsetHeight,l=[].slice.call(j.elOptionContainer.children).map(q),m=a.getComputedStyle(j.elOptionContainer),o=Math.max.apply(Math,l)+parseInt(m.borderLeftWidth,10)+parseInt(m.borderRightWidth,10),p=parseInt(a.getComputedStyle(j.elOptionWrapper).minWidth,10),r=i.options,s=j.elOptionWrapper.parentNode.querySelector(".ui-scrollview-clip").scrollTop,t=j.elSelectWrapper.parentNode,u=a.getComputedStyle(t),v=t.getBoundingClientRect(),x=0;return j.elSelectWrapper.classList.add("ui-dropdownmenu-force-display"),i._offsetTop=n(j.elSelectWrapper,j.page),j.elSelectWrapper.classList.remove("ui-dropdownmenu-force-display"),e=i._chooseDirection(),d=Math.max(o,p),g=k,c="right"===i._horizontalPosition?v.right-d:v.left,c+d>a.screen.width&&(c-=c+d-a.screen.width),f="left: "+c+"px; ",r.inline===!0&&(g=5*j.elOptionContainer.children[0].offsetHeight,h=t.offsetWidth-(parseFloat(u.paddingLeft)+parseFloat(u.paddingRight)),d=Math.min(h,Math.max(d,j.elOptionContainer.offsetWidth))),"top"===e.direction?(e.belowArea<0&&(x=e.belowArea),b=i._offsetTop-g-s+j.elPlaceHolder.offsetHeight,j.elOptionWrapper.classList.add(C.top)):(e.topArea<j.elPlaceHolder.offsetHeight&&(x=s%j.elPlaceHolder.offsetHeight),b=i._offsetTop-s<0?0:i._offsetTop-s,j.elOptionWrapper.classList.add(C.bottom)),b+=x,0==w.getParentsByTag(j.elSelect,"li").length&&j.elOptionWrapper.classList.add(C.verticalMargins),f+="top: "+b+"px; width: "+d+"px; max-height: "+g+"px;"},D._chooseDirection=function(){var a=this,b=a._ui,c={belowArea:0,topArea:0,direction:""};return c.belowArea=b.page.offsetHeight-a._offsetTop-b.elPlaceHolder.offsetHeight+b.content.scrollTop,c.topArea=a._offsetTop-b.content.scrollTop,c.belowArea<c.topArea&&b.elOptionContainer.offsetHeight>c.belowArea?c.direction="top":c.direction="bottom",c},D._toggleSelect=function(b){var c=this,d=c._ui,e=d.elOptionContainer,f=d.elOptionWrapper.classList;if(c._horizontalPosition=b&&b.clientX>a.screen.width/2?"right":"left",c._isOpen&&!f.contains(C.opening))f.remove(C.opened),c._callbacks.hideAnimationEnd=p.bind(null,c),v.prefixedFastOn(e,"animationEnd",c._callbacks.hideAnimationEnd,!1),c._hide();else{if(f.contains(C.closing)||f.contains(C.opening))return;d.elSelectWrapper.focus(),f.add(C.opening),c._callbacks.showAnimationEnd=o.bind(null,c),v.prefixedFastOn(e,"animationEnd",c._callbacks.showAnimationEnd,!1),c._show()}c._isOpen=!c._isOpen},D._hide=function(){var a=this,b=a._ui,c=a.options,d=b.elOptionWrapper;b.screenFilter&&b.screenFilter.classList.add(C.filterHidden),c.inline&&b.elSelectWrapper.style.removeProperty("width"),a._ui.elSelectWrapper.classList.remove(C.active),d.classList.add(C.closing),a.isKeyboardSupport&&a.enableDisabledFocusableElements(b.page)},D._show=function(){var a=this,b=a._ui,c=a.options,d=b.elOptionWrapper;d.setAttribute("style",a._coordinateOption()),b.screenFilter&&b.screenFilter.classList.remove(C.filterHidden),b.elSelectWrapper.classList.add(C.active),d.classList.add(C.active),c.inline&&(b.elSelectWrapper.style.width=d.offsetWidth+"px"),d.setAttribute("tabindex","0"),d.firstElementChild.focus(),a.isKeyboardSupport&&(a.disableFocusableElements(b.page),a.enableDisabledFocusableElements(d),s.focusElement(d))},D._changeOption=function(){var a=this,b=a._ui,c=b.elOptions[a._selectedIndex],d=b.elOptionContainer.querySelector("."+C.selected),e=u.getNSData;if(c!==d||b.elDefaultOption&&b.elPlaceHolder.textContent===b.elDefaultOption.textContent){if(b.elSelect.value=e(c,"value"),""===b.elSelect.value)return b.elSelect.value=e(d,"value"),void(b.elPlaceHolder.textContent=d.textContent);v.trigger(b.elSelect,"change"),d&&d.classList.remove(C.selected),c.classList.add(C.selected)}},D._getValue=function(){var a,b=this,c=b.element.options,d="";return c&&(a=c[b._selectedIndex],a&&(d=a.value)),d},D._destroy=function(){var b=this,c=b._ui,d=c.elSelectWrapper,e=c.elOptionContainer,f=c.screenFilter;d.removeEventListener("focus",b._focusBound),d.removeEventListener("blur",b._blurBound),u.replaceWithNodes(c.elSelectWrapper,c.elSelect),b.options.nativeMenu?c.elSelect.removeEventListener("change",b._nativeChangeOptionBound):(d.removeEventListener("vclick",b._toggleMenuBound),e.removeEventListener("touchmove",b._touchMoveBound),e.removeEventListener("vclick",b._changeOptionBound),e.removeEventListener("focusin",b._focusBound),e.removeEventListener("focusout",b._blurBound),c.elOptionWrapper.parentNode.removeChild(c.elOptionWrapper),f&&(f.removeEventListener("vmousedown",b._toggleMenuBound),f.parentNode.removeChild(f)),a.removeEventListener("throttledresize",b._onResizeBound,!0))},A.widgetSelector=B,c.widget.mobile.DropdownMenu=A,s.registerActiveSelector(".ui-dropdownmenu:not(.ui-disabled):not(.ui-dropdownmenu-disabled), .ui-dropdownmenu-options li:not(.ui-dropdownmenu-disabled):not(.ui-dropdownmenu-optiongroup):not(.ui-disabled)"),t.defineWidget("DropdownMenu",B,["open","close"],A,"mobile",!1,!1,HTMLSelectElement)}(a.document,d),function(a,d){function e(a){var b=a._ui.inputElement;b&&(i.on(b,"keyup",a),a.options.groupOnBlur&&i.on(b,"blur focus",a)),a.on("click",a)}function f(a){var b=a._ui.inputElement;b&&(i.off(b,"keyup",a),a.options.groupOnBlur&&i.off(b,"blur focus",a)),a.off("click",a)}var g=d.widget.mobile.BaseWidgetMobile,h=d.engine,i=d.event,j={TEXT_ENVELOPER:"ui-text-enveloper",WITH_CONTAINER:"ui-text-enveloper-with-container",CONTAINER:"ui-text-enveloper-container",TEXT_ENVELOPER_INPUT:"ui-text-enveloper-input",TEXT_ENVELOPER_BTN:"ui-text-enveloper-btn",BTN_SELECTED:"ui-text-enveloper-btn-selected",TEXT_ENVELOPER_BTN_ACTIVE:"ui-text-enveloper-btn-active",TEXT_ENVELOPER_BTN_BLUR:"ui-text-enveloper-btn-blur",TEXT_ENVELOPER_BTN_EXPANDED:"ui-text-enveloper-btn-expanded",TEXT_ENVELOPER_START:"ui-text-enveloper-start",TEXT_ENVELOPER_TEXTLINE:"ui-text-input-textline",SLASH:"ui-text-enveloper-slash",SLASH_HIDDEN:"ui-text-enveloper-slash-hidden",TEXT_ENVELOPER_BTN_SLASH:"ui-text-enveloper-btn-separator",INPUT_STYLE_PREFIX:"ui-text-enveloper-input-",INPUT_BLUR:"ui-text-enveloper-input-blur"},k={BACKSPACE:8,ENTER:13},l={NEW_VALUE:"newvalue",ADDED:"added",REMOVED:"removed",SELECT:"select",UNSELECT:"unselect",RESIZE:"resize",EXPAND:"expand",FOLD:"fold"},m=function(){var a=this;a.options={groupOnBlur:!0,label:null,link:"",description:"+ {0}",selectable:!1,input:!0,placeholder:null,labelPosition:null,selectedItems:null,items:null},a._ui={}},n=new g;m.prototype=n,m.classes=j,n._build=function(a){var b=this,c=b._ui,d=b.options;return a.classList.add(j.TEXT_ENVELOPER),b._setLabel(a,d.label),b._setLabelPosition(a,d.labelPosition),c.container.classList.add(j.CONTAINER),c.buttons=[],b._setInput(a,d.input),b._setPlaceholder(a,d.placeholder),a},n._setLabelPosition=function(a,c){var d,e=this,f=e._ui;"indent"===c?(d=b.createElement("div"),a.appendChild(d),f.container=d,a.classList.add(j.WITH_CONTAINER)):f.container=a,e.options.labelPosition=c},n._setLabel=function(a,c){var d=a.querySelector("."+j.TEXT_ENVELOPER_START),e=d?d.cloneNode(!0):null;e&&(a.removeChild(d),a.appendChild(e)),c&&(e=e||b.createElement("div"),e.innerText=c,e.classList.add(j.TEXT_ENVELOPER_START),a.appendChild(e)),this.options.label=c},n._init=function(a){var b=this;return b._btnActive=!1,b._isBlurred=!1,a},n._bindEvents=function(){e(this)},n.handleEvent=function(a){var b=this;switch(a.type){case"click":b._onClick(a);break;case"keyup":b._onKeyup(a);break;case"blur":b._onBlur(a);break;case"focus":b._onFocus(a)}},n._onFocus=function(){this.expandButtons()},n.expandButtons=function(){var a,b,c=this,d=c._ui;if(c._isBlurred){for(c._isBlurred=!1,c.remove(c._btnToRemoveIndex),d.inputContainer.classList.remove(j.INPUT_BLUR),a=d.buttons.length,b=0;a>b;b++)d.buttons[b].classList.remove(j.TEXT_ENVELOPER_BTN_BLUR);c.trigger(l.RESIZE),c.trigger(l.EXPAND)}},n._onClick=function(a){var b,c,d,e=this,f=a.target,g=f.classList,h=f.previousElementSibling,i=f.nextElementSibling,k=i&&i.nextElementSibling,m=h&&h.previousElementSibling;e._isBlurred?(e.expandButtons(),a.preventDefault(),a.stopPropagation()):e.options.selectable&&g.contains(j.TEXT_ENVELOPER_BTN)&&(b=h&&h.classList,c=i&&i.classList,g.contains(j.BTN_SELECTED)?(m&&!m.classList.contains(j.BTN_SELECTED)&&b.remove(j.SLASH_HIDDEN),k&&!k.classList.contains(j.BTN_SELECTED)&&c.remove(j.SLASH_HIDDEN),d=l.UNSELECT):(b&&b.add(j.SLASH_HIDDEN),c&&c.add(j.SLASH_HIDDEN),d=l.SELECT),g.toggle(j.BTN_SELECTED),e.trigger(d,{value:f.textContent,index:e._ui.buttons.indexOf(f)},!1),a.preventDefault(),a.stopPropagation())},n._getItems=function(){return this._ui.buttons.map(function(a){return a.textContent})},n._setItems=function(a,b){var c=this,d="string"==typeof b?b.split(","):b;d&&(this._ui.buttons.forEach(function(){c.remove(0)}),d.forEach(function(a){c.add(a)}))},n._getSelectedItems=function(){var a=[];return this._ui.buttons.forEach(function(b,c){b.classList.contains(j.TEXT_ENVELOPER_BTN_SELECTED)&&a.push({value:b.textContent,index:c})}),a},n._setSelectedItems=function(a,b){var c="string"==typeof b?b.split(","):b;c&&this._ui.buttons.forEach(function(a,b){a.classList.toggle(j.TEXT_ENVELOPER_BTN_SELECTED,-1!==c.indexOf(b))})},n._onBlur=function(){var a=this,b=a._ui.inputElement;b&&b.value&&(a.trigger(l.NEW_VALUE,{value:b.value},!1),b.value=""),a.foldButtons()},n.foldButtons=function(){var a,c,d,e,f=this,g=f._ui,h=g.buttons,i=h.length,k=h[0]?h[0].textContent:"";if(!f._isBlurred){for(a=0;i>a;a++)h[a].classList.add(j.TEXT_ENVELOPER_BTN_BLUR);g.inputContainer.classList.add(j.INPUT_BLUR),c=f._createButton(k,!1),f._btnToRemoveIndex=h.indexOf(c),i>1&&(d=b.createElement("span"),d.classList.add(j.TEXT_ENVELOPER_BTN_SLASH),e=b.createTextNode("+"+(i-1)),c.appendChild(d),c.appendChild(e)),f._isBlurred=!0,f.trigger(l.RESIZE),f.trigger(l.FOLD)}},n._onKeyup=function(a){var b=this,c=b._ui,d=c.inputElement,e=d.value,f=a.keyCode,g=c.buttons.length-1;f===k.ENTER?(b.trigger(l.NEW_VALUE,{value:e},!1),d.value="",b.trigger(l.RESIZE)):f===k.BACKSPACE?(""===e&&(b._btnActive?(b.remove(g),b._btnActive=!1):c.buttons.length&&(c.buttons[g].classList.add(j.TEXT_ENVELOPER_BTN_ACTIVE),b._btnActive=!0)),b.trigger(l.RESIZE)):b._btnActive&&(c.buttons[g].classList.remove(j.TEXT_ENVELOPER_BTN_ACTIVE),b._btnActive=!1)},n._createButton=function(a,d){var e=this,f=e._ui,g=b.createElement("div"),i=f.buttons;return d===c&&(d=!0),g.innerText=a,g.classList.add(j.TEXT_ENVELOPER_BTN),h.instanceWidget(g,"Button",{inline:d}),f.container.insertBefore(g,e._ui.inputContainer),i.push(g),e.trigger(l.ADDED,{value:a,index:i.length-1},!1),g},n._createSlash=function(){var a=this._ui,c=b.createElement("span");return c.classList.add(j.SLASH),a.container.insertBefore(c,a.inputContainer),c},n.add=function(a){var b=this,c=b._getItems(b.element);-1===c.indexOf(a)&&(b._createButton(a),b._createSlash())},n.remove=function(a){var b=this,c=b._ui,e=c.buttons,f=e.length,g=e[a].innerText,h=c.container,i=b._isBlurred?f-2:f-1;0>a||a>i?d.warn("You insert incorrect index, please check your index value"):b._isBlurred?f>2?e[f-1].textContent=e[0].textContent+" + "+(f-2):2===f&&(h.removeChild(e[f-1]),e.pop(),e[0].classList.remove(j.TEXT_ENVELOPER_BTN_BLUR)):(e[a].nextElementSibling.classList.contains(j.SLASH)&&h.removeChild(e[a].nextElementSibling),h.removeChild(e[a]),e.splice(a,1)),b.trigger(l.REMOVED,{value:g,index:a})},n.length=function(){return this._ui.buttons.length},n._setInput=function(a,c){var d,e,f,g=this,i=g._ui,k=i.container;c?(f=b.createElement("div"),d=b.createElement("input"),d.classList.add(j.TEXT_ENVELOPER_INPUT),f.appendChild(d),k.appendChild(f),h.instanceWidget(d,"TextInput",{clearBtn:!0}),i.inputElement=d,i.inputContainer=f,"string"==typeof c?f.classList.add(j.INPUT_STYLE_PREFIX+c):(e=a.querySelector("."+j.TEXT_ENVELOPER_TEXTLINE),e.parentElement.removeChild(e))):(f=i.inputContainer,f&&(k.removeChild(f),h.destroyWidget(i.inputElement,"TextInput"),i.inputContainer=null,i.inputElement=null)),g.options.input=c},n._setPlaceholder=function(a,b){var c=this._ui.inputElement;c&&c.setAttribute("placeholder",b||""),this.options.placeholder=b},n._destroy=function(){var a=this,b=a._ui;b.container.classList.remove(j.CONTAINER),a._setInput(a.element,!1),f(a),a._ui=null},n.getInput=function(){return this._ui.inputElement},d.widget.mobile.TextEnveloper=m,h.defineWidget("TextEnveloper","[data-role='textenveloper'], .ui-text-enveloper",["add","remove","length"],m,"mobile")}(a.document,d),function(a,b){function c(){var c,d=b.createElement("div"),e=b.createElement("body"),f=b.getElementsByTagName("html")[0],g=getComputedStyle(d);return d.classList.add("is-circle-test"),e.appendChild(d),f.insertBefore(e,f.firstChild),c="1px"===g.width,f.removeChild(e),"?circle"===a.location.search&&(c=!0),c}var e=!("undefined"==typeof a.tizen);d.support={cssTransitions:!0,mediaquery:!0,cssPseudoElement:!0,touchOverflow:!0,cssTransform3d:!0,boxShadow:!0,scrollTop:0,dynamicBaseTag:!0,cssPointerEvents:!1,boundingRect:!0,browser:{ie:!1,tizen:e},shape:{circle:e?a.matchMedia("(-tizen-geometric-shape: circle)").matches:c()},gradeA:function(){return!0},isCircleShape:c}}(a,a.document),function(a,b,c){function d(a,b,c,d){var e=d*n/180;return{x:a+c*p(e),y:b-c*o(e)}}function e(a,b,c,e,f){var g=d(a,b,c,f),h=d(a,b,c,e),i=180>=f-e?"0":"1",j=0;return["M",g.x,g.y,"A",c,c,0,i,j,h.x,h.y].join(" ")}function f(a,c){var d=b.createElementNS(q,"path");d.setAttribute("class",c.classes),d.setAttribute("fill","none"),d.setAttribute("stroke",c.color),d.setAttribute("stroke-width",c.width),d.setAttribute("d",e(c.x,c.y,c.r,c.referenceDegree+c.arcStart,c.referenceDegree+c.arcEnd)),d.setAttribute("data-initial-degree",c.referenceDegree),d.setAttribute("stroke-linecap",c.linecap),a.appendChild(d)}function g(a,b){var c=a.style,d=b.x+"px "+b.y+"px",e=b.referenceDegree+b.arcStart||b.degrees;a.classList&&a.classList.add(s.animated),c.webkitTransformOrigin=d,c.mozTransformOrigin=d,c.transformOrigin=d,d="rotate("+e+"deg)",c.webkitTransform=d,c.mozTransform=d,c.transform=d}function h(a,c){var e,f,g=b.createElementNS(q,"line");return g.setAttribute("class",c.classes),g.setAttribute("stroke",c.color),g.setAttribute("stroke-width",c.width),"out"===c.direction?(e=d(c.x,c.y,c.r,c.degrees),f=d(c.x,c.y,c.r-c.length,c.degrees)):(e=d(c.x,c.y,c.r-c.length,c.degrees),f=d(c.x,c.y,c.r,c.degrees)),g.setAttribute("x1",e.x),g.setAttribute("y1",e.y),g.setAttribute("x2",f.x),g.setAttribute("y2",f.y),a.appendChild(g),g}function i(a,c){var d=b.createElementNS(q,"text");d.setAttribute("x",c.x),d.setAttribute("y",c.y),d.setAttribute("text-anchor",c.position),d.setAttribute("fill",c.color),d.setAttribute("transform",c.transform),d.textContent=c.text,a.appendChild(d)}function j(a,c){var d=b.createElementNS(q,"circle");return d.setAttribute("stroke",c.color),d.setAttribute("stroke-width",c.width),d.setAttribute("cx",c.x),d.setAttribute("cy",c.y),d.setAttribute("r",c.r),d.setAttribute("fill",c.fill),a.appendChild(d),d}function k(a,b){var c;b.animation?g(a,b):a&&(c=parseInt(a.getAttribute("data-initial-degree"),10)||b.referenceDegree,a.setAttribute("data-initial-degree",c),a.setAttribute("d",e(b.x,b.y,b.r,c+b.arcStart,c+b.arcEnd)))}function l(a,b){var c,e;b.animation?g(a,b):a&&(c=d(b.x,b.y,b.r,b.degrees),e=d(b.x,b.y,b.r-b.length,b.degrees),a.setAttribute("x1",c.x),a.setAttribute("y1",c.y),a.setAttribute("x2",e.x),a.setAttribute("y2",e.y))}var m,n=Math.PI,o=Math.cos,p=Math.sin,q="http://www.w3.org/2000/svg",r=c.util.object,s={polar:"ui-polar",animated:"ui-animated"},t={x:180,y:180,r:170,arcStart:0,arcEnd:90,width:5,color:"black",animation:!1,linecap:"butt",referenceDegree:0},u={x:180,y:180,r:170,degrees:0,length:180,direction:"in",width:5,color:"black"},v={x:180,y:180,text:"Text",position:"middle",color:"white"},w={x:180,y:180,r:170,color:"white"};m={"default":{arc:t,radius:u,text:v},classes:s,polarToCartesian:d,createSVG:function(a){var c=b.createElementNS(q,"svg");return c.classList&&c.classList.add(s.polar),a&&a.appendChild(c),c},addArc:function(a,b){return a=a||this.createSVG(),b=r.merge({},t,b||{}),f(a,b),a},addRadius:function(a,b){return a=a||this.createSVG(),b=r.merge({},u,b||{}),h(a,b)},addText:function(a,b){return a=a||this.createSVG(),b=r.merge({},v,b||{}),i(a,b),a},updatePosition:function(a,b,c){var d,e=a&&a.querySelector("path"+b);e?(c=r.merge({},t,c||{}),k(e,c)):(d=a&&a.querySelector("line"+b),d&&l(d,c))},addCircle:function(a,b){var c=this;return a=a||c.createSVG(),b=r.merge({},w,b||{}),j(a,b),a}},c.util.polar=m}(a,a.document,d),function(a,b,c){function d(){ma&&(clearTimeout(ta),ma.classList.add(N.fadeIn),ta=setTimeout(function(){ma&&ma.classList.remove(N.fadeIn)},2e3))}function e(b){for(;b&&b!==a;){if(b===$)return!0;b=b.parentElement}return!1}function f(a){var b=a.touches,c=b[0];da=e(a.target),da&&1===b.length&&(R=ea?c.clientX:c.clientY,X=Date.now(),K.trigger($,P.SCROLL_BEFORE_START,{scrollLeft:ea?-S:0,scrollTop:ea?0:-S,fromAPI:ua}))}function g(a){var b=a.touches,c=b[0],e=ea?c.clientX:c.clientY,f=0,g=0;ua=!1,T=e-R,O||(S+T>0&&(T=-S),-Z>S+T&&(T=-Z-S)),ea?f=-(S+T):g=-(S+T),ca||K.trigger($,P.SCROLL_START,{scrollLeft:f,scrollTop:g,fromAPI:ua}),K.trigger($,P.SCROLL,{scrollLeft:f,scrollTop:g,inBounds:S+T>=-Z&&0>=S+T,fromAPI:ua}),d()}function h(a){var b=a.touches;da&&(1===b.length&&g(a),ca||(ca=!0),Ba(u))}function i(a){return xa?(a=ga(ha(xa.length-1,a),0),xa[a].position-xa[0].position):0}function j(a){var b,c,d=null,e=null;if(xa){if(a-=Aa/2,a=-a,xa[0].position>a)return 0;for(c=0,b=xa.length;b>c;c++)if(d=xa[c],e=xa[c+1],!e||d.position<a&&e.position>a)return c}return-1}function k(a){var b=Date.now()-X,c=null;a&&ba(T/b)>1?(V=ga(ha(fa(S+1e3*T/b),0),-Z),xa?(ya=j(S+1e3*T/b),c=xa[ya],c&&(V=-i(ya))):wa&&(V=wa*fa(V/wa)),ba(T/b)>1&&K.trigger($,P.SCROLL_FLICK,{scrollLeft:ea?-V:0,scrollTop:ea?0:-V,fromAPI:ua}),Ba(s)):(xa?(ya=j(S),c=xa[ya],c&&(V=-i(ya),Ba(s))):wa&&(V=wa*fa(S/wa),Ba(s)),ca=!1)}function l(a){O?a||(V=S>0?0:-Z,Ba(s)):(-Z>S&&(S=-Z),S>0&&(S=0))}function m(a){K.trigger($,P.SCROLL,a),K.trigger($,P.SCROLL_END,a)}function n(){var a,b=0,c=0;ca&&(S+=T,a=S>=-Z&&0>=S,k(a),l(a),ea?b=-S:c=-S,T=0,m({scrollLeft:b,scrollTop:c,inBounds:a,fromAPI:ua}),d(),da=!1,Ba(u))}function o(a){return xa?Math.abs(xa[za].position-xa[a].position):wa}function p(a){var b=a.getBoundingClientRect();return ea?b.width:b.height}function q(a){var b=a.detail&&a.detail.direction;(!$||p($))&&(za=ya,ca&&(T=0,ca=!1),"CW"===b?(ya++,xa&&ya>=xa.length&&(ya=xa.length-1),wa=-1*o(ya)):(ya--,xa&&0>ya&&(ya=0),wa=o(ya)),V+=wa,!xa&&wa&&(V=wa*fa(V/wa)),-Z>V&&(V=-Z),V>0&&(V=0),Ba(s),Ba(u),K.trigger($,P.SCROLL_START,{scrollLeft:ea?-V:0,scrollTop:ea?0:-V,fromAPI:!1}))}function r(){var a=V-S,b=ba(a);b>10?(S=fa(S+a/10),Ba(s)):b>2?(S=fa(S+a/2),Ba(s)):S=V,O||(-Z>S&&(S=-Z),S>0&&(S=0))}function s(){var a=0,b=0;$&&(r(),ea?a=-S:b=-S,K.trigger($,P.SCROLL,{scrollLeft:a,scrollTop:b,inBounds:S>=-Z&&0>=S,fromAPI:ua}),ca||K.trigger($,P.SCROLL_END,{scrollLeft:a,scrollTop:b,fromAPI:ua}),d())}function t(){qa?L.updatePosition(sa,"."+N.thumb,{arcStart:oa,arcEnd:oa+ra,r:Q}):na&&(ea?na.style.transform="translate("+oa+"px, 0)":na.style.transform="translate(0, "+oa+"px)")}function u(){var a=S+T+U;a!==W&&(W=a,oa=Z>-a?-a/Z*pa:pa,0>oa&&(oa=0),!va&&Y&&(Y.transform=ea?"translate("+W+"px, 0)":"translate(0, "+W+"px)"),t(),Ba(u))}function v(){R=0,S=0,oa=0,T=0,V=0,W=0,U=0,X=Date.now()}function w(d,e,g){var i,j,k,l;va=g,O=!1,wa=!1,$?c.warn("Scrolling exist on another element, first call disable method"):(ea="x"===e?1:0,ya=0,l=d.querySelector("div."+N.container),l?(_=l,_.style.transform=""):(_=a.createElement("div"),k=Array.prototype.slice.call(d.childNodes),k.forEach(function(a){(!c.support.shape.circle||M.matchesSelector(a,".ui-header:not(.ui-fixed), :not(.ui-footer)"))&&_.appendChild(a)}),d.insertBefore(_,d.firstElementChild),_.classList.add(N.container)),$=d,i=d.getBoundingClientRect(),j=_.getBoundingClientRect(),Z=fa(ea?j.width-i.width:j.height-i.height),Y=_.style,v(),aa=b.getComputedStyle(d).getPropertyValue("overflow"),d.style.overflow="hidden",a.addEventListener("touchstart",f,!1),a.addEventListener("touchmove",h,!1),a.addEventListener("touchend",n,!1),b.addEventListener("rotarydetent",q,!0))}function x(){B(),a.removeEventListener("touchstart",f,!1),a.removeEventListener("touchmove",h,!1),a.removeEventListener("touchend",n,!1),b.removeEventListener("rotarydetent",q,!0),$&&($.style.overflow=aa),Y=null,$=null,_=null,sa=null}function y(){var a=ea?0:90;ma.classList.add(N.circular),sa=L.createSVG(),L.addArc(sa,{arcStart:a-ia/2,arcEnd:a+ia/2,classes:N.path,width:10,r:Q,linecap:"round"}),L.addArc(sa,{referenceDegree:a-ia/2,arcStart:0,arcEnd:ra,classes:N.thumb,width:10,
+r:Q,linecap:"round"}),ma.appendChild(sa),$.parentElement.insertBefore(ma,$.nextSibling)}function z(b){var c,d,e,f=0,g=0;ma.classList.add(N.direction+"-"+(ea?"x":"y")),na=a.createElement("div"),e=na.style,na.classList.add(N.thumb),c=$.getBoundingClientRect(),d=_.getBoundingClientRect(),ea?(f=c.width-2*ka,b.width=f+"px",b.left=c.left+ka+"px",e.transform="translate3d("+oa+"px,0,0)",e.width=f/d.width*f+"px"):(g=c.height-2*ka,b.height=g+"px",b.top=c.top+ka+"px",e.transform="translate3d(0,"+oa+"px,0)",e.height=g/d.height*g+"px"),ma.appendChild(na),$.parentElement.insertBefore(ma,$.nextSibling),pa=ea?f-na.getBoundingClientRect().width:g-na.getBoundingClientRect().height}function A(){ma=a.createElement("div"),ma.classList.add(N.scrollbar),qa?y():z(ma.style)}function B(){ma&&(ma.parentElement.removeChild(ma),ma=null,na=null)}function C(a){V=a,ua=!0,K.trigger($,P.SCROLL_BEFORE_START,{scrollLeft:ea?-S:0,scrollTop:ea?0:-S,fromAPI:ua}),Ba(s),u()}function D(){return-S}function E(){return Z}function F(a,b){ya=a,U=b,S=-i(a),V=S,Ba(s),u()}function G(a){var b=$.getBoundingClientRect(),c=ea?"width":"height",d=b[c],e=ga(a-d,0);e!==Z&&(Z=e||Number.POSITIVE_INFINITY,ma&&(qa?(ra=ga(d/(Z+d)*ia,ja),pa=ia-ra,L.updatePosition(sa,"."+N.thumb,{arcStart:oa,arcEnd:oa+ra,r:Q})):(d-=2*ka,na.style[c]=d/(Z+d)*d+"px",pa=d-na.getBoundingClientRect()[c])))}function H(a){var b=a.length;xa=a,wa=null,b&&(Z=xa[b-1].position-xa[0].position+la)}function I(a){Aa=ea?$.getBoundingClientRect().height:$.getBoundingClientRect().width,Array.isArray(a)?H(a):(xa=null,wa=a,wa&&(Z=wa*fa(Z/wa)))}function J(a){return $===a}var K=c.event,L=c.util.polar,M=c.util.selectors,N={circular:"scrolling-circular",direction:"scrolling-direction",scrollbar:"scrolling-scrollbar",path:"scrolling-path",thumb:"scrolling-scrollthumb",fadeIn:"fade-in",container:"scrolling-container"},O=!1,P={SCROLL_BEFORE_START:"beforeScrollStart",SCROLL_START:"scrollStart",SCROLL_END:"scrollEnd",SCROLL_FLICK:"flick",SCROLL:"scroll"},Q=174,R=0,S=0,T=0,U=0,V=0,W=0,X=Date.now(),Y=null,Z=0,$=null,_=null,aa="",ba=Math.abs,ca=!1,da=!1,ea=0,fa=Math.round,ga=Math.max,ha=Math.min,ia=60,ja=6,ka=11,la=0,ma=null,na=null,oa=0,pa=0,qa=c.support.shape.circle,ra=ja,sa=null,ta=null,ua=!1,va=!1,wa=null,xa=null,ya=0,za=0,Aa=0,Ba=b.requestAnimationFrame||b.webkitRequestAnimationFrame;c.util.scrolling={getScrollPosition:D,getScrollPositionByIndex:i,enable:w,disable:x,enableScrollBar:A,disableScrollBar:B,scrollTo:C,setMaxScroll:G,getMaxScroll:E,setSnapSize:I,scrollToIndex:F,isElement:J,setBounceBack:function(a){O=a}}}(b,a,d),function(a,b){function d(a,b){for(var c=a._renderList,d=0,e=c.length;e>d;d+=4)"propset"===c[d]&&(c[d+1][c[d+2]]=c[d+3]);0===e&&b-a._lastRenderClearTimestamp>a._lastRenderClearTTL&&(a._lastRenderClearTimestamp=b,a._sizeMap.length=0,a._avgListItemSize=-1),c.length=0}function e(a,b){var c=a._scroll,d=q,e=a._ui.scrollview,f=c.lastPositionX,g=c.lastPositionY,h=e.scrollLeft,i=b&&b.detail&&b.detail.scrollTop||e.scrollTop;a._refreshScrollbar(),g>i&&(d=r),f>h&&(d=u),i>g&&(d=s),h>f&&(d=t),c.lastJumpY=Math.abs(i-g),c.lastJumpX=Math.abs(h-f),c.lastPositionX=h,c.lastPositionY=i,c.dir=d,c.clipHeight=e.clientHeight,c.clipWidth=e.clientWidth}function f(a,b){return parseInt(b===v?a.clientHeight:a.clientWidth,10)}function g(a,b){var c,d,e,g,h,i,j=a.element,k=a.options,m=a._scroll,n=k.dataLength,o=a._avgListItemSize,p=k.bufferSize,q=!1,r=D.call(j.children,l);for(c=k.orientation===v?m.clipHeight:m.clipWidth,-1===o&&(a._avgListItemSize=o=f(j,k.orientation)/p),e=Math.floor((p-Math.floor(c/o))/2),i=0>=b-e?0:b-e,i+p>=n&&(i=n-p,0>i&&(i=0),q=!0),d=b-i,a._loadData(i),x=!0,h=i*o,k.orientation===v?(q&&(h=a._ui.spacer.clientHeight),a._addToRenderList("propset",j.style,"margin-top",h+"px")):(q&&(h=a._ui.spacer.clientWidth),a._addToRenderList("propset",j.style,"margin-left",h+"px")),g=0;d>g;g+=1)h+=f(r[g],k.orientation);k.orientation===v?C.isElement(a._ui.scrollview)?C.scrollTo(h):a._ui.scrollview.scrollTop=h:a._ui.scrollview.scrollLeft=h,x=!1,a._currentIndex=i}function h(a){for(var b=a.firstElementChild;b;){if("LI"===b.tagName)return b;b=b.nextElementSibling}return null}function i(a,b,c,d,e,f,g){var i,j,k=D.call(b.children,l),m=0;if(f>0){for(j=g;j>0;j--)i=k.shift(),c.appendChild(i),a._updateListItem(i,e),b.appendChild(i),m+=d(i,e++);a._currentIndex+=g}else{for(j=g;j>0;j--)i=k.shift(),c.appendChild(i),a._updateListItem(i,e),b.insertBefore(i,h(b)),m-=d(i,e--);a._currentIndex-=g}return m}function j(a,b,c,d,e,f,g){var h,i=0===(2&d),j=1===(2&d),k=a._currentIndex;i&&(h=f+e,0>=k&&(a._currentIndex=k=0,h=0),k>=b-1&&(h=a._ui.spacer.clientHeight),0>h&&(h=0),a._addToRenderList("propset",c,"margin-top",h+"px")),j&&(h=g+e,0>=k&&(a._currentIndex=k=0,h=0),k>=b-1&&(h=a._ui.spacer.clientWidth),0>h&&(h=0),a._addToRenderList("propset",c,"margin-left",h+"px"))}function k(a,b){for(var c=0,d=a.length;--d>=0;)c+=a[d][b];return c}function l(a){return"LI"===a.tagName}function m(a,b,d,e){return a[e]===c&&(a[e]=b?d.clientWidth:d.clientHeight),a[e]}function n(a){var b,c,d,e,g=a.element,h=a._scroll,n=a.options,o=g.style,p=a._currentIndex,w=parseInt(n.bufferSize,10),x=n.dataLength,y=h.dir,z=h.lastPositionY,A=h.lastPositionX,B=parseInt(o.marginTop,10)||0,C=parseInt(o.marginLeft,10)||0,E=0,F=a._domBuffer,G=a._avgListItemSize,H=k(D.call(g.children,l),n.orientation===v?"clientHeight":"clientWidth"),I=a._sizeMap,J=0,K=0;switch(-1===G&&(a._avgListItemSize=G=f(g,n.orientation)/w),y){case q:break;case s:K=z-B,E=x-p-w;break;case r:K=B+H-(z+h.clipHeight),E=p;break;case u:K=A-C,E=x-p-w;break;case t:K=C+H-(A-h.clipWidth),E=p}K>0&&2>=H/K&&(b=K/G-(w-h.clipHeight/G)/5|0|0,b=Math.min(E,b),c=b/w|0,b%=w,d=y===s||y===u?1:-1,c>0&&(a._loadData(p+d*c*w),p=a._currentIndex,J+=d*c*w*G),e=p+(d>0?w:-1),J+=i(a,g,F,m.bind(null,I,2&y),e,d,b),j(a,x,o,y,J,B,C))}function o(a,b){var c=a._scroll;e(a,b),(c.lastJumpY>0||c.lastJumpX>0&&!x)&&(n(a),B.trigger(a.element,"vlistupdate"))}var p=b.widget.BaseWidget,q=-1,r=0,s=1,t=2,u=3,v="y",w="x",x=!1,y=b.util,z=y.requestAnimationFrame,A=y.selectors,B=b.event,C=b.util.scrolling,D=[].filter,E=function(){var b=this;return b._ui={scrollview:null,spacer:null,itemSize:0},b._scroll={direction:[0,0,0,0],dir:q,lastPositionX:0,lastPositionY:0,lastJumpX:0,lastJumpY:0,clipWidth:0,clipHeight:0},b.name="VirtualListview",b._currentIndex=0,b.options={bufferSize:100,dataLength:0,orientation:v,listItemUpdater:null,scrollElement:null,optimizedScrolling:!1},b._scrollEventBound=null,b._render=d.bind(null,this),b._renderList=[],b._sizeMap=[],b._domBuffer=a.createDocumentFragment(),b._lastRenderClearTimestamp=0,b._lastRenderClearTTL=1e4,b._avgListItemSize=-1,b},F=new p;E.classes={uiVirtualListContainer:"ui-virtual-list-container",spacer:"ui-virtual-list-spacer"},F._updateListItem=function(a,b){this.options.listItemUpdater(a,b)},F._setupScrollview=function(a,b){var c,d=A.getClosestByClass(a,"ui-scroller")||a.parentElement;return c=d.style,b===w?(c.overflowX="scroll",c.overflowY="hidden"):(c.overflowX="hidden",c.overflowY="scroll"),d},F._getScrollView=function(a,b){var c=null;return a.scrollElement&&(c="string"==typeof a.scrollElement?A.getClosestBySelector(b,"."+a.scrollElement):a.scrollElement),c||(c=this._setupScrollview(b,a.orientation)),c},F._build=function(b){var c,d,e,f=this,g=f._ui,h=E.classes,i=f.options,j=a.createElement("div");return b.style.position="relative",b.classList.add(h.uiVirtualListContainer),e=i.orientation.toLowerCase()===w?w:v,c=f._getScrollView(i,b),j.classList.add(h.spacer),d=j.style,d.display="block",d.position="static",e===w&&(d["float"]="left"),c.appendChild(j),g.spacer=j,g.scrollview=c,i.orientation=e,b},F._init=function(a){var c,d,e=this,f=e._ui,g=e.options,h=f.scrollview||e._getScrollView(g,a);g.dataLength<g.bufferSize&&(g.bufferSize=g.dataLength),g.bufferSize<1&&(g.bufferSize=1),c=a.getBoundingClientRect(),d=h.getBoundingClientRect(),e._initTopPosition=c.top-d.top,e._initLeftPosition=c.left-d.left,h.classList.add("ui-has-virtual-list"),f.spacer=f.spacer||h.querySelector("."+E.classes.spacer),f.scrollview=h,g.orientation=g.orientation.toLowerCase()===w?w:v,g.optimizedScrolling&&(C.enable(h,g.orientation),C.enableScrollBar()),b.util.rotaryScrolling&&b.util.rotaryScrolling.lock()},F._buildList=function(){var b,c,d=this,e=d.element,f=d.options,g="UL"===e.tagName||"OL"===e.tagName||"TAU-VIRTUALLISTVIEW"===e.tagName?"li":"div",h=f.bufferSize,i=d._domBuffer,j=f.orientation;for(c=0;h>c;++c)b=a.createElement(g),j===w&&(b.style["float"]="left"),d._updateListItem(b,c),i.appendChild(b);e.appendChild(i),this._refresh()},F._refresh=function(){this._refreshScrollbar()},F._loadData=function(a){var b=this,c=b.element.firstElementChild;if(b._currentIndex!==a){b._currentIndex=a;do b._updateListItem(c,a),++a,c=c.nextElementSibling;while(c)}},F._refreshScrollbar=function(){var a,b,c=this,d=c._currentIndex,e=c.element,f=c.options,g=c._ui,h=g.spacer.style;f.orientation===v?(a=parseFloat(e.clientHeight)||0,b=a/f.bufferSize*(f.dataLength-d),f.optimizedScrolling?C.setMaxScroll(b):c._addToRenderList("propset",h,"height",b-a+"px")):(a=parseFloat(e.clientWidth)||0,b=a/f.bufferSize*f.dataLength,f.optimizedScrolling?C.setMaxScroll(b):c._addToRenderList("propset",h,"width",a/f.bufferSize*(f.dataLength-1)-4/3*a+"px"))},F._addToRenderList=function(){var a=this,b=a._renderList;b.push.apply(b,arguments),z(a._render)},F._bindEvents=function(){var a=o.bind(null,this),b=this._ui.scrollview;b&&(b.addEventListener("scroll",a,!1),this._scrollEventBound=a)},F._destroy=function(){var a=this,b=a._ui.scrollview,c=a._ui.spacer,d=a.element,e=d.style;for(e.position="static",a.options.orientation===v?e.top="auto":e.left="auto",b&&(C.disable(b),b.removeEventListener("scroll",a._scrollEventBound,!1)),c.parentNode&&c.parentNode.removeChild(c);d.firstElementChild;)d.removeChild(d.firstElementChild)},F.scrollTo=function(a){var b=this;C.isElement(b._ui.scrollview)?C.scrollTo(a):b._ui.scrollview.scrollTop=a},F.scrollToIndex=function(a){0>a&&(a=0),a>=this.options.dataLength&&(a=this.options.dataLength-1),e(this),g(this,a)},F.draw=function(){this._buildList(),this.trigger("draw")},F.setListItemUpdater=function(a){this.options.listItemUpdater=a},E.prototype=F,b.widget.core.VirtualListview=E}(a.document,d),function(a,b,c){var d=c.widget.core.VirtualListview,e=c.engine,f=c.util,g=f.selectors,h=f.DOM.nsData,i=new d,j=i._init,k=i._refresh,l=i._updateListItem;i._init=function(a){var b=this;e.instanceWidget(a,"Listview"),null!==h(a,"row")&&c.warn("Row option in VirtualListview is deprecated and not supported. Use bufferSize option instead."),null!==h(a,"template")&&c.warn("Template option in VirtualListview is deprecated and not supported."),null!==h(a,"numItemData")&&c.warn("NumItemData option in VirtualListview is deprecated and not supported. Use dataLength option instead."),"function"!=typeof b.options.listItemUpdater&&c.warn(["ListItemUpdater in VirtualListview is not set.","Probably you use selector for automatic creation of this widget.","Selectors for this widget are deprecated and will be removed in future.","Use setListItemUpdater to set list item updater."].join(" ")),b._ui.listview=e.instanceWidget(a,"Listview"),j.call(b,a)},i._refresh=function(){this._ui.listview.refresh(),k.call(this)},i._setupScrollview=function(a){var b;return b=e.getBinding(g.getClosestByClass(a,"ui-scrollview-clip")),b.element},i._updateListItem=function(a,b){var d=this;"function"==typeof d.options.listItemUpdater?l.call(d,a,b):c.warn("List item updater must be a function. Using jQuery Template in VirtualListview is deprecated and is not supported")},i.create=function(){c.warn("VirtualListview.create() method is deprecated and no more supported. Use draw() method instead.")},d.prototype=i,c.widget.mobile.VirtualListview=d,c.engine.defineWidget("VirtualListview","[data-role='virtuallistview'],[data-role='virtuallist'], .ui-virtuallistview",["draw","setListItemUpdater","scrollTo","scrollToIndex","create"],d,"tizen")}(a,a.document,d),function(a,b){function d(a,b,c,d,e){var f=e._ui,g=f.edgeEffect||f.scrollview.querySelector("."+v.edgeEffect),h=g.style,i=q(p(a/8)-1,10);return"vertical"===b?(h.top="start"===c?"0":"auto",h.bottom="start"===c?"auto":"0"):(h.left="start"===c?"0":"auto",h.right="start"===c?"auto":"0"),e._edgeEffectGradientSize=i,h.boxShadow="0 0 0 "+i+"px "+u.replace("{1}",.5)+",0 0 0 "+2*i+"px "+u.replace("{1}",.4)+",0 0 0 "+3*i+"px "+u.replace("{1}",.3)+",0 0 0 "+4*i+"px "+u.replace("{1}",.2)+",0 0 0 "+5*i+"px "+u.replace("{1}",.1),0}function e(a){return l.getClosestByClass(a,"ui-scroller")||a.parentElement}function f(a,b){var c=null;return a.scrollElement&&(c="string"==typeof a.scrollElement?l.getClosestBySelector(b,"."+a.scrollElement):a.scrollElement),c||(c=e(b)),c}function g(a,b){return b.getAttribute("data-index")===""+a}function h(a,b,c){return c>a}function i(a,b){return-1===a.indexOf(b)}function j(a,b){var d,e,f,j=a.element,k=a._itemSize,l=a.options,m="vertical"===l.orientation?"scrollTop":"scrollLeft",n=b.detail&&b.detail[m],o=a._ui,p=o.scrollview.firstElementChild.style,q=0,t=l.dataLength,u=[],w=a._numberOfItems,x=0,y=l.infinite,z=0,A=0,B={scrollTop:0,scrollLeft:0},C=0,D=0;if(l.edgeEffect&&(b.detail&&!b.detail.inBounds?(C=0>n?n:n+a._containerSize-l.dataLength*a._itemSize,n=n-C+l.edgeEffect(C,l.orientation,0>n?"start":"end",n,a)):a._edgeEffectGradientSize>0?((o.edgeEffect||o.scrollview.querySelector("."+v.edgeEffect)).style.boxShadow="none",a._edgeEffectGradientSize=0):a._scrollviewWidget&&a._scrollviewWidget.hideBouncingEffect()),n!==c){if(a._scrollBegin=n,z=r(n/a._itemSize),z!==r(a._scrollBeginPrev/a._itemSize)&&z>=0){for(n<a._itemSize?(q=0,A=0):z>t-w&&!y?(q=t-w,A=k*(z-q)):(q=z-1,A=k),x=q;q+w>x;++x)u[x-q]=s.call(j.children,g.bind(null,x%t))[0];for(d=s.call(j.children,i.bind(null,u)),x=q+w-1;x>=q;--x)D=x%t,(x>=0&&t>x||y)&&(u[x-q]||(e=d.shift(),u[x-q]=e,e&&(a._updateListItem(e,D),x-q===w-1||q>D&&n>a._scrollBeginPrev?j.appendChild(e):(f=u.filter(h.bind(null,x-q))[0],f?j.insertBefore(e,f):j.insertBefore(e,j.firstElementChild)))));B[m]=A+n%a._itemSize}else n>=0?n<a._itemSize?B[m]=n%k:z>t-w&&!y?(q=t-w,A=k*(z-q),B[m]=A+n%k):B[m]=k+n%k:B[m]=n;p.webkitTransform="translate("+-B.scrollLeft+"px, "+-B.scrollTop+"px)",a._scrollBeginPrev=n,a._snapListviewWidget&&a._snapListviewWidget.refresh()}}var k=b.widget.BaseWidget,l=b.util.selectors,m=b.util.scrolling,n=b.support.shape.circle,o=function(){var a=this;a.options={dataLength:0,listItemUpdater:null,scrollElement:null,orientation:"vertical",snap:!1,edgeEffect:n?null:d,infinite:!1},a._ui={edgeEffect:null,scrollview:null},a._scrollBegin=0,a._elementsMap=[],a._itemSize=0,a._numberOfItems=5,a._edgeEffectGradientSize=0},p=Math.abs,q=Math.min,r=Math.floor,s=Array.prototype.filter,t=new k,u="rgba(61, 185, 204, {1})",v={uiVirtualListContainer:"ui-virtual-list-container",edgeEffect:"ui-virtual-list-edge-effect"};o.classes=v,t._build=function(a){var b,c,d=this,e=d._ui,g=o.classes,h=d.options;return a.classList.add(g.uiVirtualListContainer),c="horizontal"===h.orientation.toLowerCase()?"horizontal":"vertical",b=f(h,a),e.scrollview=b,h.orientation=c,a},t._buildList=function(){var c,e,f,g=this,h=g._ui,i=g.options,j=g._ui.scrollview,k="vertical"===i.orientation?"height":"width",n=g.element,o="UL"===n.tagName||"OL"===n.tagName?"li":"div",p=g._numberOfItems,q=l.getClosestBySelector(n,".ui-content").getBoundingClientRect(),r=null,s=[].reduce.call(j.children,function(a,b){return a+b.getBoundingClientRect()[k]},0),t=b.support.shape.circle;for(e=b.engine.getBinding(l.getClosestBySelector(n,".ui-page"),"Scrollview"),e&&(e.option("bouncingEffect",!1),g._scrollviewWidget=e,i.edgeEffect=function(a,b,c){e.showBouncingEffect(c)}),i.dataLength<p&&(p=i.dataLength),f=0;p>f;++f)c=a.createElement(o),g._updateListItem(c,f),n.appendChild(c),r=g.element.getBoundingClientRect(),r[k]<q[k]&&p++;i.snap&&t&&(g._snapListviewWidget=b.engine.instanceWidget(n,"SnapListview",i.snap)),r=g.element.getBoundingClientRect(),g._itemSize=p>0?Math.round(r[k]/p):0,g._numberOfItems=p,g._containerSize=q[k],g._numberOfVisibleElements=Math.ceil(q[k]/g._itemSize),m.enable(j,"horizontal"===i.orientation?"x":"y",!0),i.infinite?m.setMaxScroll(null):(m.enableScrollBar(),j.classList.contains("ui-scroller")?m.setMaxScroll((i.dataLength+1)*g._itemSize+s):m.setMaxScroll(i.dataLength*g._itemSize)),i.snap&&t&&m.setSnapSize(g._itemSize),i.edgeEffect===d&&(h.edgeEffect=a.createElement("div"),h.edgeEffect.classList.add(v.edgeEffect,"orientation-"+i.orientation),h.scrollview.appendChild(h.edgeEffect)),m.setBounceBack(!0)},t._updateListItem=function(a,b){a.setAttribute("data-index",b),this.options.listItemUpdater(a,b)},t._refresh=function(){var a=this;a._buildList(),a._snapListviewWidget&&a._snapListviewWidget.refresh(),a.trigger("draw")},t.draw=function(){this.refresh()},t.scrollTo=function(a){m.scrollTo(-a)},t.scrollToIndex=function(a){this.scrollTo(Math.floor(this._itemSize*a))},t._bindEvents=function(){var a=j.bind(null,this),b=this._ui.scrollview;b&&(b.addEventListener("scroll",a,!1),this._scrollEventBound=a)},t._destroy=function(){m.disable()},t.setListItemUpdater=function(a){this.options.listItemUpdater=a,this.refresh()},o.prototype=t,b.engine.defineWidget("VirtualListviewSimple","",["draw","setListItemUpdater","scrollTo","scrollToIndex"],o,"",!0),b.widget.core.VirtualListviewSimple=o}(a.document,d),function(a,b,d){var e=d.widget.mobile.VirtualListview,f=e.prototype,g=d.engine,h=d.util.DOM,i=d.util.object.merge,j="x",k="y",l={WRAP_BLOCK_Y:"ui-virtualgrid-wrapblock-y",WRAP_BLOCK_X:"ui-virtualgrid-wrapblock-x",ITEM:"virtualgrid-item"},m=function(){return this},n=new e;n._configure=function(){var a=this;"function"==typeof f._configure&&f._configure.apply(a,arguments),a.options=i({},a.options,{numItemData:0,direction:k,row:50,itemsPerLine:1,listItemUpdater:null,standalone:!1}),a._ui=i({},a._ui),a._currentIndex=0},n._build=function(a){return"function"==typeof f._build&&f._build.apply(this,arguments),this.options.direction===j&&(a.style.height="100%"),a},n._setLineSize=function(){var a,c,d,e,f=this,g=f.options,i=b.createElement("div"),j=f.element;j.appendChild(i),f._updateListItem(i,0),a=i.firstElementChild,c=a.firstElementChild,g.direction===k?(a.style.width="",a.style["float"]="none",d=h.getElementWidth(c,"outer",!0,!0),g.lineSize=a.offsetHeight,e=j.offsetWidth):(d=i.offsetHeight,e=g.standalone?f._ui.scrollview.element.offsetHeight:j.offsetHeight,g.lineSize=a.offsetWidth),j.removeChild(i),g.itemsPerLine=Math.max(Math.floor(e/d),1),g.rawNumItemData=g.numItemData,g.numItemData=Math.ceil(g.numItemData/g.itemsPerLine)},n._configureList=function(a){var b=this,c=b.options,d=a[0]||{};"function"!=typeof d.itemData||"function"!=typeof d.numItemData&&"number"!=typeof d.numItemData||("function"==typeof d.numItemData?c.numItemData=d.numItemData():c.numItemData=d.numItemData<=0?0:d.numItemData,b.itemData=d.itemData),c.direction=d.direction||c.direction,c.row=Math.max(20,c.row),b._setLineSize(),b._buildList(),c.standalone&&b._updateScrollInfo()},n._updateListItem=function(a,d){var e,f,h,i=this,j=i.options,m=j.listItemUpdater,n=j.direction,o=i.itemData,p=i._ui.$jqTmpl,q=j.itemsPerLine,r=j.rawNumItemData,s=100/q+"%",t=q*d,u=0;for(a.innerHTML="",f=b.createDocumentFragment(),h=t+u;q>u&&(r===c||r>h);)e=b.createElement("div"),e.style[n===k?"width":"height"]=s,e.classList.add(l.ITEM),"function"==typeof m?m(e,h):e.appendChild($.tmpl(p,o(h))[0]),f.appendChild(e),u++,h=t+u;a.appendChild(f),g.createWidgets(a),j.lineSize&&(a.style[n===k?"height":"width"]=j.lineSize+"px"),a.classList.add(n===k?l.WRAP_BLOCK_Y:l.WRAP_BLOCK_X)},m.classes=l,m.prototype=n,d.widget.mobile.VirtualGrid=m,g.defineWidget("VirtualGrid","[data-role=virtualgrid], .ui-virtualgrid",["create"],m,"mobile")}(a,a.document,d),function(a,d,e){var f=d.widget.mobile.BaseWidgetMobile,g=d.engine,h=d.util.object,i=function(){var a=this;a.action="",a.label=null,a.defaultHtml="",a.options=h.copy(i.prototype.options)},j={uiLoader:"ui-loader",uiLoaderPrefix:"ui-loader-",uiCorner:"ui-corner-all",uiIcon:"ui-icon",uiLoaderIcon:"ui-icon-loading",uiLoading:"ui-loading",uiTextOnly:"ui-loader-textonly"},k={pageLoadErrorMessageTheme:"e",pageLoadErrorMessage:"Error Loading Page"},l=new f;i.classes=j,i.properties=k,l.options={textVisible:!1,html:"",text:"loading"},l._build=function(a){var c=this.options,d=b.createElement("span"),e=b.createElement("h1"),f=a.classList,g=d.classList;return e.textContent=c.text,g.add(j.uiIcon),g.add(j.uiLoaderIcon),a.appendChild(d),a.appendChild(e),f.add(j.uiLoader),f.add(j.uiCorner),f.add(j.uiLoaderPrefix+"default"),this.defaultHtml=a.innerHTML,a},l._init=function(a){return this.defaultHtml=a.innerHTML,a},l.resetHtml=function(a){a=a||this.element,a.innerHTML=this.defaultHtml},l.show=function(a,d,f){var g,j,k=i.classes,l=this,m=l.element,n=m.classList,o={},p={};l.resetHtml(m),a!==c&&a.constructor===Object?(o=h.copy(l.options),p=h.merge(o,a),a=p.theme||e.mobile.loadingMessageTheme):(p=l.options,a=a||e.mobile.loadingMessageTheme||p.theme),j=d||e.mobile.loadingMessage||p.text,b.documentElement.classList.add(k.uiLoading),e.mobile.loadingMessage!==!1||p.html?(g=e.mobile.loadingMessageTextVisible!==c?e.mobile.loadingMessageTextVisible:p.textVisible,m.className="",n.add(k.uiLoader),n.add(k.uiCorner),n.add(k.uiBodyPrefix+a),n.add(k.uiLoaderPrefix+(g||d||a.text?"verbose":"default")),(p.textonly!==c&&p.textonly||f)&&n.add(k.uiTextOnly),p.html?m.innerHTML=p.html:m.getElementsByTagName("h1")[0].textContent=j):m.getElementsByTagName("h1")[0].innerHTML=""},l.hide=function(){var a=i.classes;b.documentElement.classList.remove(a.uiLoading)},i.prototype=l,d.widget.mobile.Loader=i,g.defineWidget("Loader","[data-role='loader'], .ui-loader",["show","hide","resetHtml"],i,"mobile")}(a.document,d,a.$),function(b,d){var e=d.widget.BaseWidget,f=d.util.selectors,g=d.util.DOM,h=d.event,i=d.history,j=d.event.gesture,k=d.widget.core.Page,l={CLOSED:"closed",OPENED:"opened",SLIDING:"sliding",SETTLING:"settling"},m={OPEN:"draweropen",CLOSE:"drawerclose"},n={WIDTH:240,HEIGHT:360,DURATION:300,POSITION:"left"},o=function(){var a=this;a.options={position:n.POSITION,width:n.WIDTH,height:n.HEIGHT,duration:n.DURATION,closeOnClick:!0,overlay:!0,drawerTarget:"."+k.classes.uiPage,enable:!0,dragEdge:1},a._pageSelector=null,a._isDrag=!1,a._state=l.CLOSED,a._settlingType=l.CLOSED,a._translatedX=0,a._translatedY=0,a._ui={},a._eventBoundElement=null,a._drawerOverlay=null},p={page:k.classes.uiPage,drawer:"ui-drawer",left:"ui-drawer-left",right:"ui-drawer-right",up:"ui-drawer-up",down:"ui-drawer-down",overlay:"ui-drawer-overlay",open:"ui-drawer-open",close:"ui-drawer-close"},q=new e;o.prototype=q,o.classes=p,q._unbindDragEvents=function(b,c){var d=b._ui.drawerOverlay;h.disableGesture(c),h.off(c,"drag dragstart dragend dragcancel swipe swipeleft swiperight swipe vmouseup",b,!1),h.prefixedFastOff(b.element,"transitionEnd",b,!1),h.off(a,"resize",b,!1),d&&h.off(d,"vclick",b,!1)},q._bindDragEvents=function(b,c){var d=b._ui.drawerOverlay;b._eventBoundElement=c,h.enableGesture(c,new j.Drag,new j.Swipe({orientation:"left"===b.options.position||"right"===b.options.position?j.Orientation.HORIZONTAL:j.Orientation.VERTICAL})),h.on(c,"drag dragstart dragend dragcancel swipe swipeleft swiperight swipeup swipedown vmouseup",b,!1),h.prefixedFastOn(b.element,"transitionEnd",b,!1),h.on(a,"resize",b,!1),d&&h.on(d,"vclick",b,!1)},q.handleEvent=function(a){var b=this;switch(a.type){case"drag":b._onDrag(a);break;case"dragstart":b._onDragStart(a);break;case"dragend":b._onDragEnd(a);break;case"dragcancel":b._onDragCancel(a);break;case"vmouseup":b._onMouseup(a);break;case"swipe":case"swipeleft":case"swiperight":case"swipeup":case"swipedown":b._onSwipe(a);break;case"vclick":b._onClick(a);break;case"transitionend":case"webkitTransitionEnd":case"mozTransitionEnd":case"oTransitionEnd":case"msTransitionEnd":b._onTransitionEnd(a);break;case"resize":b._onResize(a)}},q._onMouseup=function(){var a=this;a._state===l.SLIDING&&a.close()},q._onClick=function(){var a=this;a._state===l.OPENED&&a.close()},q._onResize=function(){var a=this;a._refresh()},q._onTransitionEnd=function(){var a=this,b=a.options.position,c=a._drawerOverlay;a._state===l.SETTLING&&(a._settlingType===l.OPENED?(a.trigger(m.OPEN,{position:b}),a._setActive(!0),a._state=l.OPENED):(a.close(),a.trigger(m.CLOSE,{position:b}),a._setActive(!1),a._state=l.CLOSED,c&&(c.style.visibility="hidden")))},q._onSwipe=function(a){var b,c=this,d=c.options;if(a.detail)switch(a.detail.direction){case"left":b="right";break;case"right":b="left";break;case"up":b="down";break;case"down":b="up"}else"swiperight"===a.type?b="left":"swipeleft"===a.type?b="right":"swipeup"===a.type?b="down":"swipedown"===a.type&&(b="up");d.enable&&c._isDrag&&d.position===b&&(c.open(),c._isDrag=!1)},q._onDragStart=function(a){var b=this;b._state!==l.OPENED&&(b.options.enable&&!b._isDrag&&b._state!==l.SETTLING&&b._checkSideEdge(a)?b._isDrag=!0:b.close())},q._onDrag=function(b){var c,d,e=this,f=b.detail.deltaX,g=b.detail.deltaY,h=e.options,i=e._translatedX,j=e._translatedY;if(h.enable&&e._isDrag&&e._state!==l.SETTLING)switch(h.position){case"left":c=-h.width+f+i,0>c&&e._translate(c,0,0);break;case"right":c=a.innerWidth+f-i,c>0&&c>a.innerWidth-h.width&&e._translate(c,0,0);break;case"up":d=-h.height+g+j,0>d&&e._translate(0,d,0);break;case"down":d=a.innerHeight+g-j,d>0&&d>a.innerHeight-h.height&&e._translate(0,d,0)}},q._onDragEnd=function(a){var b=this,c=b.options,d=a.detail;c.enable&&b._isDrag&&(("left"===c.position||"right"===c.position)&&(Math.abs(d.deltaX)>c.width/2?b.open():b._state!==l.SETTLING&&b.close()),("up"===c.position||"down"===c.position)&&(Math.abs(d.deltaY)>c.height/2?b.open():b._state!==l.SETTLING&&b.close())),b._isDrag=!1},q._onDragCancel=function(){var a=this;a.options.enable&&a._isDrag&&a.close(),a._isDrag=!1},q._translate=function(a,b,c){var d=this,e=d.element;d._state!==l.SETTLING&&(d._state=l.SLIDING),c&&g.setPrefixedStyle(e,"transition",g.getPrefixedValue("transform "+c/1e3+"s ease-out")),g.setPrefixedStyle(e,"transform","translate3d("+a+"px, "+b+"px, 0px)"),d.options.overlay&&d._setOverlay(a,b),c||d._onTransitionEnd()},q._setOverlayOpacity=function(a){this._ui.drawerOverlay.style.opacity=1-a},q._setOverlayVisibility=function(a){var b=this._ui.drawerOverlay.style;1>a?b.visibility="visible":b.visibility="hidden"},q._calcOverlay=function(b,c){var d,e=this.options,f=Math.abs(b),g=Math.abs(c);return"right"===e.position?d=f/a.innerWidth:"left"===e.position?d=f/e.width:"down"===e.position?d=g/a.innerHeight:"up"===e.position&&(d=g/e.height),d},q._setOverlay=function(a,b){var c=this,d=c._calcOverlay(a,b);c._setOverlayVisibility(d),c._setOverlayOpacity(d)},q._setActive=function(a){var b=this,c=d.router.Router.getInstance().getRoute("drawer");a?c.setActive(b):c.setActive(null)},q._build=function(a){var c,d=this,e=d._ui,g=d.options;return a.classList.add(p.drawer),a.style.top=0,c=f.getClosestBySelector(a,g.drawerTarget),c&&(c.appendChild(a),c.style.overflowX="hidden"),d.options.overlay&&(e.drawerOverlay=d._createOverlay(a),e.drawerOverlay.style.visibility="hidden"),e.placeholder||(e.placeholder=b.createComment(a.id+"-placeholder"),a.parentNode.insertBefore(e.placeholder,a)),e.targetElement=c,a},q._init=function(a){var b=this,c=b._ui;return c.drawerPage=f.getClosestByClass(a,p.page),c.drawerPage.style.overflowX="hidden",b._initLayout(),a},q._initLayout=function(){var b=this,c=b.options,d=b.element,e=d.style,f=b._ui,g=f.drawerOverlay?f.drawerOverlay.style:null;c.width=c.width||f.targetElement.offsetWidth,c.height=c.height||f.targetElement.offsetHeight,e.width=0!==c.width?c.width+"px":"100%",e.height=0!==c.height?c.height+"px":"100%",e.top="0",g&&(g.width=a.innerWidth+"px",g.height=a.innerHeight+"px",g.top=0),"right"===c.position?(d.classList.add(p.right),b._translate(a.innerWidth,0,0)):"left"===c.position?(d.classList.add(p.left),b._translate(-c.width,0,0)):"up"===c.position?(d.classList.add(p.up),b._translate(0,-a.innerHeight,0)):"down"===c.position&&(d.classList.add(p.down),b._translate(0,c.height,0)),b._state=l.CLOSED},q._translateRight=function(){var b=this,c=b.options;"right"===c.position&&(b._state===l.OPENED?b._translate(a.innerWidth-c.width,0,0):b._translate(a.innerWidth,0,0))},q._checkSideEdge=function(a){var b=this,c=a.detail,d=c.pointer.clientX-c.estimatedDeltaX,e=c.pointer.clientY-c.estimatedDeltaY,f=b.options,g=f.position,h=b._eventBoundElement,i=h.offsetWidth,j=h.offsetHeight,k=h.offsetLeft+i,l=h.offsetTop+j,m=i*f.dragEdge,n=j*f.dragEdge;return"left"===g&&d>0&&m>d||"right"===g&&d>k-m&&k>d||"up"===g&&e>0&&n>e||"down"===g&&e>l-n&&l>e},q._refresh=function(){var a=this;a._translateRight(),a._initLayout()},q._createOverlay=function(a){var c=b.createElement("div");return c.classList.add(p.overlay),a.parentNode.insertBefore(c,a),c},q._bindEvents=function(){var a=this,b=a._ui.targetElement;a._bindDragEvents(a,b)},q._unbindEvents=function(){var a=this,b=a._ui.targetElement;a._unbindDragEvents(a,b)},q._enable=function(){this._oneOption("enable",!0)},q._disable=function(){this._oneOption("enable",!1)},q.isOpen=function(){return this._state===l.OPENED},q.open=function(b){var d=this,e=d.options,f=d.element.classList,g=d._ui.drawerOverlay;d._state!==l.OPENED&&(d._state=l.SETTLING,d._settlingType=l.OPENED,b=b!==c?b:e.duration,g&&(g.style.visibility="visible"),f.remove(p.close),f.add(p.open),"left"===e.position?d._translate(0,0,b):"right"===e.position?d._translate(a.innerWidth-e.width,0,b):"up"===e.position?d._translate(0,0,b):"down"===e.position&&d._translate(0,a.innerHeight-e.height,b))},q.close=function(b,e){var f=this,g=b?b.reverse:!1,h=f.options,j=f.element.classList;if(f._state!==l.CLOSED){if(!g&&f._state===l.OPENED&&!d.getConfig("disableRouter"))return void i.back();f._state=l.SETTLING,f._settlingType=l.CLOSED,e=e!==c?e:h.duration,j.remove(p.open),j.add(p.close),"left"===h.position?f._translate(-h.width,0,e):"right"===h.position?f._translate(a.innerWidth,0,e):"up"===h.position?f._translate(0,-h.height,e):"down"===h.position&&f._translate(0,a.innerHeight,e)}},q.setDragHandler=function(a){var b=this;b.options.dragEdge=1,b._unbindDragEvents(b,b._eventBoundElement),b._bindDragEvents(b,a)},q.transition=function(a){var b=this,c=b.options;"left"===c.position?(b._translate(-c.width+a,0,c.duration),b._translatedX=a):"right"===c.position&&(b._translate(c.width-a,0,c.duration),b._translatedX=a),"up"===c.position?(b._translate(0,-c.height+a,c.duration),b._translatedY=a):"down"===c.position&&(b._translate(0,c.height-a,c.duration),b._translatedY=a)},q.getState=function(){return this._state},q._destroy=function(){var a=this,b=a._ui,c=b.drawerOverlay,d=b.placeholder,e=d.parentNode,f=a.element;e.insertBefore(f,d),e.removeChild(d),c&&c.removeEventListener("vclick",a._onClickBound,!1),a._unbindEvents()},o.STATE=l,d.widget.core.Drawer=o}(a.document,d),function(b,c){var d=c.widget.core.Drawer,e=c.engine,f=function(){d.call(this)},g=new d;f.prototype=g,g._configure=function(){var b=this;b.options.dragEdge=.05,b.options.width=a.screen.width>=960?360:.75*a.screen.width,b.options.height=a.screen.height},c.widget.mobile.Drawer=f,e.defineWidget("Drawer","[data-role='drawer'], .ui-drawer",["transition","setDragHandler","open","close","isOpen","getState"],f,"mobile")}(a.document,d),function(a,b){var c=b.engine,d=b.widget.core.OnOffSwitch,e=function(){d.call(this,arguments)},f=b.widget.core.BaseKeyboardSupport,g="input[data-role='toggleswitch'],select[data-role='toggleswitch'],select.ui-toggleswitch,input.ui-toggleswitch";e.prototype=new d,b.widget.mobile.ToggleSwitch=e,c.defineWidget("ToggleSwitch",g,[],e,"mobile"),f.registerActiveSelector(g)}(a.document,d),function(a,b){function d(a){var b=this,c=i.getClosestByClass(a.target,l.NAVIGATION_ITEM),d=c&&parseInt(c.getAttribute(k.POSITION),10),e=b._navigationStack,f=e[d],g=e.length-1-d;c&&setTimeout(function(){c.classList.contains(l.NAVIGATION_ACTIVE)||e[e.length-1]===f||(b.pop(g),b.trigger("navigate",{id:f,position:d}))},0)}var e=b.widget.mobile.BaseWidgetMobile,f=b.widget.core.BaseKeyboardSupport,g=b.engine,h=b.event,i=b.util.selectors,j=function(){
+var a=this;f.call(this),a._clickBound=null,a._ui={},a._navigationStack=[]},k={POSITION:"data-position"},l={NAVIGATION:"ui-navigation",NAVIGATION_CONTAINER:"ui-navigation-container",NAVIGATION_ITEM:"ui-navigation-item",NAVIGATION_ACTIVE:"ui-navigation-active",NAVIGATION_HIDE:"ui-navigator-hide",NAVIGATION_BACK:"ui-navigator-back",NAVIGATION_BACK_HIDE:"ui-navigator-back-hide",NAVIGATION_ACTIVE_ANIMATION:"ui-navigator-active-animation"},m=new e;j.prototype=m,j.classes=l,j.attributes=k,m._build=function(b){var c;return b.classList.add(l.NAVIGATION),c=a.createElement("ul"),c.classList.add(l.NAVIGATION_CONTAINER),this._ui.container=c,b.appendChild(c),b},m._bindEvents=function(a){var b=this;b._clickBound=d.bind(b),a.addEventListener("vclick",b._clickBound,!1)},m.create=function(){b.warn("Create method is deprecated because with 'create' method,it is hard to meet the newly changed Navigation function. To handle Navigation Bar, please utilize 'push' method with and 'panelChanger' component, instead.")},m.pop=function(a){var b=this,d=b._ui.container,e=b._navigationStack,f=d.lastChild,g=f&&f.classList,i=f&&f.previousElementSibling&&f.previousElementSibling.classList;a===c&&(a=1),g&&(g.add(l.NAVIGATION_HIDE),i&&(i.add(l.NAVIGATION_BACK),i.add(l.NAVIGATION_ACTIVE),h.one(f,"animationend, webkitAnimationEnd",function(){d.removeChild(d.lastChild),g.remove(l.NAVIGATION_BACK),a>1&&b.pop(a-1)})),e.pop())},m.push=function(b){var c,d,e,f=this,g=f.element,i=f._navigationStack,j=f._ui.container,m=j.childElementCount,n=j.lastElementChild,o=n&&n.classList,p=null;i.push(b),m>0&&(o.add(l.NAVIGATION_BACK_HIDE),h.one(n,"animationend webkitAnimationEnd",function(){n!==f._ui.container.lastElementChild&&(o.remove(l.NAVIGATION_BACK_HIDE),o.remove(l.NAVIGATION_ACTIVE))})),c=a.createElement("li"),c.setAttribute(k.POSITION,m),p=c.classList,p.add(l.NAVIGATION_ITEM),m>0&&(d=a.createElement("span"),d.classList.add("ui-arrow"),c.appendChild(d)),e=a.createElement("a"),e.classList.add("ui-text"),e.setAttribute("href","#"+b),e.innerHTML=b,c.appendChild(e),p.add(l.NAVIGATION_ACTIVE),p.add(l.NAVIGATION_ACTIVE_ANIMATION),h.one(c,"animationend webkitAnimationEnd",function(){p.remove(l.NAVIGATION_ACTIVE_ANIMATION)}),j.appendChild(c),j.offsetWidth>g.offsetWidth&&(g.scrollLeft=j.offsetWidth-g.offsetWidth)},m._destroy=function(a){var b=this;a.removeEventListener("vclick",b._clickBound,!1),a.removeChild(b._ui.container),b._clickBound=null,b._ui=null,b._navigationStack=null},f.registerActiveSelector(".ui-navigation .ui-text"),b.widget.mobile.Navigation=j,g.defineWidget("Navigation","[data-role='navigation'], .ui-navigation",["push","pop","create"],j,"mobile")}(a.document,d),function(a){a.widget.core.indexscrollbar=a.widget.core.indexscrollbar||{}}(d),function(a,b){function c(a,b){return this.element=a,this.options=d.merge(b,this._options,!1),this.container=this.options.container,f.call(self),this.indices={original:this.options.index,merged:[]},this._init(),this}var d=b.util.object,e=b.util.DOM,f=b.widget.core.BaseKeyboardSupport;c.prototype={_options:{container:null,offsetLeft:0,index:[],verticalCenter:!1,moreChar:"*",moreCharLineHeight:9,indexHeight:41,selectedClass:"ui-state-selected",ulClass:null,maxIndexLen:0},_init:function(){this.indices.original=this.options.index,this.indexLookupTable=[],this.indexElements=null,this.selectedIndex=-1,this.visiblity="hidden",this._setMaxIndexLen(),this._makeMergedIndices(),this._drawDOM(),this._appendToContainer(),this.options.verticalCenter&&this._adjustVerticalCenter(),this._setIndexCellInfo()},_clear:function(){for(;this.element.firstChild;)this.element.removeChild(this.element.firstChild);this.indices.merged.length=0,this.indexLookupTable.length=0,this.indexElements=null,this.selectedIndex=-1,this.visiblity=null},refresh:function(){this._clear(),this._init()},destroy:function(){this._clear()},show:function(){this.visibility="visible",this.element.style.visibility=this.visibility},hide:function(){this.visibility="hidden",this.element.style.visibility=this.visibility},isShown:function(){return"visible"===this.visibility},_setMaxIndexLen:function(){var a,b=this,c=b.options,d=b.container,e=c.indexHeight,f=d.offsetHeight;a=Math.floor(f/e),a>0&&a%2===0&&(a-=1),c.maxIndexLen=c.maxIndexLen>0?Math.min(a,c.maxIndexLen):a},_makeMergedIndices:function(){var a,b,c=this.indices.original,d=c.length,e=Math.min(this.options.maxIndexLen,d),f=d-e,g=parseInt(f/parseInt(e/2,10),10),h=f%parseInt(e/2,10),i=[],j=[],k=0;for(a=0,b=e;b>a;a++)i[a]=1,a%2&&(i[a]+=g+(h-->0?1:0)),k+=i[a],j.push({start:k-1,length:i[a]});this.indices.merged=j},_drawDOM:function(){var b,c,d,e,f,g,h=this.indices.original,i=this.indices.merged,j=i.length,k=this.options.indexHeight,l=this.options.moreChar,m=this.container.clientHeight-(j-1)*k,n=this.options.moreCharLineHeight;for(c=a.createDocumentFragment(),f=0;j>f;f++)g=i[f],b=1===g.length?h[g.start]:l,e=a.createElement("a"),d=a.createElement("li"),e.innerText=b.toUpperCase(),e.setAttribute("href","#"+b.toUpperCase()),d.appendChild(e),d.style.height=(f===j-1?m:k)+"px",d.style.lineHeight=b===l?k+n+"px":k+"px",c.appendChild(d);this.element.appendChild(c),this.options.ulClass&&this.element.classList.add(this.options.ulClass)},_adjustVerticalCenter:function(){var a=this.indices.merged.length,b=a*this.options.indexHeight,c=parseInt((this.container.offsetHeight-b)/2,10);this.element.style.paddingTop=c+"px"},_appendToContainer:function(){var b=this,c=b.options,d=b.element,e=b.container,f=d.style,g=a.createElement("div"),h=c.paddingBottom+"px";e.appendChild(d),f.left=c.offsetLeft+"px",c.paddingBottom&&(f.paddingBottom=h,g.classList.add("ui-indexscrollbar-margin"),g.style.height=h,e.appendChild(g))},setPaddingTop:function(a){var b=this.element.clientHeight,c=this.element.style.paddingTop,d=this.container.clientHeight;c=""===c?0:parseInt(c,10),b-=c,b>d&&(a-=a+b-d),this.element.style.paddingTop=a+"px",this._setIndexCellInfo()},getOffsetTopByIndex:function(a){var b=this.indexLookupTable[a].cellIndex,c=this.indexElements[b],d=c.offsetTop;return d},_setIndexCellInfo:function(){var a=this.element,b=this.indices.merged,c=e.getElementOffset(this.container).top,d=this.element.querySelectorAll("LI"),f=[];[].forEach.call(d,function(a,d){for(var e=b[d],g=e.start,h=g+e.length,i=c+a.offsetTop,j=a.offsetHeight/e.length;h>g;g++)f.push({cellIndex:d,top:i,range:j}),i+=j}),this.indexLookupTable=f,this.indexElements=a.children},getIndexByPosition:function(a){var b,c,d,e,f=this.indexLookupTable;if(f[0]&&(b=f[0],a<b.top))return 0;if(f[f.length-1]&&(b=f[f.length-1],a>=b.top+b.range))return f.length-1;for(c=0,d=f.length;d>c;c++)if(b=f[c],e=a-b.top,e>=0&&e<b.range)return c;return 0},getValueByIndex:function(a){return 0>a&&(a=0),this.indices.original[a]},select:function(a){var b,c;this.clearSelected(),this.selectedIndex!==a&&(this.selectedIndex=a,b=this.indexLookupTable[a].cellIndex,c=this.indexElements[b],c.classList.add(this.options.selectedClass))},clearSelected:function(){var a=this.element,b=this.options.selectedClass,c=a.querySelectorAll("."+b);[].forEach.call(c,function(a){a.classList.remove(b)}),this.selectedIndex=-1}},b.widget.core.indexscrollbar.IndexBar=c}(a.document,d),function(a,b){function c(a){a.preventDefault(),a.stopPropagation()}function d(a,b){return this.element=a,this.options=e.merge(b,this._options,!1),this.value=null,this._init(),this}var e=b.util.object,f=b.event;d.prototype={_options:{className:"ui-indexscrollbar-indicator",selectedClass:"ui-selected",alignTo:"container",container:null},_init:function(){var a=this,b=a.options,d=a.element;d.className=b.className,d.innerHTML="<span></span>",f.on(d,["touchstart","touchmove"],c,!1),b.referenceElement.parentNode.insertBefore(d,b.referenceElement),a.fitToContainer()},fitToContainer:function(a){var b=this,c=b.element,d=c.style,e=b.options,f=e.container,g=f.getBoundingClientRect();a=a||e.alignTo,d.width=g.width+"px","container"===a?d.height=g.height+"px":d.height=g.height+g.top+"px",d.top=("container"===a?g.top:0)+"px",d.left=g.left+"px"},setValue:function(a){var b="",c="";this.value=a,a=a.toUpperCase(),b=a.substr(a.length-1),c=a.substr(0,a.length-1),this.element.firstChild.innerHTML="<span>"+c+'</span><span class="ui-selected">'+b+"</span>"},show:function(){this.element.style.display="block"},hide:function(){this.element.style.display="none"},destroy:function(){for(var a=this.element;a.firstChild;)a.removeChild(a.firstChild);f.off(a,["touchstart","touchmove"],c,!1),this.element=null}},b.widget.core.indexscrollbar.IndexIndicator=d}(a.document,d),function(b,c){var d=function(){var a=this;a.indicator=null,a.indexBar1=null,a.indexBar2=null,a._ui={},a.index=null,a.touchAreaOffsetLeft=0,a.indexElements=null,a.selectEventTriggerTimeoutId=null,a.ulMarginTop=0,a.eventHandlers={}},e=c.widget.BaseWidget,f=c.event,g=c.util.selectors,h=c.util.object,i=c.util.DOM,j=c.widget.core.indexscrollbar.IndexBar,k=c.widget.core.indexscrollbar.IndexIndicator,l=c.widget.core.Page,m=c.engine.getWidgetDefinition("Page").selector,n={SELECT:"select"},o="vmousedown",p="vmousemove",q="vmouseup",r=!1,s=new e;d.prototype=s,h.merge(s,{widgetName:"IndexScrollbar",widgetClass:"ui-indexscrollbar",_configure:function(){this.options={moreChar:"*",indexScrollbarClass:"ui-indexscrollbar",selectedClass:"ui-state-selected",indicatorClass:"ui-indexscrollbar-indicator",delimiter:",",index:["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","1"],maxIndexLen:0,indexHeight:41,keepSelectEventDelay:50,container:null,supplementaryIndex:null,supplementaryIndexMargin:1,moreCharLineHeight:9,verticalCenter:!0,indicatorAlignTo:"container"}},_build:function(a){return a},_init:function(a){var b=this,c=b.options;return a.classList.add(c.indexScrollbarClass),b._ui.page=g.getClosestBySelector(a,m),b._setIndex(a,c.index),b._setMaxIndexLen(a,c.maxIndexLen),b._setInitialLayout(),b._createSubObjects(),b._updateLayout(),b._extended(!0),a},_refresh:function(){var a=this;a._isExtended()&&(a._unbindEvent(),a.indicator.hide(),a._extended(!1)),a._setIndex(a.element,a.options.index),a._updateLayout(),a.indexBar1.options.index=a.options.index,a.indexBar1.refresh(),a.indicator.fitToContainer(),a._bindEvents(),a._extended(!0)},_destroy:function(){var a=this;a.isBound()&&(a._unbindEvent(),a._extended(!1),a._destroySubObjects(),a.indicator=null,a.index=null,a.eventHandlers={})},_createSubObjects:function(){var a=this,c=a.options,d=a.element;a.indexBar1=new j(b.createElement("UL"),{container:d,offsetLeft:0,index:c.index,verticalCenter:c.verticalCenter,indexHeight:c.indexHeight,maxIndexLen:c.maxIndexLen,paddingBottom:c.paddingBottom,moreCharLineHeight:c.moreCharLineHeight}),"function"==typeof c.supplementaryIndex&&(a.indexBar2=new j(b.createElement("UL"),{container:d,offsetLeft:-d.clientWidth-c.supplementaryIndexMargin,index:[],indexHeight:c.indexHeight,ulClass:"ui-indexscrollbar-supplementary"}),a.indexBar2.hide()),a.indicator=new k(b.createElement("DIV"),{container:a._getContainer(),referenceElement:a.element,className:c.indicatorClass,alignTo:c.indicatorAlignTo})},_destroySubObjects:function(){var a,b,c,d={iBar1:this.indexBar1,iBar2:this.indexBar2,indicator:this.indicator};for(c in d)d.hasOwnProperty(c)&&(a=d[c],a&&(b=a.element,a.destroy(),b.parentNode.removeChild(b)))},_setInitialLayout:function(){var b=this.element,c=this._getContainer(),d=a.getComputedStyle(c).position,e=b.style;"absolute"!==d&&"relative"!==d&&(e.top=c.offsetTop+"px",e.height=c.offsetHeight+"px")},_setMaxIndexLen:function(a,b){var c=this,d=c.options,e=c._getContainer(),f=e.offsetHeight;0>=b&&(b=Math.floor(f/d.indexHeight)),b>0&&b%2===0&&(b-=1),d.maxIndexLen=b},_updateLayout:function(){var a=this;a._setInitialLayout(),a._draw(),a.touchAreaOffsetLeft=a.element.offsetLeft-10},_draw:function(){return this.indexBar1.show(),this},_removeIndicator:function(){var a=this.indicator,b=a.element.parentNode;b.removeChild(a.element),a.destroy(),this.indicator=null},_getEventReceiverByPosition:function(b){var c,d=a.innerWidth,e=this.element.clientWidth;return c=this.options.supplementaryIndex?b>=d-e&&d>=b?this.indexBar1:this.indexBar2:this.indexBar1},_updateIndicatorAndTriggerEvent:function(b){this.indicator.setValue(b),this.indicator.show(),this.selectEventTriggerTimeoutId&&a.clearTimeout(this.selectEventTriggerTimeoutId),this.selectEventTriggerTimeoutId=a.setTimeout(function(){this.trigger(n.SELECT,{index:b}),this.selectEventTriggerTimeoutId=null}.bind(this),this.options.keepSelectEventDelay)},_onTouchStartHandler:function(a){var c=a.touches||a._originalEvent&&a._originalEvent.touches,d=null,e=null,f=0,g=0;return r=!0,c&&c.length>1?(a.preventDefault(),void a.stopPropagation()):(d=this._getPositionFromEvent(a),e=this.indexBar1,f=e.getIndexByPosition(d.y),g=e.getValueByIndex(f),e.select(f),b.addEventListener(p,this.eventHandlers.touchMove),b.addEventListener(q,this.eventHandlers.touchEnd),b.addEventListener("touchcancel",this.eventHandlers.touchEnd),void this._updateIndicatorAndTriggerEvent(g))},_onTouchMoveHandler:function(a){var b,c,d,e=a._originalEvent&&a._originalEvent.touches,g=null,h=null,i=null;return e&&e.length>1||!r?(f.preventDefault(a),void f.stopPropagation(a)):(g=this._getPositionFromEvent(a),h=this.indexBar1,i=this.indexBar2,c=this._getEventReceiverByPosition(g.x),c===i&&(i.options.index=this.options.supplementaryIndex(h.getValueByIndex(h.selectedIndex)),i.refresh()),b=c.getIndexByPosition(g.y),d=c.getValueByIndex(b),c===i?d=h.getValueByIndex(h.selectedIndex)+d:i&&!i.isShown()&&i.setPaddingTop(h.getOffsetTopByIndex(h.selectedIndex)),c.select(b),c.show(),h===c&&i&&i.hide(),this._updateIndicatorAndTriggerEvent(d),f.preventDefault(a),void f.stopPropagation(a))},_onTouchEndHandler:function(a){var c=this,d=a._originalEvent&&a._originalEvent.touches;(d&&0===d.length||!d)&&(r=!1),c.indicator.hide(),c.indexBar1.clearSelected(),c.indexBar2&&(c.indexBar2.clearSelected(),c.indexBar2.hide()),b.removeEventListener(p,c.eventHandlers.touchMove),b.removeEventListener(q,c.eventHandlers.touchEnd),b.removeEventListener("touchcancel",c.eventHandlers.touchEnd)},_bindOnPageShow:function(){var a=this;a.eventHandlers.onPageShow=a.refresh.bind(a),a._ui.page&&a._ui.page.addEventListener(l.events.BEFORE_SHOW,a.eventHandlers.onPageShow,!1)},_unbindOnPageShow:function(){var a=this;a.eventHandlers.onPageShow&&a._ui.page&&a._ui.page.removeEventListener(l.events.BEFORE_SHOW,a.eventHandlers.onPageShow,!1)},_bindEvents:function(){var a=this;a._bindResizeEvent(),a._bindEventToTriggerSelectEvent(),a._bindOnPageShow()},_unbindEvent:function(){var a=this;a._unbindResizeEvent(),a._unbindEventToTriggerSelectEvent(),a._unbindOnPageShow()},_bindResizeEvent:function(){this.eventHandlers.onresize=function(){this.refresh()}.bind(this),a.addEventListener("resize",this.eventHandlers.onresize)},_unbindResizeEvent:function(){this.eventHandlers.onresize&&a.removeEventListener("resize",this.eventHandlers.onresize)},_bindEventToTriggerSelectEvent:function(){var a=this;a.eventHandlers.touchStart=a._onTouchStartHandler.bind(a),a.eventHandlers.touchEnd=a._onTouchEndHandler.bind(a),a.eventHandlers.touchMove=a._onTouchMoveHandler.bind(a),a.element.addEventListener(o,a.eventHandlers.touchStart)},_unbindEventToTriggerSelectEvent:function(){var a=this;a.element.removeEventListener(o,a.eventHandlers.touchStart)},_data:function(a,b){var c,d=this.element,e=d.__data;if(e||(e=d.__data={}),"object"==typeof a){for(c in a)a.hasOwnProperty(c)&&this._data(c,a[c]);return this}return"undefined"==typeof b?e[a]:(e[a]=b,this)},_isValidElement:function(a){return a.classList.contains(this.widgetClass)},_isExtended:function(){return!!this._data("extended")},_extended:function(a){return this._data("extended",a),this},_setIndex:function(a,b){var c=this.options;"string"==typeof b&&(b=b.split(c.delimiter)),c.index=b},_getOffset:function(a){var b=0,c=0;do c+=a.offsetTop,b+=a.offsetLeft,a=a.offsetParent;while(a);return{top:c,left:b}},_getContainer:function(){var a,c=this.options.container,d=this.element,e=d.parentNode;if(!c){for(;e&&e!==b.body;){if(a=i.getCSSProperty(e,"overflow-y"),"scroll"===a||"auto"===a&&e.scrollHeight>e.clientHeight)return e;e=e.parentNode}c=d.parentNode}return c||d.parentNode},_getPositionFromEvent:function(a){return-1!==a.type.search(/^touch/)?{x:a.touches[0].clientX,y:a.touches[0].clientY}:{x:a.clientX,y:a.clientY}},addEventListener:function(a,b){this.element.addEventListener(a,b)},removeEventListener:function(a,b){this.element.removeEventListener(a,b)}}),c.widget.core.IndexScrollbar=d}(a.document,d),function(){function a(a){var b,c,d=[];for(c=a.length,b=0;c>b;b++)d.push(a[b].textContent.trim());return d}var b=d.engine,c=d.util.selectors,e=d.widget.core.Page,f=d.widget.core.Scrollview,g=d.widget.core.IndexScrollbar,h=g.prototype,i=new g,j=function(){var a=this;a._ui={},g.call(a)},k={PAGE:e.classes.uiPage,CONTENT:e.classes.uiContent,SCROLLVIEW_CLIP:f.classes.clip,FLOATING_BUTTON_CONTAINER:"ui-floatingactions",GROUP_INDEX:"ui-group-index"},l={INDEX_HEIGHT:20,MORE_CHAR_LINEHEIGHT:4};j.classes=k,i._configure=function(b){var d=this,e=c.getClosestByClass(b,k.PAGE),f=e.querySelector("."+k.CONTENT),g=a(e.getElementsByClassName(k.GROUP_INDEX));h._configure.call(d),d.options.container||(d.options.container=f||b.parentNode),g.length&&(d.options.index=g),d.options.indexHeight=l.INDEX_HEIGHT,d.options.moreCharLineHeight=l.MORE_CHAR_LINEHEIGHT,d.options.verticalCenter=!1},i._init=function(a){var b=this;h._init.call(b,a),b._fitHeight()},i._setInitialLayout=function(){var a=this,b=a.element,c=a.options,d=c.container,e=b.style,f=d.parentElement.querySelector("."+k.FLOATING_BUTTON_CONTAINER);f&&(c.paddingBottom=d.offsetHeight-f.offsetTop+d.offsetTop),e.height=d.offsetHeight+"px",e.top=d.offsetTop+"px"},i._fitHeight=function(){var a,b=this,c=b.element,d=c.getElementsByTagName("ul")[0],e=d.lastChild;a=c.offsetHeight-d.offsetHeight,e&&(e.style.height=e.offsetHeight+a+"px")},j.prototype=i,d.widget.mobile.IndexScrollbar=j,b.defineWidget("IndexScrollbar","[data-role='indexscrollbar'], .ui-indexscrollbar",[],j,"mobile")}(),function(a,b,c){var d=c.widget.core.Button;c.widget.mobile.Button=d,c.engine.defineWidget("Button","button, [data-role='button'], .ui-btn, input[type='button']",[],d,"mobile",!0)}(a,a.document,d),function(b,c){var d=c.widget.BaseWidget,e=c.widget.core.Page.classes,f=c.widget.core.BaseKeyboardSupport,g=f.KEY_CODES,h=c.engine,i=c.event,j=c.util.selectors,k=new d,l=/matrix\((.*), (.*), (.*), (.*), (.*), (.*)\)/,m=19,n=function(){var a=this;f.call(a),a.element=null,a.options={},a._style=null,a._startX=0,a._currentX=0,a._hasSingle=!0,a._padding={},a._position={},a._scope={}},o="ui-floatingactions",p=["left-min","left-2nd-icon","left-1st-icon","center","right-1st-icon","right-2nd-icon","right-min"],q={WIDGET:o,TRANSITIONS:o+"-transitions",EXPAND_TO_LEFT:o+"-expand-to-left",EXPAND_TO_RIGHT:o+"-expand-to-right",PAGE_WITH_FLOATING_ACTIONS:"ui-page-floatingactions"};k._configure=function(){this.options={duration:300,position:"right-1st-icon"}},k._init=function(a){var b=this;return b._style=a.style,b.element.hasAttribute("tabindex")||b.element.setAttribute("tabindex","0"),b._hasSingle=a.children.length<=1,b._buildInsideButtons(),b._positionCalculation(),b._setScope(),b._updatePosition(),b._toggleParentClasses(),a},k._bindEvents=function(){var a=this,b=a.element;i.enableGesture(b,new i.gesture.Drag({blockVertical:!0})),i.on(b,"drag dragstart dragend dragcancel touchstart touchend vmousedown vmouseup keyup",a)},k._unbindEvents=function(){i.disableGesture(this.element),i.off(this.element,"drag dragstart dragend dragcancel touchstart touchend vmousedown vmouseup keyup",this)},k._refresh=function(){var a=this,b=a.element;a._hasSingle=b.children.length<=1,a._positionCalculation(),a._setScope(),a._updatePosition()},k._destroy=function(){var a=this;a.isBound()&&(a._unbindEvents(),a._style=null,a._position=null,a._scope=null,a._padding=null,a._toggleParentClasses(!0))},k._buildInsideButtons=function(){for(var a=0,b=this,d=b.element,e=d.children,f=e.length;f>a;a++)c.widget.Button(e[a])},k._positionCalculation=function(){var b,c,d=this,e=d.element,f=a.getComputedStyle(e),g=d._position,h=d._padding,i=e.offsetWidth;b=parseInt(f.paddingLeft,10),b=parseInt(f.paddingLeft,10),c=parseInt(f.paddingRight,10),g.min=-a.innerWidth+b,g.max=i-c,g.center=(g.max+g.min)/2,g.left=g.min+i-(b+c),g.leftOneButton=g.min+(g.left-g.min)/2,g.right=g.max-i+(c+b),g.rightOneButton=g.right+(g.max-g.right)/2,h.left=b,h.right=c,h.ratioInShow=m/(g.center-g.left),h.ratioInHide=m/(g.left-g.min)},k._setScope=function(){var a=this,b=a._position,c=a._scope,d=a._padding,e=a._hasSingle;c.min=b.min+d.left/2,c.leftOneButton=e?null:b.min+3*(b.left-b.min)/4,c.left=b.left+(b.center-b.left)/2,c.center=b.center+(b.right-b.center)/2,c.right=b.right+d.right/2,c.rightOneButton=e?null:b.right+3*(b.max-b.right)/4,c.max=b.max},k._start=function(b){var c=this,d=c.element;c._startX=b.detail.pointer.clientX,c._currentX=parseInt(a.getComputedStyle(d).webkitTransform.match(l)[5],10),d.classList.remove(q.TRANSITIONS),c._clearExpandWidget()},k._clearExpandWidget=function(){var a=this.element.classList;a.remove(q.EXPAND_TO_LEFT),a.remove(q.EXPAND_TO_RIGHT)},k._expandWidget=function(a){var b=this,c=b.element.classList;switch(a){case"left-min":case"left-1st-icon":case"left-2nd-icon":c.add(q.EXPAND_TO_LEFT),c.remove(q.EXPAND_TO_RIGHT);break;case"center":b._clearExpandWidget();break;case"right-min":case"right-1st-icon":case"right-2nd-icon":c.remove(q.EXPAND_TO_LEFT),c.add(q.EXPAND_TO_RIGHT)}},k._move=function(a){var b,c=this,d=c._style,e=a.detail.estimatedX-c._startX+c._currentX,f=c._position;e>=f.min&&e<=f.max&&(b="translate3d("+e+"px, 0, 0)",d.webkitTransform=b,d.transform=b)},k._setPosition=function(a,b){var d=this,e=d._hasSingle;e&&"left-2nd-icon"===b&&(b="left-1st-icon",c.warn("Cannot set 2nd icon when widget has 1 icon")),e&&"right-2nd-icon"===b&&(b="right-1st-icon",c.warn("Cannot set 2nd icon when widget has 1 icon")),d.options.position=b,d._updatePosition()},k._getPositionByName=function(a){var b=this._position;switch(a){case"left-min":return b.min;case"left-2nd-icon":return b.leftOneButton;case"left-1st-icon":return b.left;case"center":return b.center;case"right-1st-icon":return b.right;case"right-2nd-icon":return b.rightOneButton;case"right-min":return b.max;default:return b.max}},k._toggleParentClasses=function(a){var b=this,c=j.getClosestByClass(b.element,e.uiPage);c&&c.classList.toggle(q.PAGE_WITH_FLOATING_ACTIONS,!a)},k._updatePosition=function(){var a,b=this,c=b.element.style,d=b.options.position;b.element.classList.add(q.TRANSITIONS),a="translate3d("+b._getPositionByName(d)+"px, 0, 0)",c.webkitTransform=a,c.transform=a,b._expandWidget(d)},k._getPositionNameByPosition=function(a){var b=this,c=b._scope,d=b._hasSingle;return a<c.min?"left-min":!d&&a<c.leftOneButton?"left-2nd-icon":a<c.left?"left-1st-icon":a<c.center?"center":a<c.right?"right-1st-icon":!d&&a<c.rightOneButton?"right-2nd-icon":"right-min"},k._moveTo=function(a){var b=this;b.options.position=b._getPositionNameByPosition(a),b._updatePosition()},k._end=function(a){var b=this;b._moveTo(a.detail.estimatedX-b._startX+b._currentX)},k._moveOnLeft=function(){var a=Math.max(p.indexOf(this.options.position)-1,0);this.option("position",p[a])},k._moveOnRight=function(){var a=Math.min(p.indexOf(this.options.position)+1,p.length-1);this.option("position",p[a])},k._onkeyup=function(a){var b=a,c=this;switch(b.keyCode){case g.left:c._reposition&&c._moveOnLeft();break;case g.right:c._reposition&&c._moveOnRight();break;case g.enter:a.target===this.element&&c._toggleRepositionMode(!c._reposition);break;case g.escape:c._toggleRepositionMode(!1);break;default:return}},k._toggleRepositionMode=function(a){var b=this;a?(b.element.classList.add("ui-floatingactions-reposition"),b.disableFocusableElements(b.element)):(b.element.classList.remove("ui-floatingactions-reposition"),b.enableDisabledFocusableElements(b.element)),b._reposition=a},k._focus=function(a){a.hasAttribute("tabindex")||a.setAttribute("tabindex",0),a.classList.add("ui-focus"),a.focus()},k._blur=function(a){a.hasAttribute("tabindex")&&a.removeAttribute("tabindex",0),a.classList.remove("ui-focus")},k.handleEvent=function(a){var b=this;switch(a.type){case"dragstart":b._start(a);break;case"drag":b._move(a);break;case"dragend":case"dragcancel":b._end(a);break;case"keyup":b._onkeyup(a)}},k.onAttach=function(){this.refresh()},n.prototype=k,n.classes=q,c.widget.mobile.FloatingActions=n,h.defineWidget("FloatingActions","[data-role='floatingactions'], ."+o,[],n,"mobile")}(a.document,d),function(a,b){function d(a,b,c,d,e){var f,g,h,i,j,k,l=a,m=e._carouselItemByCount(l);return e._lastCurrentIndex!==Math.round(a)&&(null!==e._lastCurrentIndex&&e._rollItems(Math.round(a)-e._lastCurrentIndex,Math.round(a)),e._lastCurrentIndex=Math.round(a)),f=b-m,f<-e._carouselCenterIndex?f+=e._numberOfCarouselItems:f>e._carouselCenterIndex&&(f-=e._numberOfCarouselItems),g=0>f?-1:1,h=Math.abs(f),i=1-d.scaleFactor*h,j=1-d.moveFactor*h,k=1-(d.enabled?d.scaleFactor:1)*h,i=0>i?0:i,k=0>k?0:k,j=g*(q*(1-j))+c,{moveY:j,scale:i,opacity:k}}function e(a){var c=a._carouselItems,e=a.options,f=a._itemHeight,g=a._objectValue,h=(a._containerHeight-f)/2;c.forEach(function(b,c){var f=d(g.value,c,h,e,a);f.opacity>0?b.element.style.transform="translateY("+f.moveY+"px) scale("+f.scale+")":b.element.style.transform="translateY(-1000px)",b.element.style.opacity=f.opacity}),b.event.trigger(a.element,"spinstep",parseInt(g.value,10))}var f=a.document,g=b.widget.BaseWidget,h=b.widget.core.Page,i=b.widget.core.Appbar,j=b.engine,k=b.event,l=k.gesture,m=b.util.selectors,n=b.util.Animate,o=300,p=600,q=100,r=60,s=13,t=500,u=function(){var a=this;a.options={min:0,max:9,step:1,moduloValue:"enabled",shortPath:"enabled",duration:p,direction:"up",rollHeight:"custom",itemHeight:38,momentumLevel:0,momentumDuration:800,scaleFactor:.4,moveFactor:.4,loop:"enabled",labels:[],digits:0,value:0,dragTarget:"document",enabled:!1},a._ui={scrollableParent:null,page:null,appbar:null},a._carouselItems=[],a._numberOfCarouselItems=s,a.length=a.options.max-a.options.min+a.options.step,a._prevValue=null,a._overflowYBeforeDrag=null,a._lastCurrentIndex=null,a._currentCentralCarouseItem=0,a._count=0,a._dragTimeoutHandler=null},v="ui-spin",w={SPIN:v,PREFIX:v+"-",ITEM:v+"-item",SELECTED:v+"-item-selected",NEXT:v+"-item-next",PREV:v+"-item-prev",ENABLED:"enabled",ENABLING:v+"-enabling",PLACEHOLDER:v+"-placeholder",CAROUSEL:v+"-carousel",CAROUSEL_ITEM:v+"-carousel-item"},x=new g;u.classes=w,u.timing=n.timing,x._fillCarouselByCount=function(a){var b,c,d,e,f=this;for(a=Math.round(a),e=0;e<f._numberOfCarouselItems;e++)f._carouselItems[e].element.firstElementChild&&f._carouselItems[e].element.removeChild(f._carouselItems[e].element.firstElementChild);for(c=f._numberOfCarouselItems-f.length,0>c&&(c=0),e=Math.floor(c/2),d=c-e;e<f._numberOfCarouselItems-d;e++)b=f._itemByCount(a+e-f._carouselCenterIndex),b&&f._carouselItems[f._carouselItemByCount(a+e-f._carouselCenterIndex)].element.appendChild(b)},x._rollItems=function(a,b){var c,d,e=this,f=a>0?1:-1;a=Math.abs(a),1===a?(c=e._carouselItems[e._carouselItemByCount(b+f*e._carouselCenterIndex)],d=e._itemByCount(b+f*e._carouselCenterIndex),c.element.firstElementChild&&c.element.removeChild(c.element.firstElementChild),d&&c.element.appendChild(d)):a>1&&e._fillCarouselByCount(b)},x._removeSelectedLayout=function(){var a=this,b=a._itemByCount(a._previousCount);b&&b.classList.remove(w.SELECTED)},x._addSelectedLayout=function(){var a=this,b=a._itemByCount(a._count);b&&b.classList.add(w.SELECTED)},x._show=function(){var a=this,c=new n({}),d=null,f={value:a._previousCount};a._removeSelectedLayout(),d={animation:[{object:f,property:"value",to:a._count}],animationConfig:{duration:a.options.enabled?a.options.duration:1,timing:u.timing.ease}},a.state=d,a._objectValue=f,a._animation=c,c.set(d.animation,d.animationConfig),c.tick(e.bind(null,a)),c.start(function(){a._addSelectedLayout(),a._prevValue=a.options.value,a.options.value=a._getValueByCount(a._count),b.event.trigger(a.element,"spinchange",{value:parseInt(a.options.value,10),dValue:parseInt(a.options.value,10)-parseInt(a._prevValue,10)})})},x._modifyItems=function(){var a,b=this,c=b.options,e=0,g=[],h=Math.abs(c.max-c.min)/c.step+1,i=0,j="",k=null,l=0;for(b._ui.items=g;h>l;l++)k=f.createElement("div"),k.classList.add(w.ITEM),g.push(k);for(i=0;h>i;i++){if(k=g[i],j="",b.options.labels.length)j=b.options.labels[i];else if(j+=c.min+i*c.step,c.digits>0)for(;j.length<c.digits;)j="0"+j;k.innerHTML=j}"container"===c.rollHeight?e=b._containerHeight:"custom"===c.rollHeight?e=c.itemHeight:(k=g[0],e=k?k.getBoundingClientRect().height:b._containerHeight),b._itemHeight=e,a=(b._containerHeight-e)/2,b._carouselItems.forEach(function(e,f){var g=d(b._valueToCount(c.value),f,a,c,b);e.element.style.transform="translateY("+g.moveY+"px) scale("+g.scale+")",e.element.style.opacity=g.opacity})},x._setItemHeight=function(a,b){b="string"==typeof b?parseInt(b.replace("px").trim(),10):b,this.options.itemHeight=b},x._updateItems=function(){var a=this;a._removeSelectedLayout(),a._modifyItems(),a._addSelectedLayout()},x._refresh=function(){var a=this,b=getComputedStyle(a.element).height||0;a._containerHeight=parseInt(b,10),a._modifyItems(),a._fillCarouselByCount(a._count),a._show()},x._init=function(){var a=this,b=a.options;b.min=b.min!==c?parseInt(b.min,10):0,b.max=b.max!==c?parseInt(b.max,10):0,b.value=b.value!==c?parseInt(b.value,10):0,b.step=b.step!==c?parseInt(b.step,10):1,b.duration=b.duration!==c?parseInt(b.duration,10):0,b.labels=Array.isArray(b.labels)?b.labels:b.labels.split(","),a.length=b.max-b.min+b.step,a._count=a._valueToCount(b.value),a.dragTarget="document"===b.dragTarget?f:a.element,a._refresh()},x._buildCarousel=function(a){var b,c=this,d=f.createElement("div"),e=f.createDocumentFragment(),g=0;for(c._carouselItems=[],c._numberOfCarouselItems=a,c._carouselCenterIndex=Math.floor(a/2),d.classList.add(w.CAROUSEL,w.PREFIX+a);a>g;g++)b=f.createElement("div"),b.id="cel-"+g,b.classList.add(w.CAROUSEL_ITEM),c._carouselItems[g]={element:b},e.appendChild(b);return d.appendChild(e),d},x._build=function(a){var b=f.createElement("div"),c=null,d=this;return a.classList.add(w.SPIN),b.classList.add(w.PLACEHOLDER),a.appendChild(b),c=d._buildCarousel(d._numberOfCarouselItems),a.appendChild(c),d._ui.carousel=c,d._ui.placeholder=b,a},x._valueToCount=function(a){var b=this;return(a-b.options.min)/b.options.step||0},x._setValue=function(c){var d=this;c=a.parseFloat(c,10),d._ui.placeholder.textContent=c,isNaN(c)?b.warn("Spin: value is not a number"):((c<d.options.min||c>d.options.max)&&"disabled"===d.options.loop&&(c=Math.min(Math.max(c,d.options.min),d.options.max)),c!==d.options.value&&(d._previousCount=d._count,d._count=d._valueToCount(c),d.options.value=c,d.element.dataset.value=c,d._stopAnimation(),d._show()))},x._stopAnimation=function(){var a=this,b=a.state.animation[0];null!==b&&b.to!==b.current&&a._animation.stop()},x._carouselItemByCount=function(a){var b=this._carouselCenterIndex,c=(a+b)%this._numberOfCarouselItems;return 0>c&&(c+=this._numberOfCarouselItems),c},x._getValueByCount=function(a){var b,c,d=this,e=d.options;return"enabled"!==e.loop?b=a*e.step+e.min:a>=0?b=a%d.length*e.step+e.min:(c=a%d.length||0,0>c&&(c+=d.length),b=c*e.step+e.min),b},x._getValue=function(){var a=this,b=a.options,c=a._getValueByCount(a._count);return"enabled"!==a.options.loop&&(a._objectValue.value=Math.min(Math.max(c,b.min),b.max)),c},x._setMax=function(a,b){var d=this.options;d.max=b!==c?parseInt(b,10):0,this.length=d.max-d.min+d.step},x._setMin=function(a,b){var d=this.options;d.min=b!==c?parseInt(b,10):0,this.length=d.max-d.min+d.step},x._setLabels=function(a,b){var c=this;c.options.labels=b.split(","),c._refresh()},x._setModuloValue=function(a,b){this.options.moduloValue="enabled"===b?"enabled":"disabled"},x._setShortPath=function(a,b){this.options.shortPath="enabled"===b?"enabled":"disabled"},x._setLoop=function(a,b){
+this.options.loop="enabled"===b?"enabled":"disabled"},x._setDuration=function(b,c){this.options.duration=a.parseInt(c,10)},x._setEnabled=function(b,c){var d=this;return d.options.enabled="false"===c?!1:c,d.options.enabled?(b.classList.add(w.ENABLING),a.setTimeout(function(){b.classList.remove(w.ENABLING)},o),b.classList.add(w.ENABLED),k.on(d.dragTarget,"drag dragend dragstart",d),k.on(d.dragTarget,"vmousedown vmouseup",d)):(b.classList.add(w.ENABLING),a.setTimeout(function(){b.classList.remove(w.ENABLING),d.refresh()},o),b.classList.remove(w.ENABLED),k.off(d.dragTarget,"drag dragend dragstart",d),k.off(d.dragTarget,"vmousedown vmouseup",d),d._animation.stop()),this._prevValue=null,!0},x._setDirection=function(a,b){this.options.direction=["up","down"].indexOf(b)>-1?b:"up"},x._drag=function(c){var d=this;null===f.getElementById(d.element.id)?k.off(d.dragTarget,"drag dragend dragstart",d):d.options.enabled&&(d._objectValue.value=d._startDragCount-c.detail.deltaY/r,"enabled"!==d.options.loop&&(d._objectValue.value=Math.min(Math.max(d._objectValue.value,0),d.length-1)),e(d)),a.clearTimeout(d._dragTimeoutHandler),d._dragTimeoutHandler=a.setTimeout(function(){d._dragEnd({detail:{velocityY:c.velocityY,distance:c.distance,direction:c.direction}}),d._dragTimeoutHandler=null,b.event.gesture.Manager.getInstance().resetDetecting()},t)},x._dragStart=function(){var a=this;a._animation.pause(),a._startDragCount=a._count,a._previousCount=a._count,a._removeSelectedLayout()},x._dragEnd=function(b){var c=this,d=c._animation._animate.chain[0],e=0,f=c.options.duration;a.clearTimeout(c._dragTimeoutHandler),c.options.momentumLevel>0&&b.detail.velocityY>.7&&b.detail.distance?(e=c.options.momentumLevel*Math.round(b.detail.distance/20),"up"===b.detail.direction&&(e=-e),c._count=Math.round(c._objectValue.value)-e||0,"enabled"!==c.options.loop&&(c._count=Math.min(Math.max(c._count,0),c.length-1)),f=c.options.momentumDuration,d[0].timing=u.timing.easeOut):(c._count=Math.round(c._objectValue.value)||0,"enabled"!==c.options.loop&&(c._count=Math.min(Math.max(c._count,0),c.length-1)),f=Math.abs(c._count-c._objectValue.value)*f),d[0].from=c._objectValue.value,d[0].to=c._count,d[0].duration=f,c._animation.start(c._animation._animate.callback)},x._vmouseDown=function(){var a=this,c=a._ui;c.scrollableParent=m.getScrollableParent(a.element),c.scrollableParent&&(a._overflowYBeforeDrag=c.scrollableParent.style.overflowY,c.scrollableParent.style.overflowY="hidden"),c.page=m.getClosestBySelector(a.element,h.selector),c.page&&(c.appbar=c.page.querySelector(i.selector),c.appbar&&b.widget.Appbar(c.appbar).lockExpanding(!0))},x._vmouseUp=function(){var a=this,c=a._ui;c.scrollableParent&&(c.scrollableParent.style.overflowY=a._overflowYBeforeDrag),c.appbar&&b.widget.Appbar(c.appbar).lockExpanding(!1)},x._itemIndexByValue=function(a){var b=this.options;return Math.round((a-b.min)/b.step)},x._itemByCount=function(a){var b=this,c=b._getValueByCount(a);return b._ui.items[b._itemIndexByValue(c)]},x._click=function(a){var b=this,c=a.target,d=b._ui.items,e=b._count,f=d.indexOf(c);!b.element.classList.contains(w.ENABLING)&&f>-1&&(b._previousCount=e,c===b._itemByCount(e-1)?b._count--:c===b._itemByCount(e+1)&&b._count++,b._previousCount!==b._count&&b._show())},x.handleEvent=function(a){var b=this;switch(a.type){case"drag":b._drag(a);break;case"vmousedown":b._vmouseDown(a);break;case"vmouseup":b._vmouseUp(a);break;case"dragend":b._dragEnd(a);break;case"dragstart":b._dragStart(a);break;case"vclick":b._click(a)}},x._bindEvents=function(){var a=this;k.enableGesture(a.dragTarget,new l.Drag({blockHorizontal:!0,threshold:7})),k.on(a.element,"vclick",a)},x._unbindEvents=function(){var a=this;k.disableGesture(a.dragTarget),k.off(a.dragTarget,"drag dragend dragstart",a),k.off(a.element,"vclick",a)},x._destroy=function(){var a=this,b=a.element,c=a._ui;a._unbindEvents(),c.items.forEach(function(a){a.parentNode&&a.parentNode.removeChild(a)}),a._carouselItems.forEach(function(a){a.element.parentNode.removeChild(a.element)}),b.removeChild(c.carousel),b.removeChild(c.placeholder),b.classList.remove(w.SPIN)},u.prototype=x,b.widget.core.Spin=u,j.defineWidget("Spin",".ui-spin",[],u,"core")}(a,d),function(a,b){var c=b.widget.core.Spin,d=c.prototype,e=b.engine,f=b.util.object,g=f.copy(c.classes),h=function(){var a=this,b={scaleFactor:0,moveFactor:.5,itemHeight:54,dragTarget:"self"};c.call(a),a.options=a.options?f.fastMerge(a.options,b):b},i=new c;i._init=function(){var a=this;d._init.call(a),a.option("enabled",!0)},h.prototype=i,h.classes=g,h.timing=c.timing,b.widget.mobile.Spin=h,e.defineWidget("Spin",".ui-spin",[],h,"mobile",!0)}(a,d),function(a,b,d){function e(a,b){var c=b.toString().split(a).join("");return 0===c.length?a:c}var f=d.widget.mobile.BaseWidgetMobile,g=d.engine,h=d.event,i=d.util.selectors.getClosestByClass,j=d.widget.mobile.Spin,k="ui-time-picker",l={CONTAINER:k+"-container",HOUR_CONTAINER:k+"-container-hour",MINUTE_CONTAINER:k+"-container-minute",FORMAT_CONTAINER:k+"-container-format",ACTIVE_CONTAINER:k+"-container-active",TIME_INPUT:k+"-input",TIME_INPUT_ACTIVE:k+"-input-active"},m="."+k,n=function(){this.options={format:"12"},this._spins={hour:null,minute:null,format:null},this._ui={},this._previousInputValue=-1,this._inputValueState=!1},o=new f;n.classes=l,o._init=function(){var a=this,b=a.options;b.format=b.format!==c?b.format:"12",a._setValue(new Date),a.option("format",b.format),Object.keys(a._spins).forEach(function(b){a._spins[b].refresh()})},o._build=function(a){var b=this,c=b._buildTimePicker("hour"),d=b._buildTimePicker("minute"),e=b._buildFormat();return a.appendChild(c),a.appendChild(d),a.appendChild(e),a},o._buildTimePicker=function(a){var c,e=this,f=e._ui,g=b.createElement("div"),h=b.createElement("input"),i=b.createElement("div"),k={momentumLevel:1};return g.classList.add(j.classes.SPIN),i.classList.add(n.classes.CONTAINER),"hour"===a?("24"===e.options.format?(k.min=0,k.max=23):(k.min=1,k.max=12),i.classList.add(n.classes.HOUR_CONTAINER)):"minute"===a&&(k.min=0,k.max=59,k.digits=2,i.classList.add(n.classes.MINUTE_CONTAINER)),h.min=k.min,h.max=k.max,h.type="number",h.step="1",h.classList.add(n.classes.TIME_INPUT),g.appendChild(h),i.appendChild(g),f[a+"Spin"]=g,f[a+"Input"]=h,f[a+"Container"]=i,c=d.widget.Spin(g,k),e._spins[a]=c,i},o._buildFormat=function(){var a,c=this,e=b.createElement("div"),f=b.createElement("div"),g={min:0,max:1,labels:"AM,PM",loop:"false"};return e.classList.add(j.classes.SPIN),f.classList.add(n.classes.CONTAINER),f.classList.add(n.classes.FORMAT_CONTAINER),f.appendChild(e),a=d.widget.Spin(e,g),c._spins.format=a,f},o._setDateValue=function(a){var b,c,d=this,e=d._ui,f=d._spins;b=a.getHours(),c=a.getMinutes(),"12"===d.options.format&&(b>12?(b-=12,f.format.value(1)):f.format.value(0)),e.hourInput.setAttribute("value",b),e.hourInput.value=b,e.minuteInput.setAttribute("value",c),e.minuteInput.value=c,f.hour.value(b),f.minute.value(c)},o._setInputValue=function(a,b,c){var d=this,e=d._ui,f=d._spins;"hour"===a?(e.hourInput.setAttribute("value",b),e.hourInput.value=b,f.hour.value(b)):"minute"===a&&(e.minuteInput.setAttribute("value",b),e.minuteInput.value=b,f.minute.value(b)),d._previousInputValue=b,d._inputValueState=c},o._focusInput=function(a){var b=this,c=b._ui;"hour"===a?(b.element.classList.add(n.classes.TIME_INPUT_ACTIVE),c.hourContainer.classList.add(n.classes.ACTIVE_CONTAINER),c.minuteContainer.classList.remove(n.classes.ACTIVE_CONTAINER),c.hourInput.focus(),b._previousInputValue=c.hourInput.value):"minute"===a&&(b.element.classList.add(n.classes.TIME_INPUT_ACTIVE),c.minuteContainer.classList.add(n.classes.ACTIVE_CONTAINER),c.hourContainer.classList.remove(n.classes.ACTIVE_CONTAINER),c.minuteInput.focus(),b._previousInputValue=c.minuteInput.value),b._inputValueState=!1},o._setValue=function(a){var b=this;a instanceof Date&&b._setDateValue(a)},o._getValue=function(){var a=new Date(0),b=this,c=b._spins,d=parseInt(c.hour.value(),10);return"12"===b.options.format&&1===c.format.value()&&(d+=12),a.setHours(d),a.setMinutes(parseInt(c.minute.value(),10)),a},o._onClick=function(a){var b=this,c=b._ui,d=b.element,e=a.target,f=c.hourContainer,g=c.minuteContainer,h=i(e,n.classes.CONTAINER);h&&h.classList.contains(n.classes.HOUR_CONTAINER)&&i(e,j.classes.SELECTED)?b._focusInput("hour"):h&&h.classList.contains(n.classes.MINUTE_CONTAINER)&&i(e,j.classes.SELECTED)?b._focusInput("minute"):(d.classList.remove(n.classes.TIME_INPUT_ACTIVE),g.classList.remove(n.classes.ACTIVE_CONTAINER),f.classList.remove(n.classes.ACTIVE_CONTAINER))},o._onInputChange=function(a){var b,c=this,d=c._ui,f=c.options,g=a.target.value,h=i(a.target,n.classes.CONTAINER);if(h&&h.classList.contains(n.classes.HOUR_CONTAINER))if(c._inputValueState){if(b=parseInt(g,10),b>d.hourInput.max||b<d.hourInput.min)return void c._setInputValue("hour",c._previousInputValue,!0);c._setInputValue("hour",b,!1),c._focusInput("minute")}else b=parseInt(e(c._previousInputValue,g),10),c._setInputValue("hour",b,!0),("12"===f.format&&b>1||"24"===f.format&&b>2)&&c._focusInput("minute");else if(h&&h.classList.contains(n.classes.MINUTE_CONTAINER))if(c._inputValueState){if(b=parseInt(g,10),b>d.minuteInput.max||b<d.minuteInput.min)return void c._setInputValue("minute",c._previousInputValue,!1);c._setInputValue("minute",b,!1)}else b=parseInt(e(c._previousInputValue,g),10),c._setInputValue("minute",b,!0)},o._onSpinChange=function(a){var b=this,c=i(a.target,n.classes.CONTAINER);c&&c.classList.contains(n.classes.HOUR_CONTAINER)?b._setInputValue("hour",a.detail.value,!1):c&&c.classList.contains(n.classes.MINUTE_CONTAINER)&&b._setInputValue("minute",a.detail.value,!1)},o.handleEvent=function(a){var b=this;switch(a.type){case"click":b._onClick(a);break;case"input":b._onInputChange(a);break;case"spinchange":b._onSpinChange(a)}},o._bindEvents=function(){var a=this,c=a._ui;h.on(b,"click",a),h.on(c.hourInput,"input",a),h.on(c.minuteInput,"input",a),h.on(c.hourSpin,"spinchange",a),h.on(c.minuteSpin,"spinchange",a)},o._unbindEvents=function(){var a=this,c=a._ui;h.off(b,"click",a),h.off(c.hourInput,"input",a),h.off(c.minuteInput,"input",a),h.off(c.hourSpin,"spinchange",a),h.off(c.minuteSpin,"spinchange",a)},o._destory=function(){var a=this,b=a._spins;Object.keys(b).forEach(function(a){b[a]._destory()}),a._unbindEvents()},n.prototype=o,d.widget.mobile.TimePicker=n,g.defineWidget("TimePicker",m,[],n,"mobile")}(a,a.document,a.tau),function(a,b,d){var e=d.widget.mobile.BaseWidgetMobile,f=d.engine,g=d.event,h=d.util.selectors.getClosestByClass,i=d.widget.mobile.Spin,j="ui-date-picker",k={HEADER:j+"-header",CONTENT:j+"-content",CONTAINER:j+"-container",DAY_CONTAINER:j+"-container-day",MONTH_CONTAINER:j+"-container-month",YEAR_CONTAINER:j+"-container-year"},l=["January","February","March","April","May","June","July","August","September","October","November","December"],m=1900,n=2050,o="."+j,p=function(){this.options={view:"wheel"},this._spins={day:null,month:null,year:null},this._ui={header:null}},q=new e;p.classes=k,q._init=function(){var a=this;a._setValue(new Date),a._changeMonth(a._getDateValue("month")),Object.keys(a._spins).forEach(function(b){a._spins[b].refresh()})},q._buildDatePicker=function(a){var c,e=this,f=e._ui,g=b.createElement("div"),h=b.createElement("div"),j={momentumLevel:1};return g.classList.add(i.classes.SPIN),h.classList.add(p.classes.CONTAINER),"day"===a?(j={min:1,max:31,momentumLevel:1},h.classList.add(p.classes.DAY_CONTAINER)):"month"===a?(j={min:1,max:l.length,labels:l.map(function(a){return a.toUpperCase().substring(0,3)}).join(","),momentumLevel:1},h.classList.add(p.classes.MONTH_CONTAINER)):"year"===a&&(j={min:m,max:n,value:2020,momentumLevel:1},h.classList.add(p.classes.YEAR_CONTAINER)),h.appendChild(g),f[a+"Spin"]=g,c=d.widget.Spin(g,j),e._spins[a]=c,h},q._build=function(a){var c=this,d=c._ui,e=b.createElement("div"),f=b.createElement("div"),g=c._buildDatePicker("day"),h=c._buildDatePicker("month"),i=c._buildDatePicker("year");return e.classList.add(p.classes.HEADER),a.appendChild(e),d.header=e,f.classList.add(p.classes.CONTENT),f.appendChild(g),f.appendChild(h),f.appendChild(i),a.appendChild(f),a},q._getValue=function(){return this._value},q._getDateValue=function(a){var b=this._value;switch(a){case"day":return b.getDate();case"month":return b.getMonth()+1;case"year":return b.getFullYear();default:return b}},q._setValue=function(a){var b,c=this,d=c._spins;a instanceof Date&&(c._value=a,Object.keys(d).forEach(function(a){d[a].value(c._getDateValue(a))}),b=l[a.getMonth()]+" "+a.getFullYear(),c._ui.header.innerHTML=b)},q._changeDay=function(a){var b=this,c=b.value();c.setDate(a),b.value(c)},q._dayInMonth=function(a,b){return a===c&&(a=this._getDateValue("year")),b===c&&(b=this._getDateValue("month")),new Date(a,b,0).getDate()},q._changeMonth=function(a){var b,c=this,d=c._spins,e=c.value(),f=e.getDate();b=c._dayInMonth(e.getFullYear(),a),f>b&&(f=b),e.setDate(f),e.setMonth(a-1),d.day.option("max",b),d.day._prevValue=f,d.day._updateItems(),c.value(e)},q._changeYear=function(a){var b,c=this,d=c._spins,e=c.value(),f=e.getMonth(),g=e.getDate();b=c._dayInMonth(a,f+1),g>b&&(g=b),e.setFullYear(a),e.setDate(g),d.day.option("max",b),d.day._updateItems(),c.value(e)},q._onSpinChange=function(a){var b=this,c=h(a.target,p.classes.CONTAINER);c&&c.classList.contains(p.classes.DAY_CONTAINER)?b._changeDay(a.detail.value):c&&c.classList.contains(p.classes.MONTH_CONTAINER)?b._changeMonth(a.detail.value):c&&c.classList.contains(p.classes.YEAR_CONTAINER)&&b._changeYear(a.detail.value)},q.handleEvent=function(a){var b=this;"spinchange"===a.type&&b._onSpinChange(a)},q._bindEvents=function(){var a=this,b=a._ui;g.on(b.daySpin,"spinchange",a,!1),g.on(b.monthSpin,"spinchange",a,!1),g.on(b.yearSpin,"spinchange",a,!1)},q._unbindEvents=function(){var a=this,b=a._ui;g.off(b.daySpin,"spinchange",a,!1),g.off(b.monthSpin,"spinchange",a,!1),g.off(b.yearSpin,"spinchange",a,!1)},p.prototype=q,d.widget.mobile.DatePicker=p,f.defineWidget("DatePicker",o,[],p,"mobile")}(a,a.document,a.tau),function(a,b,d){function e(a,b){var c=b.toString().split(a).join("");return 0===c.length?a:c}var f=d.widget.mobile.BaseWidgetMobile,g=d.engine,h=d.event,i=d.util.selectors.getClosestByClass,j=d.widget.mobile.Spin,k="ui-datetime-picker-wheel",l={WIDGET:k,CONTAINER:k+"-container",HOUR_CONTAINER:k+"-container-hour",MINUTE_CONTAINER:k+"-container-minute",FORMAT_CONTAINER:k+"-container-format",DATE_CONTAINER:k+"-container-date",ACTIVE_CONTAINER:k+"-container-active",TIME_INPUT:k+"-input",TIME_INPUT_ACTIVE:k+"-input-active",SEPARATOR:k+"-container-separator"},m="."+k,n=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],o=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],p=function(){this.options={format:"12",value:(new Date).toUTCString()},this._spins={date:null,hour:null,minute:null,format:null},this._ui={},this._previousInputValue=-1,this._inputValueState=!1},q={SELECTED:"datetimepickerwheelselected",CHANGE:"datetimepickerwheelchange"},r=new f;p.classes=l,r._init=function(){var a=this,b=a.options;b.format=b.format!==c?b.format:"12",a._setValue(b.value),a.option("format",b.format),Object.keys(a._spins).forEach(function(b){a._spins[b].refresh()})},r._build=function(a){var c=this,d=c._buildDatePicker(),e=c._buildDateTimePickerWheel("hour"),f=c._buildDateTimePickerWheel("minute"),g=c._buildFormat(),h=b.createElement("div");return a.classList.add(l.WIDGET),h.classList.add(l.SEPARATOR),a.appendChild(d),a.appendChild(e),a.appendChild(h),a.appendChild(f),a.appendChild(g),a},r._buildDateTimePickerWheel=function(a){var c,e=this,f=e._ui,g=b.createElement("div"),h=b.createElement("input"),i=b.createElement("div"),k={momentumLevel:1};return g.classList.add(j.classes.SPIN),i.classList.add(l.CONTAINER),"hour"===a?("24"===e.options.format?(k.min=0,k.max=23):(k.min=1,k.max=12),i.classList.add(l.HOUR_CONTAINER)):"minute"===a&&(k.min=0,k.max=59,k.digits=2,i.classList.add(l.MINUTE_CONTAINER)),h.min=k.min,h.max=k.max,h.type="number",h.step="1",h.classList.add(l.TIME_INPUT),g.appendChild(h),i.appendChild(g),f[a+"Spin"]=g,f[a+"Input"]=h,f[a+"Container"]=i,c=d.widget.Spin(g,k),e._spins[a]=c,i},r._buildDatePicker=function(a){var c,e,f,g,h=this,i=h._ui,k=b.createElement("div"),m=b.createElement("div"),p={};for(a=a||new Date,g=a.getFullYear(),e=new Date(g.toString()),f=e,k.classList.add(j.classes.SPIN),m.classList.add(l.CONTAINER),m.classList.add(l.DATE_CONTAINER),p.labels=[];f.getFullYear()===g;)p.labels.push(n[f.getDay()]+", "+o[f.getMonth()]+" "+f.getDate()),f.setDate(f.getDate()+1);return p.min=0,p.max=p.labels.length-1,p.loop=!1,p.momentumLevel=1,m.appendChild(k),i.dateSpin=k,i.dateContainer=m,c=d.widget.Spin(k,p),h._spins.date=c,h._year=g,m},r._buildFormat=function(){var a,c=this,e=b.createElement("div"),f=b.createElement("div"),g={min:0,max:1,labels:"AM,PM",loop:"false"};return e.classList.add(j.classes.SPIN),f.classList.add(l.CONTAINER),f.classList.add(l.FORMAT_CONTAINER),f.appendChild(e),a=d.widget.Spin(e,g),c._spins.format=a,f},r._setDateValue=function(a){var b,c,d,e=this,f=e._ui,g=e._spins,h=864e5;b=a.getHours(),c=a.getMinutes(),"12"===e.options.format&&(b>12?(b-=12,g.format.value(1)):g.format.value(0)),f.hourInput.setAttribute("value",b),f.hourInput.value=b,f.minuteInput.setAttribute("value",c),f.minuteInput.value=c,d=new Date(a.getFullYear(),0,1),g.date.value(Math.floor((a-d)/h)),g.hour.value(b),g.minute.value(c),e.options.value=a},r._setInputValue=function(a,b,c){var d=this,e=d._ui,f=d._spins;"hour"===a?(e.hourInput.setAttribute("value",b),e.hourInput.value=b,f.hour.value(b)):"minute"===a&&(e.minuteInput.setAttribute("value",b),e.minuteInput.value=b,f.minute.value(b)),d._previousInputValue=b,d._inputValueState=c},r._focusInput=function(a){var b=this,c=b._ui;"hour"===a?(b.element.classList.add(l.TIME_INPUT_ACTIVE),c.hourContainer.classList.add(l.ACTIVE_CONTAINER),c.minuteContainer.classList.remove(l.ACTIVE_CONTAINER),c.hourInput.focus(),b._previousInputValue=c.hourInput.value):"minute"===a&&(b.element.classList.add(l.TIME_INPUT_ACTIVE),c.minuteContainer.classList.add(l.ACTIVE_CONTAINER),c.hourContainer.classList.remove(l.ACTIVE_CONTAINER),c.minuteInput.focus(),b._previousInputValue=c.minuteInput.value),b._inputValueState=!1},r._setValue=function(a){var b=this;"string"==typeof a&&(a=new Date(a)),a instanceof Date&&b._setDateValue(a)},r._getValue=function(){var a=this,b=new Date(a.options.value),c=a._spins,d=parseInt(c.hour.value(),10);return"12"===a.options.format&&1===c.format.value()&&(d+=12),b.setHours(d),b.setMinutes(parseInt(c.minute.value(),10)),b},r._onClick=function(a){var b=this,c=b._ui,d=b.element,e=a.target,f=c.hourContainer,g=c.minuteContainer,k=i(e,l.CONTAINER);k&&k.classList.contains(l.HOUR_CONTAINER)&&i(e,j.classes.SELECTED)?b._focusInput("hour"):k&&k.classList.contains(l.MINUTE_CONTAINER)&&i(e,j.classes.SELECTED)?b._focusInput("minute"):k&&k.classList.contains(l.DATE_CONTAINER)&&i(e,j.classes.SELECTED)?h.trigger(b.element,q.SELECTED,{datetime:b._getValue()}):(d.classList.remove(l.TIME_INPUT_ACTIVE),g.classList.remove(l.ACTIVE_CONTAINER),f.classList.remove(l.ACTIVE_CONTAINER))},r._onInputChange=function(a){var b,c=this,d=c._ui,f=c.options,g=a.target.value,h=i(a.target,l.CONTAINER);if(h&&h.classList.contains(l.HOUR_CONTAINER))if(c._inputValueState){if(b=parseInt(g,10),b>d.hourInput.max||b<d.hourInput.min)return void c._setInputValue("hour",c._previousInputValue,!0);c._setInputValue("hour",b,!1),c._focusInput("minute")}else b=parseInt(e(c._previousInputValue,g),10),c._setInputValue("hour",b,!0),("12"===f.format&&b>1||"24"===f.format&&b>2)&&c._focusInput("minute");else if(h&&h.classList.contains(l.MINUTE_CONTAINER))if(c._inputValueState){if(b=parseInt(g,10),b>d.minuteInput.max||b<d.minuteInput.min)return void c._setInputValue("minute",c._previousInputValue,!1);c._setInputValue("minute",b,!1)}else b=parseInt(e(c._previousInputValue,g),10),c._setInputValue("minute",b,!0)},r._onSpinChange=function(a){var b=this,c=i(a.target,l.CONTAINER);c&&c.classList.contains(l.HOUR_CONTAINER)?b._setInputValue("hour",a.detail.value,!1):c&&c.classList.contains(l.MINUTE_CONTAINER)?b._setInputValue("minute",a.detail.value,!1):c&&c.classList.contains(l.DATE_CONTAINER)&&b._setDate(new Date(b._year,0,a.detail.value+1)),d.event.trigger(b.element,"datetimepickerwheelchange",{date:b._getValue()})},r._setDate=function(a){var b=new Date(this.options.value);"string"==typeof a&&(a=new Date(a)),a instanceof Date&&(b.setFullYear(a.getFullYear()),b.setMonth(a.getMonth()),b.setDate(a.getDate()),this.options.value=b)},r.handleEvent=function(a){var b=this;switch(a.type){case"vclick":b._onClick(a);break;case"input":b._onInputChange(a);break;case"spinchange":b._onSpinChange(a)}},r._bindEvents=function(){var a=this,b=a._ui;h.on(a.element,"vclick",a),h.on(b.hourInput,"input",a),h.on(b.minuteInput,"input",a),h.on(b.hourSpin,"spinchange",a),h.on(b.minuteSpin,"spinchange",a),h.on(b.dateSpin,"spinchange",a)},r._unbindEvents=function(){var a=this,b=a._ui;h.off(a.element,"vclick",a),h.off(b.hourInput,"input",a),h.off(b.minuteInput,"input",a),h.off(b.hourSpin,"spinchange",a),h.off(b.minuteSpin,"spinchange",a),h.off(b.dateSpin,"spinchange",a)},r._destory=function(){var a=this,b=a._spins;Object.keys(b).forEach(function(a){b[a]._destory()}),a._unbindEvents()},p.prototype=r,d.widget.mobile.DateTimePickerWheel=p,g.defineWidget("DateTimePickerWheel",m,[],p,"mobile")}(a,a.document,a.tau),function(a,b){function d(a){var b=a.insertCell();return b.insertAdjacentHTML("afterbegin","<div></div>"),b.firstChild}var e=b.util.object,f=b.engine,g=b.event,h=["MON","TUE","WED","THU","FRI","SAT","SUN"],i=["January","February","March","April","May","June","July","August","September","October","November","December"],j={WIDGET:"ui-calendar",PREV_MONTH_DAY:"ui-calendar-prev-month-day",NEXT_MONTH_DAY:"ui-calendar-next-month-day",CURRENT_MONTH_DAY:"ui-calendar-current-month-day",DISABLED:"ui-calendar-disabled",ARROW_DISABLED:"ui-calendar-disabled-arrow",SELECTION:"ui-calendar-selection",CONTROLLER:"ui-calendar-controller",ARROW:"ui-calendar-arrow",ARROW_RIGHT:"ui-calendar-right-arrow",ARROW_LEFT:"ui-calendar-left-arrow",ONE_WEEK:"ui-calendar-one-week",TOP_SPACE:"ui-calendar-top-space",SWITCH_VIEW:"ui-calendar-switch",CALENDAR_VIEW:"ui-calendar-view"},k={pastSelection:!1,closeOnSelect:!1},l=function(){var a=this;a.options=e.merge({},k),a._value=new Date,a._dateData=a._value,a._todayYear=a._dateData.getFullYear(),a._todayMonth=a._dateData.getMonth()+1,a._defaultToday=a._dateData.getUTCDate(),a._selectDay=null,a._activeMonth=null,a._fixMonth=null,a._loadTodayFlag=!0,a._hours=a._dateData.getHours(),a._minutes=a._dateData.getMinutes(),a._seconds=a._dateData.getSeconds(),a._ui={"switch":null,leftArrow:null,rightArrow:null,calendarView:null}},m=b.widget.BaseWidget,n=new m;l.prototype=n,l.classes=j,n._init=function(a){var b=this;return b._ui.calendarView=a.querySelector("."+j.CALENDAR_VIEW),b._ui["switch"]=a.querySelector("."+j.SWITCH_VIEW),b._ui.leftArrow=a.querySelector("."+j.ARROW_LEFT),b._ui.rightArrow=a.querySelector("."+j.ARROW_RIGHT),b.options.pastSelection||b._ui.leftArrow.classList.add(j.ARROW_DISABLED),null===b._activeMonth&&(b._fixMonth=b._activeMonth=b._todayMonth),null===b._selectDay&&(b._selectDay=b._defaultToday),b._buildCalendar(b._ui.calendarView),a},n._buildCalendar=function(a){var b,c,e=this,f=e._ui,g=new Date(e._todayYear,e._todayMonth-1,0),h=new Date(e._todayYear,e._todayMonth,0),k=g.getDay(),l=g.getDate(),m=h.getDate(),n=Math.ceil(m/7)+1,o=7,p=1,q=1,r=a.insertRow(),s=null;for(r.style.height="7px",b=1;n+1>b;b++){for(c=a.insertRow();0!=k;)k-=1,o-=1,s=d(c),s.classList.add(j.PREV_MONTH_DAY),s.innerHTML=l-k,e._fixMonth!==e._todayMonth||e.options.pastSelection||s.classList.add(j.DISABLED);for(;0!=o;)s=d(c),p>m?(s.classList.add(j.NEXT_MONTH_DAY),s.innerHTML=q,o-=1,q+=1):(s.innerHTML=p,s.classList.add(j.CURRENT_MONTH_DAY),p+=1,o-=1,e._defaultToday>parseInt(s.innerHTML,10)&&(e._fixMonth!==e._todayMonth||e.options.pastSelection||s.classList.add(j.DISABLED)),e._loadTodayFlag&&s.innerHTML===e._defaultToday.toLocaleString()?(s.classList.add(j.SELECTION),e._selectDay=s,e._activeMonth=e._todayMonth,e._loadTodayFlag=!1):e._activeMonth===e._todayMonth&&s.innerHTML===e._selectDay.innerHTML&&(s.classList.add(j.SELECTION),e._selectDay=s));o=7}e.options.pastSelection||f.leftArrow.classList.toggle(j.DISABLED,e._fixMonth==e._todayMonth),f["switch"].innerHTML=i[e._todayMonth-1]+" "+e._todayYear},n._deleteCalendar=function(a){for(;a.rows.length>2;)a.deleteRow(2)},n._onClick=function(a){var b=this,c=b._ui,d=a.target,e=d.classList;e.contains(j.DISABLED)||(d===c.rightArrow?b._moveMonth(1):d===c.leftArrow?b._moveMonth(-1):d===c["switch"]?g.trigger(b.element,"calendarswitch",{date:b._getValue()}):("TD"===d.tagName&&(d=d.querySelector("div"),e=d?d.classList:null),!e||e.contains(j.SELECTION)||e.contains(j.DISABLED)||(e.contains(j.PREV_MONTH_DAY)?(b._moveMonth(-1),b._selection(d.innerHTML),b.options.closeOnSelect&&g.trigger(b.element,"calendarswitch",{date:b._getValue()})):e.contains(j.NEXT_MONTH_DAY)&&(b._moveMonth(1),b._selection(d.innerHTML),b.options.closeOnSelect&&g.trigger(b.element,"calendarswitch",{date:b._getValue()})),e.contains(j.CURRENT_MONTH_DAY)&&(b._selection(d.innerHTML),b.options.closeOnSelect&&g.trigger(b.element,"calendarswitch",{date:b._getValue()})))))},n._setValue=function(a){var b=this;"string"==typeof a&&(a=new Date(a)),a instanceof Date&&(b._value=a,b._hours=a.getHours(),b._minutes=a.getMinutes(),b._seconds=a.getSeconds(),b._setMonth(a.getMonth()+1),b._selection(a.getDate()))},n._getValue=function(){return new Date(this._value)},n._moveMonth=function(a){var b=this;0!==a&&(b._todayMonth=b._todayMonth+a,0===b._todayMonth&&(b._todayMonth=12,b._todayYear=b._todayYear-1),13===b._todayMonth&&(b._todayMonth=1,b._todayYear=b._todayYear+1)),b._updateCalendar()},n._setYear=function(a){var b=this;b._todayYear!==a&&(b._todayYear=a,b._updateCalendar())},n._setMonth=function(a){var b=this;b._todayMonth!==a&&(b._todayMonth=a,b._updateCalendar())},n._updateCalendar=function(){var a=this,b=a._ui.calendarView;a._deleteCalendar(b),a._dateData=new Date(a._todayYear,a._todayMonth-1,0,a._hours,a._minutes,a._seconds),a._buildCalendar(b)},n._selection=function(a){var b,d,e=this;a!=c&&(d=a.toString(),b=e._ui.calendarView.querySelectorAll("div."+j.CURRENT_MONTH_DAY),b.forEach(function(a){a.innerHTML===d&&(e._selectDay.classList.remove(j.SELECTION),a.classList.add(j.SELECTION),e._selectDay=a,e._activeMonth=e._todayMonth)}),e._value=new Date(e._todayYear,e._todayMonth-1,a,e._hours,e._minutes,e._seconds))},n._unBindEvents=function(a){g.off(a,"vclick",this,!1)},n._bindEvents=function(a){g.on(a,"vclick",this,!1)},n.handleEvent=function(a){"vclick"===a.type?this._onClick(a):a.preventDefault()},n._setPastSelection=function(a,b){return this.options.pastSelection=b,!0},n._refresh=function(){var a=this,b=a._ui.calendarView;a._deleteCalendar(b),a._buildCalendar(b)},n._build=function(b){var c=a.createElement("div"),d=a.createElement("div"),e=a.createElement("div"),f=a.createElement("div"),g=a.createElement("table"),i=a.createElement("tr"),k=a.createElement("tr"),l=a.createElement("td"),m=a.createElement("td"),n=a.createElement("td"),o=a.createElement("td"),p=a.createElement("td"),q=a.createElement("td"),r=a.createElement("td");return b.classList.add(j.WIDGET),c.classList.add(j.CONTROLLER),d.classList.add(j.ARROW_LEFT),d.classList.add(j.ARROW),e.classList.add(j.ARROW_RIGHT),e.classList.add(j.ARROW),f.classList.add(j.SWITCH_VIEW),c.appendChild(d),c.appendChild(e),c.appendChild(f),g.classList.add(j.CALENDAR_VIEW),i.classList.add(j.TOP_SPACE),k.classList.add(j.ONE_WEEK),l.innerHTML=h[0],k.appendChild(l),m.innerHTML=h[1],k.appendChild(m),n.innerHTML=h[2],k.appendChild(n),o.innerHTML=h[3],k.appendChild(o),p.innerHTML=h[4],k.appendChild(p),q.innerHTML=h[5],k.appendChild(q),r.innerHTML=h[6],r.classList.add("ui-sunday"),k.appendChild(r),g.appendChild(i),g.appendChild(k),b.appendChild(c),b.appendChild(g),b},n._destroy=function(){var a=this;a.options=null,a._unBindEvents(a.element)},b.widget.mobile.Calendar=l,f.defineWidget("Calendar",".ui-calendar",[],l,"mobile")}(b,d),function(a,b,d){var e=d.widget.mobile.BaseWidgetMobile,f=d.engine,g=(d.event,"ui-datetime-picker"),h={CONTAINER:g+"-container",HIDDEN:g+"-hidden"},i="."+g,j=function(){var a=this;a.options={format:"12",view:"wheel",value:(new Date).toUTCString()},a._datetime=null,a._calendar=null,a._ui={datetime:null,calendar:null}},k={CHANGE:"datetimepickerchange"},l=new e;j.classes=h,l._init=function(){var a=this,b=a.options;b.format=b.format!==c?b.format:"12",a._setValue(b.value),a.option("format",b.format),a._setView(a.element,b.view)},l._build=function(a){var c=this,e=c._ui,f=b.createElement("div"),g=b.createElement("div");return a.appendChild(f),a.appendChild(g),c._datetime=d.widget.DateTimePickerWheel(f),c._calendar=d.widget.Calendar(g,{closeOnSelect:!0}),e.datetime=f,e.calendar=g,a},l._onDateTimeSelected=function(a){var b=this;a.target===b._ui.datetime&&(b._calendar.value(a.detail.datetime),b._setView(b.element,"calendar"))},l._onCalendarSwitch=function(a){var b=this;a.target===b._ui.calendar&&(b._datetime.value(a.detail.date),b._setView(b.element,"wheel"),d.event.trigger(b.element,k.CHANGE,{date:b._getValue()}))},l._setView=function(a,b){var c=this._ui;this.options.view=b,"wheel"===b?(c.calendar.classList.add(h.HIDDEN),c.datetime.classList.remove(h.HIDDEN)):"calendar"===b&&(c.datetime.classList.add(h.HIDDEN),c.calendar.classList.remove(h.HIDDEN))},l._setValue=function(a){var b=this;"string"==typeof a&&(a=new Date(a)),a instanceof Date&&(b._datetime.value(a),b._calendar.value(a),b.options.value=a)},l._getValue=function(){var a=this;return"wheel"===a.options.view?a._datetime.value():"calendar"===a.options.view?a._calendar.value():a.options.value},l._onDateTimeChange=function(a){var b=this;b.options.value=a.detail.datetime,d.event.trigger(b.element,k.CHANGE,{date:b._getValue()})},l._setFormat=function(a,b){var c=this;c.options.format=b,c._datetime.option("format",b)},l._getFormat=function(){return self._datetime.option("format")},l.handleEvent=function(a){var b=this;switch(a.type){case"datetimepickerwheelselected":b._onDateTimeSelected(a);break;case"calendarswitch":b._onCalendarSwitch(a);break;case"datetimepickerwheelchange":b._onDateTimeChange(a)}},l._bindEvents=function(){var a=this;a.element.addEventListener("datetimepickerwheelselected",this,!1),a.element.addEventListener("datetimepickerwheelchange",this,!1),a.element.addEventListener("calendarswitch",this,!1)},l._unbindEvents=function(){var a=this;a.element.removeEventListener("datetimepickerwheelselected",this,!1),a.element.removeEventListener("calendarswitch",this,!1)},l._destory=function(){var a=this,b=a._ui,c=a.element;a._unbindEvents(),a._calendar.destory(),a._datetime.destory(),c.removeChild(b.datetime),c.removeChild(b.calendar)},j.prototype=l,d.widget.mobile.DateTimePicker=j,f.defineWidget("DateTimePicker",i,[],j,"mobile")}(a,a.document,a.tau),function(a,b){var c=b.widget.mobile.BaseWidgetMobile,d=b.engine,e=b.event,f="ui-color-",g=/ui-color-[^\s]+/g,h=function(){var a=this;a.options={icon:"delete"},a._ui={text:null,button:null}},i={widget:"ui-chip",text:"ui-chip-text",button:"ui-chip-button"},j={BEFORE_REMOVE:"chipbeforeremove"},k={widget:"."+i.widget+", [data-role='chip']",text:"."+i.text,button:"."+i.button},l=new c;h.prototype=l,h.classes=i,h.events=j,l._onClick=function(){var a,b=this;a=e.trigger(b.element,j.BEFORE_REMOVE),a&&b.element.parentElement.removeChild(b.element),b.destroy()},l.handleEvent=function(a){"vclick"===a.type&&this._onClick(a)},l._build=function(b){var c,d,e=this,f=e._ui;return d=b.querySelector(k.button),d&&b.removeChild(d),c=b.querySelector(k.text)||b.querySelector("*:not("+k.button+")"),c?b.removeChild(c):(c=a.createElement("span"),c.className=i.text,c.innerHTML=b.textContent),b.textContent="",d||(d=a.createElement("button"),d.className=["ui-btn",i.button].join(" "),d.setAttribute("data-icon","minus"),
+d.setAttribute("data-style","flat")),b.appendChild(c),b.appendChild(d),f.text=c,f.button=d,b},l._updateButtonColor=function(){var a,b=this,c=b._ui.button,d=f+b.options.icon;a=c.className.match(g)||[],a.forEach(function(a){a!==d&&c.classList.remove(a)}),-1===a.indexOf(d)&&c.classList.add(d)},l._init=function(a){var c=this,d=c._ui;return d.text=d.text||a.querySelector(k.text),d.button=d.button||a.querySelector(k.button),b.widget.Button(d.button,{icon:c.options.icon}),c._updateButtonColor(),a},l._bindEvents=function(){var a=this,b=a._ui.button;e.on(b,"vclick",a,!1)},l._unbindEvents=function(){var a=this,b=a._ui.button;e.off(b,"vclick",a,!1)},l._destroy=function(){var b=this;b._unbindEvents(),b._ui=null,e.trigger(a,"destroyed",{widget:"Chip"})},b.widget.mobile.Chip=h,d.defineWidget("Chip",k.widget,[],h,"mobile")}(a.document,d),function(a,b,d){function e(a,b,c){var e,f=null,g=null;a.options.handler&&(f=a.ui.handle.style,d.support.shape.circle?(e=a._offsets,g="rotateZ("+(c/e.maxY*z-z/2||0)+"deg)"):g="translate3d("+(b||0)+"px, "+(c||0)+"px, 0px)",f.webkitTransform=g,f.mozTransform=g,f.msTransform=g,f.oTransform=g,f.transform=g)}function f(a){var b=a.getScrollPosition(),c=a._offsets,d=a.options.direction,f=C(B(b.x,a._availableOffsetX)/a._availableOffsetX*c.maxX),g=C(B(b.y,a._availableOffsetY)/a._availableOffsetY*c.maxY);isNaN(f)===!0&&(f=c.x),isNaN(g)===!0&&(g=c.y),e(a,"y"===d?0:f,"x"===d?0:g),c.x=f,c.y=g}function g(b){b._dragging===!1&&(f(b),b._hideTimer&&a.clearTimeout(b._hideTimer),b.ui.handler.classList.add(D.visible))}function h(b){b._dragging===!1&&(b._hideTimer&&a.clearTimeout(b._hideTimer),f(b))}function i(b){b._dragging===!1&&(f(b),b._hideTimer&&a.clearTimeout(b._hideTimer),b._hideTimer=a.setTimeout(function(){b.ui.handler.classList.remove(D.visible)},b.options.delay))}function j(b,c,d){var f=b._lastMouse,g=b._offsets,h=b.options.direction,i=f.x-c,j=f.y-d;f.x=c,f.y=d,g.x+=-i,g.y+=-j,g.x=A(0,g.x),g.y=A(0,g.y),g.x=B(g.maxX,g.x),g.y=B(g.maxY,g.y),e(b,"y"===h?0:g.x,"x"===h?0:g.y),b.scrollTo("y"===h?0:g.x/g.maxX*b._availableOffsetX,"x"===h?0:g.y/g.maxY*b._availableOffsetY),b._hideTimer&&a.clearTimeout(b._hideTimer)}function k(b,c){var d=b._lastMouse,e=c.touches,f=e&&e[0];b._hideTimer&&a.clearTimeout(b._hideTimer),b._dragging=!0,d.x=f?f.clientX:c.clientX,d.y=f?f.clientY:c.clientY,b.ui.handle.classList.add("ui-active"),"y"===b.options.direction?b.element.style.overflowY="hidden":b.element.style.overflowX="hidden",p.stopImmediatePropagation(c),p.preventDefault(c)}function l(a,b){var d=b.touches,e=d&&d[0],f=0,g=0;a._dragging&&(d===c||d.length<=1)&&(p.stopImmediatePropagation(b),p.preventDefault(b),f=e?e.clientX:b.clientX,g=e?e.clientY:b.clientY,j(a,f,g))}function m(b,c){var d=b.ui;b._dragging&&(b._dragging=!1,p.stopImmediatePropagation(c),p.preventDefault(c),"y"===b.options.direction?b.element.style.overflowY="auto":b.element.style.overflowX="auto",d.handle.classList.remove("ui-active"),b._hideTimer&&a.clearTimeout(b._hideTimer),b._hideTimer=a.setTimeout(function(){d.handler.classList.remove(D.visible)},b.options.delay))}var n=function(){var a=this;a.options={handler:!0,handlerTheme:"s",direction:"y",scroll:"y",delay:1500},a.ui={handler:null,thumb:null,track:null,handle:null,expander:null,page:null},a._callbacks={scrolstart:null,scrollupdate:null,scrollend:null,touchstart:null,touchmove:null,touchend:null,resize:null},a._dragging=!1,a._offsets={x:0,y:0,maxX:0,maxY:0},a._lastPointerEvents="",a._availableOffsetX=0,a._availableOffsetY=0,a._hideTimer=null,a._lastMouse={x:0,y:0}},o=d.engine,p=d.event,q=d.util.DOM,r=d.util.selectors,s=d.widget.core.Page.classes,t=d.widget.core.Scrollview,u=t.prototype,v=u._build,w=u._init,x=u._bindEvents,y=u._destroy,z=60,A=Math.max,B=Math.min,C=Math.floor,D={handler:"ui-handler",directionPrefix:"ui-handler-direction-",track:"ui-handler-track",handle:"ui-handler-handle",thumb:"ui-handler-thumb",expander:"ui-handler-expander",visible:"ui-handler-visible",themePrefix:"ui-handler-",scrollbarDisabled:"scrollbar-disabled",disabled:"disabled",hideNativeScrollbar:"ui-hide-scrollbar"},E=new t;n.classes=D,E._build=function(a){var c,d,e,f=b.createElement("div"),g=b.createElement("a"),h=b.createElement("span"),i=b.createElement("div"),j=b.createElement("span"),k=this.options,l=this.ui;return k.scroll="y"===k.direction?"y":"x",c=v.call(this,a),f.className=D.handler+" "+D.themePrefix+k.handlerTheme+" "+D.directionPrefix+k.direction,h.className=D.expander,g.className=D.handle,j.className=D.thumb,i.className=D.track,g.setAttribute("aria-label",("y"===k.direction?"Vertical":"Horizontal")+" handler, double tap and move to scroll"),h.appendChild(j),g.appendChild(h),i.appendChild(g),f.appendChild(i),c.appendChild(f),d=c.style,e=c.firstElementChild.style,a.classList.add(D.hideNativeScrollbar),"x"===k.direction&&(e.display="inline-block",e.minWidth="100%"),"y"===k.direction&&(e.display="block",d.minWidth="100%"),l.handler=f,l.handle=g,l.expander=h,l.track=i,l.thumb=j,c},E._init=function(a){var b=this,c=b.ui,d=c.page;w.call(b,a),null===c.handler&&(c.handler=a.querySelector("."+D.handler)),null===c.track&&(c.track=a.querySelector("."+D.track)),null===c.handle&&(c.handle=a.querySelector("."+D.handle)),null===c.thumb&&(c.thumb=a.querySelector("."+D.thumb)),null===d&&(d=r.getClosestByClass(a,s.uiPage)),c.page=d,b.enableHandler(!0)},E._refresh=function(){var a=this,b=a.element,c=a._offsets,d=a.ui,e=d.handle,f=e.style,g=d.track.getBoundingClientRect(),h=g.height,i=g.width,j=b.querySelector("."+t.classes.view),k=j.getBoundingClientRect(),l=k.height,m=k.width;"y"===a.options.direction?f.height=C(h/l*h)+"px":f.width=C(i/m*i)+"px",c.maxX=C(A(0,i-q.getElementWidth(e,"inner",!0))),c.maxY=C(A(0,h-q.getElementHeight(e,"inner",!0))),a._availableOffsetX=A(0,m-i),a._availableOffsetY=A(0,l-h)},E._bindEvents=function(c){var d=this,e=d._callbacks,f=d.ui;x.call(d,c),e.scrollstart=g.bind(null,d),e.scrollupdate=h.bind(null,d),e.scrollstop=i.bind(null,d),e.touchstart=k.bind(null,d),e.touchmove=l.bind(null,d),e.touchend=m.bind(null,d),e.resize=d._refresh.bind(d),c.addEventListener("scrollstart",e.scrollstart,!1),c.addEventListener("scrollupdate",e.scrollupdate,!1),c.addEventListener("scrollstop",e.scrollstop,!1),f.handle.addEventListener("vmousedown",e.touchstart,!1),f.page.addEventListener("pageshow",e.resize,!1),b.addEventListener("vmousemove",e.touchmove,!1),b.addEventListener("vmouseup",e.touchend,!1),a.addEventListener("throttledresize",e.resize,!1),b.addEventListener("touchcancel",e.touchend,!0)},E.enableHandler=function(a){var b=this,d=D.scrollbarDisabled,e=D.disabled,f=b.element,g=f.parentNode.classList,h=f.classList;return a!==c&&(b.options.handler=a,a?(g.add(d),h.remove(e),b._refresh()):(g.remove(d),h.add(e))),b.options.handler},E._setHandlerTheme=function(a){var b=this.element.classList,c=D.themePrefix,d=c+a;b.contains(d)===!1&&(b.remove(c+this.options.handlerTheme),b.add(d))},E._destroy=function(){var c=this,d=c.ui,e=c._callbacks,f=c.element;f.classList.remove(D.hideNativeScrollbar),f.removeEventListener("scrollstart",e.scrollstart,!1),f.removeEventListener("scroll",e.scrollupdate,!1),f.removeEventListener("scrollstop",e.scrollstop,!1),d.handle.removeEventListener("vmousedown",e.touchstart,!1),d.page.removeEventListener("pageshow",e.touchstart,!1),b.removeEventListener("vmousemove",e.touchmove,!1),b.removeEventListener("vmouseup",e.touchend,!1),b.removeEventListener("touchcancel",e.touchend,!0),a.removeEventListener("throttledresize",e.resize,!1),y.call(c)},n.prototype=E,d.widget.core.ScrollHandler=n,o.defineWidget("ScrollHandler","[data-role='content'][data-handler='true']:not([data-scroll='none']):not(.ui-scrollview-clip):not(.ui-scrolllistview),[data-handler='true'], .ui-scrollhandler",["enableHandler","scrollTo","ensureElementIsVisible","centerToElement","getScrollPosition","skipDragging","translateTo"],n,"tizen")}(a,a.document,d),function(b,c){function d(b){var c=this;j.on(b,"tabchange sectionchange",c,!1),a.addEventListener("resize",c,!1)}function e(b){var c=this;j.off(b,"tabchange sectionchange",c,!1),a.removeEventListener("resize",c,!1)}var f=c.widget.BaseWidget,g=c.engine,h=c.util.selectors,i=c.widget.core.Page,j=c.event,k=function(){var a=this;a._ui={},a._component={},a.options={changeDuration:200}},l={TABS:"ui-tabs",WITH_TITLE:"ui-tabs-with-title",TITLE:"ui-title",PAGE:i.classes.uiPage},m=new f;k.prototype=m,k.classes=l,m.handleEvent=function(a){var b=this;switch(a.type){case"tabchange":b._onTabChange(a);break;case"sectionchange":b._onSectionChange(a);break;case"resize":b._refresh()}},m._build=function(a){return a.classList.add(l.TABS),a.getElementsByClassName(l.TITLE).length&&a.classList.add(l.WITH_TITLE),a},m._initHeight=function(){var a,b=this;b.element.style.height||(a=c.widget.Page(b._ui.page),b.element.style.height=a.getContentHeight()+"px")},m._init=function(a){var b=this,d=b._ui;return d.page=h.getClosestByClass(a,l.PAGE),d.subtab=a.querySelector(c.widget.core.SubTab.selector),d.title=a.getElementsByClassName(l.TITLE)[0],d.sectionChanger=a.querySelector("[data-role='section-changer'], .ui-section-changer"),b._component.subtab=c.widget.SubTab(d.subtab),b._changed=!1,b._lastIndex=0,b._initHeight(),b._initSectionChanger(),a},m._initSectionChanger=function(){var b,c=this,d=c._ui,e=d.sectionChanger,f=d.subtab.offsetHeight,h=d.title;e&&(b=e.style,b.width=a.innerWidth+"px",b.height=c.element.offsetHeight-f-(h?h.offsetHeight:0)+"px",c._component.sectionChanger=g.instanceWidget(e,"SectionChanger"))},m._onTabChange=function(a){var b=this,c=a.detail.active,d=b._component.sectionChanger;b._changed?b._changed=!1:b._lastIndex!==c&&(b._changed=!0,d.setActiveSection(c,b.options.changeDuration,!1,!1)),b._lastIndex=c},m._onSectionChange=function(a){var b=this,c=a.detail.active,d=b._component.subtab;b._changed?b._changed=!1:b._lastIndex!==c&&(b._changed=!0,d.setActive(c)),b._lastIndex=c},m._bindEvents=function(){var a=this;d.call(a,a.element)},m._destroy=function(){var a=this;e.call(a,a.element),a._ui=null,a._component=null},m._refresh=function(){this._initSectionChanger()},m._setIndex=function(a){var b=this,d=b._ui.sectionChanger.getElementsByTagName("section").length;d>a&&!(0>a)?b._component.subtab.setActive(a):c.warn("You inserted the wrong index value")},m.setIndex=function(a){this._setIndex(a)},m._getIndex=function(){return this._lastIndex},m.getIndex=function(){return this._getIndex()},c.widget.core.Tabs=k,g.defineWidget("Tabs","[data-role='tabs'], .ui-tabs",["setIndex","getIndex"],k,"core")}(a.document,d),function(b,c){function d(a){for(var c;a!==b.body;){if(c=m.getCSSProperty(a,"overflow-y"),"scroll"===c||"auto"===c&&a.scrollHeight>a.clientHeight)return a;a=a.parentNode}return null}function e(a){a._setItemSize(),a._checkItemLabel(),a._setGridStyle(),a._refreshItemsInfo(),a._calculateListHeight(),a._inPopup.refresh()}function f(a){var b=a.target.classList;b.contains(z.ITEM)&&(b.add(z.ITEM_ACTIVE),a.target.style.animation="")}function g(a){a._setGridStyle()}var h=c.widget.BaseWidget,i=c.widget.core.BaseKeyboardSupport,j=c.engine,k=c.event,l=c.util.selectors,m=c.util.DOM,n=c.widget.core.Page.events,o=c.widget.mobile.Popup,p=c.widget.Popup,q=o.selector,r=o.events,s=".ui-gridview li:nth-child({index})",t=/matrix\((.*), (.*), (.*), (.*), (.*), (.*)\)/,u="data-role",v=300,w=16,x={PREV:0,NEXT:1},y={IN:"in",OUT:"out",NONE:"none"},z={GRIDLIST:"ui-gridview",ITEM:"ui-gridview-item",ITEM_ACTIVE:"ui-gridview-item-active",HELPER:"ui-gridview-helper",HOLDER:"ui-gridview-holder",IMAGE:"ui-gridview-image",LABEL:"ui-gridview-label",LABEL_IN:"ui-gridview-label-in",LABEL_OUT:"ui-gridview-label-out",HANDLER:"ui-gridview-handler",CHECKED:"ui-gridview-image-checked",ITEM_HAS_LABEL:"ui-gridview-item-has-label"},A={ANY_NOT_IMAGE:"*:not(."+z.IMAGE+")"},B=function(){var a=this;i.call(this),a.options={},a._direction=0,a._styleElement=null,a._inPopup=null,a._ui={listElements:[],listItems:[],helper:{},holder:{},scrollableParent:null,content:null},a._borderSize=w,a._refreshSizesCallback=e.bind(null,this)},C=new h;B.prototype=C,B.classes=z,C._configure=function(){this.options={cols:0,reorder:!1,label:y.NONE,minWidth:"auto",minCols:2,maxCols:5},this._direction=x.NEXT},C._build=function(a){return a.classList.add("ui-gridview-cols"),a},C._init=function(b){var c,e=this,f=e._ui;f.listElements=[].slice.call(e.element.getElementsByTagName("li")),e._setItemSize(),e._setLabel(b),e._checkItemLabel(),e._setReorder(b,e.options.reorder),e._calculateListHeight(),e._initCheckboxState(b),e._ui.content=l.getClosestByClass(b,"ui-content")||a,e._ui.scrollableParent=d(b)||e._ui.content,c=l.getClosestBySelector(b,q),c&&(e._inPopup=p(c))},C._onResize=function(){var a=this;a.options.cols=0,a.refresh()},C._onResizeTimeOut=function(){var b=this;clearTimeout(b._resizeTimeout),b._resizeTimeout=a.setTimeout(function(){b._onResize()},v)},C._bindEvents=function(){var b=this,c=b._getParentPage(b.element),d=this._inPopup;b._onSetGridStyle=g.bind(null,b),d&&k.on(d.element,r.transition_start,b._refreshSizesCallback),b.on("animationend webkitAnimationEnd",f),b.on("change",b),k.on(a,"resize",b,!0),k.on(c,n.SHOW,b._onSetGridStyle)},C._unbindEvents=function(){var a=this,b=a.element,c=a._getParentPage(b),d=a._inPopup;k.disableGesture(b),k.off(b,"drag dragstart dragend dragcancel dragprepare",a),k.off(b,"pinchin pinchout",a),d&&k.off(d.element,r.before_show,this._refreshSizesCallback),a.off("animationend webkitAnimationEnd",f),a.off("change",a),k.off(c,n.SHOW,a._onSetGridStyle)},C._refresh=function(){var b=this,c=b._ui,e=b.element;b._removeGridStyle(),c.listElements=[].slice.call(e.getElementsByTagName("li")),b._setItemSize(),b._setGridStyle(),b._setLabel(e),b._checkItemLabel(),b._setReorder(e,b.options.reorder),b._calculateListHeight(),b._ui.content=l.getClosestByClass(e,"ui-content")||a,b._ui.scrollableParent=d(e)||b._ui.content},C._destroy=function(){this._unbindEvents(),this._removeGridStyle(),this._inPopup=null},C.handleEvent=function(a){var b=this;switch(a.type){case"change":b._shadeCheckbox(a.target);break;case"dragprepare":if(a.detail.srcEvent.srcElement.classList.contains(z.HANDLER))break;a.preventDefault();break;case"dragstart":if(a.detail.srcEvent.srcElement.classList.contains(z.HANDLER)){b._start(a);break}a.preventDefault();break;case"drag":b._move(a);break;case"dragend":b._end(a);break;case"pinchin":b._in(a);break;case"pinchout":b._out(a);break;case"resize":b._onResizeTimeOut()}},C._start=function(b){var c,d=this,e=d.element,f=d._ui.helper,g=b.detail.srcEvent.srcElement.parentElement,h=a.getComputedStyle(g,null),i=g.style,j=h.getPropertyValue("webkit-transform")||h.getPropertyValue("transform")||"",k=j.match(t),l=0,m=0;d._refreshItemsInfo(),k.length>0&&(l=parseInt(k[6],10),m=parseInt(k[5],10)),g.classList.add(z.HELPER),c=d._createHolder(),e.insertBefore(c,g),e.appendChild(g),i.top=l+"px",i.left=m+"px",f.element=g,f.style=i,f.position={startTop:l,startLeft:m,moveTop:l,moveLeft:m},f.startX=b.detail.estimatedX,f.startY=b.detail.estimatedY,f.width=parseFloat(h.getPropertyValue("width"))||0,f.height=parseFloat(h.getPropertyValue("height"))||0,d._ui.holder=c,f.element=g,d._ui.helper=f},C._move=function(a){var b,c,d,e,f,g,h=this,i=h._ui,j=h.element,k=i.listItems,l=k.length,m=h._ui.helper,n=m.style,o=m.position,p=m.element,q=m.startX,r=m.startY,s=h._ui.scrollableParent;for(c=o.startTop+a.detail.estimatedY-r,b=o.startLeft+a.detail.estimatedX-q,e=j.offsetTop+c+p.offsetHeight-(s.offsetHeight+s.scrollTop),f=s.scrollTop-(j.offsetTop+c),g=p.offsetHeight/5,e>0&&p.offsetTop+p.offsetHeight<j.offsetHeight&&(s.scrollTop+=g,c+=g,o.startTop+=g),f>0&&p.offsetTop>0&&(s.scrollTop-=g,c-=g,o.startTop-=g),n.top=c+"px",n.left=b+"px",o.moveTop=c,o.moveLeft=b,d=0;l>d;d++)h._compareOverlapItem(k[d])&&(h._direction?j.insertBefore(i.holder,k[d].element.nextSibling):j.insertBefore(i.holder,k[d].element),h._refreshItemsInfo(),h._setItemMargin())},C._end=function(){var a=this,b=a.element,c=a._ui.helper,d=c.element,e=a._ui.holder;d.classList.remove(z.HELPER),c.style.top=0,c.style.left=0,b.insertBefore(d,e),b.removeChild(e),a._setItemMargin(),a._ui.helper={}},C._out=function(){var a=this,b=a.options,c=b.cols,d=b.minCols;c>d&&(a._minWidth=null,b.cols=c-1,a._refresh())},C._in=function(){var a=this,b=a.options,c=b.cols,d=b.maxCols;(null===d||d>c)&&(b.cols=c+1,a._minWidth=null,a._refresh())},C._compareOverlapItem=function(a){var b,c,d=this,e=d._ui.helper,f=e.position;return e.element===a.element?!1:(f.moveTop>a.top||f.moveTop===a.top&&f.moveLeft>a.left?d._direction=x.PREV:d._direction=x.NEXT,b=f.moveTop>a.top?a.top+a.height-f.moveTop:f.moveTop+e.height-a.top,c=f.moveLeft>a.left?a.left+a.width-f.moveLeft:f.moveLeft+e.width-a.left,0>=b||0>=c?!1:b*c>a.height*a.width/2?!0:!1)},C._calculateListHeight=function(){var b,c,d=this,e=d._ui.listElements,f=e.length&&a.getComputedStyle(e[0],null);c=Math.ceil(e.length/d.options.cols),b=parseFloat(f.getPropertyValue("height"))||0,"out"===d.element.getAttribute("data-label")?d.element.style.height=b*c+"px":d.element.style.height=(b+1)*c+1+"px"},C._initCheckboxState=function(a){var b=a.querySelectorAll("input[type=checkbox]"),c=0,d=this,e=b.length;for(c=0;e>c;c++)d._shadeCheckbox(b[c])},C._shadeCheckbox=function(a){a.parentElement.classList.toggle(z.CHECKED,a.checked)},C._refreshItemsInfo=function(){var b,c,d,e=this,f=e._ui.listElements,g=f.length,h=[],i=0,j=null,k=0,l="";for(d=0;g>d;d++)c=f[d],j=a.getComputedStyle(c,null),l=j.getPropertyValue("webkit-transform")||j.getPropertyValue("transform")||"",b=l.match(t),b&&b.length>0&&(i=parseInt(b[6],10),k=parseInt(b[5],10)),h.push({top:i,left:k,height:parseFloat(j.getPropertyValue("width"))||0,width:parseFloat(j.getPropertyValue("width"))||0,element:c});e._ui.listItems=h},C._createHolder=function(){var a=b.createElement("li"),c=a.classList;return c.add(z.ITEM),c.add(z.HOLDER),a},C._setItemMargin=function(){var a,b=this,c=b.options,d=[].slice.call(b.element.getElementsByTagName("li")),e=d.length,f=c.cols,g=null,h=b._borderSize;for(a=0;e>a;a++)g=d[a].style,f-1>a%f?g.marginRight=h+"px":g.marginRight="0",a>f-1?g.marginTop=h+"px":g.marginTop="0"},C._setItemSize=function(){var b,c,d,e,f=this,g=f.options,h=a.getComputedStyle(f.element,null),i=parseFloat(h.getPropertyValue("width"))||0,j=f._minWidth,k=f._ui.listElements,l=k.length,m=f._borderSize,n=null;for(j="auto"===g.minWidth?0:j?parseInt(j,10):null,f._minWidth=j,b=g.cols,0===b&&(e=a.getComputedStyle(f.element,":after").content,e=e.replace(/[^0-9]+/,""),e&&(b=parseInt(e.replace(/\"/g,""),10))),0===b&&j>0&&(b=j?Math.floor(i/j):b),0===b&&(b=g.minCols),g.cols=b,f._itemSize=(i-(b-1)*m)/b,f._itemHeight=f._itemSize,d=f._itemSize+"px",f._setItemMargin(),c=0;l>c;c++)n=k[c].style,n.width=d,n.height=d;for(c=0;l>c;c++)k[c].querySelector("*:not(img)")&&k[c].classList.add(z.ITEM_HAS_LABEL)},C._checkItemLabel=function(){var a,b=this,c=b._ui.listElements,d=c.length;for(a=0;d>a;a++)c[a].querySelector(A.ANY_NOT_IMAGE)&&c[a].classList.add(z.ITEM_HAS_LABEL)},C._getParentPage=function(a){for(;a&&a!==b.body;){if("page"===a.getAttribute(u)||a.classList.contains("ui-page")===!0)return a;a=a.parentNode}return b.body},C._setReorder=function(a,d){var e,f,g=this,h=g.options,i=g._getParentPage(a);k.disableGesture(a),d?(k.enableGesture(a,new k.gesture.Drag({blockVertical:!1})),k.on(a,"drag dragstart dragend dragcancel dragprepare",g,!0),k.off(a,"pinchin pinchout",g),a.classList.add("ui-gridview-reorder"),g._ui.listElements.forEach(function(a){var c=null;a.querySelector("."+z.HANDLER)||(c=b.createElement("div"),c.classList.add(z.HANDLER),a.appendChild(c))}),i&&(e=i.querySelector(c.widget.core.Appbar.selector),e&&(f=c.widget.Appbar(e),f.lockExpanding(!0)))):(k.enableGesture(a,new k.gesture.Pinch),k.off(a,"drag dragstart dragend dragcancel dragprepare",g,!0),k.on(a,"pinchin pinchout",g),a.classList.remove("ui-gridview-reorder"),i&&(e=i.querySelector(c.widget.core.Appbar.selector),e&&(f=c.widget.Appbar(e),f.lockExpanding(!1)))),h.reorder=d},C._setGridStyle=function(){var a,c,d,e,f=this,g=f._ui.listElements,h=g.length,i=f.options,j=i.cols,k=[],l=0;for(c=b.createElement("style"),c.type="text/css",a=Math.ceil(h/j),d=0;a>d;d++)for(e=0;j>e&&h>l;e++)g[l].style.animation="grid_show_item cubic-bezier(0.25, 0.46, 0.45, 1.00) 350ms "+17*l+"ms",k.push(f._getTransformStyle(e,d,++l));c.textContent=k.join("\n"),c.id="GridView",b.head.appendChild(c),f._styleElement=c},C._setCols=function(a,b){var c=this,d=c.options;return"auto"===b?d.cols=0:d.cols=parseInt(b,10),!0},C._getCols=function(){var a=this,b=a.options;return 0===b.cols?"auto":b.cols},C._getTransformStyle=function(a,b,c){var d,e,f=this._itemSize+this._borderSize,g=a*f+"px",h=b*this._itemHeight+Math.max(b-1,0)*this._borderSize+"px";return d="{ -webkit-transform: translate3d("+g+", "+h+", 0); transform: translate3d("+g+", "+h+", 0) }",e=s.replace("{index}",c)+d},C._removeGridStyle=function(){var a=this._styleElement;a&&(a.parentNode.removeChild(a),this._styleElement=null)},C.addItem=function(b){var c,d,e,f=this,g=f._ui.listElements,h=f._styleElement,i=h.textContent,j=f.element,k=f.options.cols,l=g.length&&a.getComputedStyle(g[0],null);b.classList.add(z.ITEM),b.style.width=(parseFloat(l.getPropertyValue("width"))||0)+"px",j.appendChild(b),g.push(b),e=g.length,d=Math.floor((e-1)/k),c=(e-1)%k,h.textContent=i.concat("\n"+f._getTransformStyle(c,d,e))},C.removeItem=function(a){var b,c=this,d=c.element,e=c._ui.listElements,f=c._styleElement,g=f.textContent.split("\n");b=e.indexOf(a),b>-1&&(e.splice(b,1),d.removeChild(a),g.pop(),f.textContent=g.join("\n"))},C._setLabel=function(a,b){var c,d=this,e=d.options;c=b||e.label,a.classList.remove(z.LABEL_IN),a.classList.remove(z.LABEL_OUT),c===y.IN?a.classList.add(z.LABEL_IN):c===y.OUT&&a.classList.add(z.LABEL_OUT),e.label=c},i.registerActiveSelector("."+z.GRIDLIST+" li."+z.ITEM),c.widget.mobile.GridView=B,j.defineWidget("GridView","ul.ui-gridview, ul[data-role='gridview']",[],B,"mobile")}(a.document,d),function(a){a.addEventListener("beforerouterinit",function(){d.autoInitializePage!==c&&d.setConfig("autoInitializePage",d.autoInitializePage)},!1),a.addEventListener("routerinit",function(b){var e=b.detail,f=d.util.object,g=e.getRoute("page"),h=e.getRoute("popup"),i=d.history,j=i.back.bind(e),k=d.widget.core.Page.classes,l=k.uiPageActive;d.changePage=e.open.bind(e),a.addEventListener("pageshow",function(){d.activePage=a.querySelector("."+l)}),d.firstPage=g.getFirstElement(),d.getActivePage=g.getActiveElement.bind(g),d.back=j,d.initializePage=e.init.bind(e),d.pageContainer=e.container,d.openPopup=function(a,b){var d;d=a&&a.length!==c&&"object"==typeof a?a[0]:a,b=f.merge({},b,{rel:"popup"}),e.open(d,b)},d.closePopup=h.close.bind(h,null)},!1)}(a.document),function(a){function b(b,c){var d=g.stripQueryParams(b).replace("#",""),e=a.getElementById(d);return e&&j.matchesSelector(e,c)?b===d?h.setNSData(e,"url","#"+d):h.setNSData(e,"url",b):e=null,e}var c,e,f=d.util,g=f.path,h=f.DOM,i=f.object,j=f.selectors,k=d.history,l=d.engine,m={};m.orderNumber=1,m.defaults={transition:"none"},m.filter=l.getWidgetDefinition("Page").selector.replace(/(\s*)/g,""),m.firstPage=null,m._originalBaseHref="",m._originalLocationHref="",m.option=function(){var a=i.merge({},m.defaults);return a.transition=d.getConfig("pageTransition",a.transition),a},m.init=function(){var b=[].slice.call(a.querySelectorAll(this.filter));b.forEach(function(a){h.getNSData(a,"url")||h.setNSData(a,"url",a.id&&"#"+a.id||location.pathname+location.search)})},m.open=function(b,c){var d,e,f=a.title;d=b!==this.getFirstElement()||c.dataUrl?h.getNSData(b,"url"):g.documentUrl.hrefNoHash,!d&&c.href&&(d=c.href,h.setNSData(b,"url",d)),f=h.getNSData(b,"title")||j.getChildrenBySelector(b,".ui-header > .ui-title").textContent||f,h.getNSData(b,"title")||h.setNSData(b,"title",f),d&&!c.fromHashChange&&(!g.isPath(d)&&d.indexOf("#")<0&&(d=g.makeUrlAbsolute("#"+d,g.documentUrl.hrefNoHash)),e=i.merge({},c,{url:d}),c.volatileRecord&&k.enableVolatileMode(),k.replace(e,f,d),k.disableVolatileMode()),this._setBase(d),a.title=f,this.active=!0,this.getContainer().change(b,c)},m.find=function(a){var c,e=this,f=d.router.Router.getInstance(),h=e._createDataUrl(a),i=e.getFirstElement(),j=f.getContainer(),k="[data-url='"+h+"']",l=/,/gm;return/#/.test(a)&&g.isPath(h)?null:(k+=e.filter.replace(l,",[data-url='"+h+"']"),c=j.element.querySelector(k),c||!h||g.isPath(h)||(c=b(h,e.filter)),!c&&g.isFirstPageUrl(h,e.getFirstElement())&&i&&(c=i),c)},m.parse=function(a,b){var c,d=this,e=d._createDataUrl(b);return d._setBase(b),c=a.querySelector(d.filter),c&&(h.setNSData(c,"url",e),h.setNSData(c,"external",!0)),c},m.onHashChange=function(){return null},m._createDataUrl=function(a){return g.convertUrlToDataUrl(a,!0)},m.onOpenFailed=function(){this._setBase(g.parseLocation().hrefNoSearch)},m._getBaseElement=function(){return e||(e=a.querySelector("head")),c||(c=a.querySelector("base"),c?(this._originalBaseHref=c.href,this._originalLocationHref=g.documentUrl.hrefNoHash):(c=a.createElement("base"),c.href=g.documentBase.hrefNoHash,e.appendChild(c))),c},m._setBase=function(a){var b=this._getBaseElement(),c=b.href,d="";this._originalBaseHref&&(this._originalLocationHref!==g.parseUrl(a).hrefNoSearch?(d=g.parseUrl(a).hrefNoSearch.replace(this._originalLocationHref,""),g.documentBase=g.parseUrl(g.makeUrlAbsolute(d,g.documentBase.href))):a=this._originalBaseHref),g.isPath(a)&&(a=g.makeUrlAbsolute(a,g.documentBase),g.parseUrl(c).hrefNoSearch!==g.parseUrl(a).hrefNoSearch&&(b.href=a,g.documentBase=g.parseUrl(g.makeUrlAbsolute(a,g.documentUrl.href))))},m.getContainer=function(){return d.router.Router.getInstance().getContainer()},m.getActive=function(){return this.getContainer().getActivePage()},m.getActiveElement=function(){return this.getActive().element},m.getFirstElement=function(){return this.firstPage},m.setFirstElement=function(a){this.firstPage=a},d.router.route.page=m}(a.document),function(){var a,b=d.util.object,c={volatileRecord:!0,orderNumber:2},e=d.router.route.page,f=e,g=e.option,h=function(){};h.prototype=f,a=new h,a.option=function(){return b.merge({},g.call(e),c)},d.router.route.maintab=a}(),function(a,b,c){function d(a,c){var d,e=/^#/;return a=a.replace(e,""),d=b.getElementById(a),d&&i.matchesSelector(d,c)?j.setNSData(d,"url","#"+a):d=null,d}var e=c.widget.core.Popup,f=c.util,g={defaults:{transition:"none",container:null,volatileRecord:!0},filter:"."+e.classes.popup,activePopup:null,events:{POPUP_HIDE:"popuphide"},_path:c.util.path,_history:c.history},h=c.engine,i=c.util.selectors,j=c.util.DOM,k=c.util.object,l="popup=true",m=/([&|\?]popup=true)/;g.orderNumber=100,g.option=function(){var a=k.merge({},g.defaults);return a.transition=c.getConfig("popupTransition",a.transition),a},g.setActive=function(a,b){var c,d=g._path.getLocation(),e=d.replace(m,"");this.activePopup=a,a?b&&!b.fromHashChange&&b.history&&(c=g._path.addHashSearchParams(e,l),g._history.replace(b,"",c),this.active=!0):d!==e&&(this.active=!1,g._history.back())},g.open=function(a,d,e){var i,k,l=this,m=c.router.Router.getInstance(),n=l.events,o=function(){b.removeEventListener(n.POPUP_HIDE,o,!1),a.parentNode.removeChild(a),l.activePopup=null},p=function(){var c,f=d["position-to"];f&&(d.positionTo=f),e&&(c=e.touches?e.touches[0]:e,d.x=c.clientX,d.y=c.clientY),b.removeEventListener(n.POPUP_HIDE,p,!1),i=h.instanceWidget(a,"Popup",d),i.open(d),l.activePopup=i,l.active=i.options.history},q=m.container.getActivePage();j.getNSData(a,"external")===!0&&(k=d.container?q.element.querySelector(d.container):q.element,a.parentNode!==k&&(a=f.importEvaluateAndAppendElement(a,k)),b.addEventListener(g.events.POPUP_HIDE,o,!1)),l.hasActive()?(b.addEventListener(n.POPUP_HIDE,p,!1),l.close()||p()):p()},g.close=function(a,b){var d,f=g._path.getLocation(),i=f.replace(m,"");return b=b||{},!a||a instanceof e||(a=h.instanceWidget(a,"Popup",b)),a=a||this.activePopup,a?(d=a.options,d.history&&f!==i?(d.transition=b.transition||d.transition,d.ext=b.ext||d.ext,d.dismissible||c.router.Router.getInstance().unlock(),g._history.back()):a.close(b),!0):!1},g.onHashChange=function(a,b){var c=this.activePopup;return c&&(c.close(b),this.active)?(this.active=!1,!0):!1},g.onOpenFailed=function(){return null},g.find=function(a){var b,e=this,f=e._createDataUrl(a),h=c.router.Router.getInstance().getContainer().getActivePage();return b=h.element.querySelector("[data-url='"+f+"']"+e.filter),b||!f||g._path.isPath(f)||(b=d(f,e.filter)),b},g.parse=function(a,b){var c,d=this,e=d._createDataUrl(b);return c=a.querySelector(d.filter),c&&(j.setNSData(c,"url",e),j.setNSData(c,"external",!0)),c},g._createDataUrl=function(a){return g._path.convertUrlToDataUrl(a)},g.hasActive=function(){return this.active},g.getActive=function(){return this.activePopup},g.getActiveElement=function(){var a=this.getActive();return a&&a.element},c.router.route.popup=g}(a,a.document,d),function(){var a=d.widget.core.Drawer,b=d.router.Router,c=d.util.path,e=d.history,f=d.engine,g={},h="drawer=true",i=/([&|\?]drawer=true)/;g.orderNumber=1e3,g.defaults={transition:"none"},g.filter="."+a.classes.drawer,g.option=function(){return null},g.open=function(a){var b=f.instanceWidget(a,"Drawer");b.open()},g.find=function(a){var d,e=c.convertUrlToDataUrl(a),f=b.getInstance().getContainer().getActivePage();return d=f.element.querySelector("#"+e)},g.parse=function(){return null},g.setActive=function(a){var b,d=c.getLocation(),f=d.replace(i,"");this._activeDrawer=a,a?(b=c.addHashSearchParams(f,h),e.replace({},"",b),this.active=!0):d!==f&&e.back()},g.onHashChange=function(a,b,c){var d=this,e=d._activeDrawer,f=c.stateUrl;return e&&f.search(h)>0&&a.search(h)<0?(e.close(b),this.active=!1,!0):!1},d.router.route.drawer=g}(),function(b,c){var d=c.widget.core.PanelChanger,e=c.util.selectors,f=c.util.cookie,g=c.history,h=c.engine,i={PANEL_CHANGER:d.classes.PANEL_CHANGER},j={REVERSE:"slide-reverse"},k={};k.orderNumber=10,k.option=function(){return null},k.setActive=function(a){var b=this,c=e.getClosestByClass(a,i.PANEL_CHANGER),d=h.instanceWidget(c,"PanelChanger");b.active=!0,b._panelChangerElement=c,b._panelChangerComponent=d},k.onHashChange=function(a,b,c){var e=this,h=d["default"].STORAGE_NAME,i=JSON.parse(f.readFromCookie(h)||"[]"),k=e._panelChangerComponent,l=i[i.length-1];return e.active&&k?e._panelChangerElement.querySelector("#"+l).classList.contains(d.classes.PRE_IN)||0===i.length?(g.replace(c,c.stateTitle,c.stateUrl),!0):(i.pop(),k.options.manageHistory&&i.length>0?(g.replace(c,c.stateTitle,c.stateUrl),f.writeToCookie(h,JSON.stringify(i)),k.changePanel("#"+i.pop(),j.REVERSE,"back"),!0):(e.active=!1,!1)):!1},k.tauback=function(a){var b=this,c=d["default"].STORAGE_NAME,e=JSON.parse(f.readFromCookie(c)||"[]"),g=b._panelChangerComponent;g&&(e.pop(),g.options&&g.options.manageHistory&&e.length>0&&(f.writeToCookie(c,JSON.stringify(e)),g.changePanel("#"+e.pop(),j.REVERSE,"back"),a.stopPropagation()))},a.addEventListener("tauback",k.tauback.bind(k),!1),c.router.route.panel=k}(a.document,d),function(){var a,b=d.util.object,c=d.util.path,e=d.util.DOM,f={volatileRecord:!0,orderNumber:2},g=function(){this.filter=".ui-card",this.options=f},h=g.prototype;g.prototype=h,h.option=function(){return b.merge({},f)},h.find=function(){return null},h._createDataUrl=function(a){return c.convertUrlToDataUrl(a,!0)},h.parse=function(a,b){var c,d=this,f=d._createDataUrl(b);return c=a.querySelector(d.filter),c&&(e.setNSData(c,"url",f),e.setNSData(c,"external",!0)),c},h.open=function(a,b){var d=e.getNSData(a,"url"),f=b.card;!d&&b.href&&(d=b.href,e.setNSData(a,"url",d)),d&&!b.fromHashChange&&!c.isPath(d)&&d.indexOf("#")<0&&(d=c.makeUrlAbsolute("#"+d,c.documentUrl.hrefNoHash)),f&&f.changeContent(a,b)},a=new g,d.router.route.card=a}(),function(){function a(a,b,c){var d,e=c.target,f={};4===e.readyState&&(f.success=200===e.status||0===e.status&&e.responseXML,d=e.responseXML,b.fullDocument||(d=d.body.firstChild),a(f,d))}function b(b,c,d,e){var g,h=c,i=a.bind(null,e,d);d&&(h=f.addSearchParams(c,d)),g=new XMLHttpRequest,g.responseType="document",g.overrideMimeType("text/html"),g.open("GET",h),
+g.addEventListener("error",i),g.addEventListener("load",i),g.send()}var c=d.template,e=d.util,f=e.path;c.register("html",b)}(),function(a){a.getConfig("autorun",!0)===!0&&a.engine.run()}(d),function(a,b){var c="ui-theme-",d="light",e={setTheme:function(d){var e=a.body.classList,f=[].slice.call(e);f.forEach(function(a){a.startsWith(c)&&e.remove(a)}),d&&(e.add(c+d),b.event.trigger(a,"themechange",{theme:d}))},getTheme:function(){var b=a.body.classList,e=[].slice.call(b);return e=e.filter(function(a){return a.startsWith(c)}),e.length?e[0].replace(c,""):d}};b.theme=e}(a.document,d),d.info.profile="mobile"}(window,window.document);
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Light.ttf b/d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Light.ttf
new file mode 100644 (file)
index 0000000..cc55284
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Light.ttf differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Medium.ttf b/d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Medium.ttf
new file mode 100644 (file)
index 0000000..048ad9c
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Medium.ttf differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Regular.ttf b/d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Regular.ttf
new file mode 100644 (file)
index 0000000..51822cd
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/fonts/Roboto-Regular.ttf differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/bottom_left.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/bottom_left.svg
new file mode 100644 (file)
index 0000000..fb76663
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="78px" height="78px" viewBox="0 0 78 78" enable-background="new 0 0 78 78" xml:space="preserve">
+<path d="M0,0c0,43.078,34.921,78,78,78H0L0,0z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/bottom_right.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/bottom_right.svg
new file mode 100644 (file)
index 0000000..3fc6b14
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="78px" height="78px" viewBox="0 0 78 78" enable-background="new 0 0 78 78" xml:space="preserve">
+<path d="M78,0c0,43.078-34.922,78-78,78h78V0z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/top_left.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/top_left.svg
new file mode 100644 (file)
index 0000000..c997dd8
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="78px" height="78px" viewBox="0 0 78 78" enable-background="new 0 0 78 78" xml:space="preserve">
+<path d="M78,0C34.922,0,0,34.922,0,78V0L78,0z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/top_right.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/0_Round_corner/top_right.svg
new file mode 100644 (file)
index 0000000..27265de
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="78px" height="78px" viewBox="0 0 78 78" enable-background="new 0 0 78 78" xml:space="preserve">
+<path d="M0,0c43.078,0,78,34.922,78,78V0H0z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_action_bar_icon_current_location_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_action_bar_icon_current_location_mtrl.svg
new file mode 100644 (file)
index 0000000..380382c
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <path fill="#FFFFFF" d="M59.277,33C57.924,22.452,49.549,14.076,39,12.724V6.75h-6v5.974C22.451,14.076,14.076,22.452,12.723,33
+               H6.75v6h5.973C14.076,49.549,22.451,57.924,33,59.276v5.974h6v-5.974C49.549,57.924,57.924,49.549,59.277,39h5.973v-6H59.277z
+                M36,53.475c-9.636,0-17.476-7.839-17.476-17.475S26.364,18.525,36,18.525S53.476,26.364,53.476,36S45.636,53.475,36,53.475z"/>
+       <path fill="#FFFFFF" d="M36,25.5c-5.796,0-10.5,4.704-10.5,10.5S30.204,46.5,36,46.5S46.5,41.796,46.5,36S41.796,25.5,36,25.5z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_ab_back_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_ab_back_mtrl.svg
new file mode 100644 (file)
index 0000000..d210dad
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <polygon fill="#FFFFFF" points="40.897,61.521 12.748,34.989 40.897,8.453 44.773,12.423 20.843,34.989 44.773,57.549 
+               40.897,61.521   "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_ab_more_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_ab_more_mtrl.svg
new file mode 100644 (file)
index 0000000..774d42f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<ellipse fill="#FFFFFF" cx="36" cy="17.914" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="36.006" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="54.086" rx="6.183" ry="6.086"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_clear_search_api_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_clear_search_api_mtrl.svg
new file mode 100644 (file)
index 0000000..54ea990
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <polygon fill="#FFFFFF" points="54,21.626 50.375,18 36,32.374 21.626,18 18,21.626 32.374,36 18,50.375 21.626,54 36,39.626 
+               50.375,54 54,50.375 39.625,36   "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_voice_search_api_mtrl_alpha.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/10_Search/tw_ic_voice_search_api_mtrl_alpha.svg
new file mode 100644 (file)
index 0000000..23f2dba
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<path fill="#FFFFFF" d="M57.379,34.732l-5.22-0.078c-0.13,8.72-7.209,15.55-16.116,15.55c-9.548,0-16.202-8.176-16.202-15.512
+       h-5.221c0,9.107,7.584,19.174,18.769,20.572v9.988h5.22v-9.969C49.166,54.075,57.22,45.485,57.379,34.732z"/>
+<path fill="#FFFFFF" d="M36,44.958c5.651,0,10.249-4.621,10.249-10.298l0.029-17.612c0-5.68-4.611-10.301-10.278-10.301
+       c-5.667,0-10.278,4.621-10.278,10.301v17.609C25.721,40.337,30.333,44.958,36,44.958z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/13_View_controls/tw_spinner_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/13_View_controls/tw_spinner_mtrl.svg
new file mode 100644 (file)
index 0000000..5e827db
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 72"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="17.5 25.5 34.06 46.5 50.5 25.5 17.5 25.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_cursor_handler_bottom.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_cursor_handler_bottom.svg
new file mode 100644 (file)
index 0000000..54eaefd
--- /dev/null
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 27.5"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M10.82,0h.36C12.17,0,22,10.52,22,16.24v.88A10.52,10.52,0,0,1,11.37,27.5h-.74A10.52,10.52,0,0,1,0,17.12v-.88C0,10.52,9.9,0,10.82,0Z"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_cursor_handler_top.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_cursor_handler_top.svg
new file mode 100644 (file)
index 0000000..6889ba3
--- /dev/null
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 27.5"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M10.82,27.5h0C9.9,27.5,0,17,0,11.26v-.88A10.52,10.52,0,0,1,10.63,0h.74A10.52,10.52,0,0,1,22,10.38v.88C22,17,12.17,27.5,11.18,27.5Z"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_select_handler_left.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_select_handler_left.svg
new file mode 100644 (file)
index 0000000..e75b116
--- /dev/null
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 23"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M20,0h0l-.58.07-11,2.47A12.06,12.06,0,0,0,3.2,5.18a10.29,10.29,0,0,0-.34,14.58c3.86,4.14-3.83-4.11,0,0a10,10,0,0,0,14.37.28A11.49,11.49,0,0,0,20,14V0Z"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_select_handler_right.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_copypaste_select_handler_right.svg
new file mode 100644 (file)
index 0000000..855cea2
--- /dev/null
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 23"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M0,0V14a11.49,11.49,0,0,0,2.74,6.05,10,10,0,0,0,14.37-.28c3.86-4.14-3.83,4.11,0,0A10.29,10.29,0,0,0,16.8,5.18a12.06,12.06,0,0,0-5.27-2.64L.58.07,0,0Z"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_ic_ab_back_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_ic_ab_back_mtrl.svg
new file mode 100644 (file)
index 0000000..d210dad
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <polygon fill="#FFFFFF" points="40.897,61.521 12.748,34.989 40.897,8.453 44.773,12.423 20.843,34.989 44.773,57.549 
+               40.897,61.521   "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_ic_ab_more_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/17_Copy_paste/tw_ic_ab_more_mtrl.svg
new file mode 100644 (file)
index 0000000..774d42f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<ellipse fill="#FFFFFF" cx="36" cy="17.914" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="36.006" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="54.086" rx="6.183" ry="6.086"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_add_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_add_mtrl.svg
new file mode 100644 (file)
index 0000000..87f9388
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<polygon fill="#FFFFFF" points="62.25,32.625 39.375,32.625 39.375,9.75 32.625,9.75 32.625,32.625 9.75,32.625 9.75,39.375 
+       32.625,39.375 32.625,62.25 39.375,62.25 39.375,39.375 62.25,39.375 "/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_back_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_back_mtrl.svg
new file mode 100644 (file)
index 0000000..d210dad
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <polygon fill="#FFFFFF" points="40.897,61.521 12.748,34.989 40.897,8.453 44.773,12.423 20.843,34.989 44.773,57.549 
+               40.897,61.521   "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_more_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_more_mtrl.svg
new file mode 100644 (file)
index 0000000..774d42f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<ellipse fill="#FFFFFF" cx="36" cy="17.914" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="36.006" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="54.086" rx="6.183" ry="6.086"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_search_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_ab_search_mtrl.svg
new file mode 100644 (file)
index 0000000..3efa86a
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<path fill="#FFFFFF" d="M62.387,57.766L49.55,44.93c2.734-3.684,4.355-8.242,4.355-13.171c0-12.211-9.937-22.146-22.149-22.146
+       c-12.21,0-22.144,9.934-22.144,22.146c0,12.212,9.934,22.148,22.144,22.148c4.929,0,9.488-1.62,13.172-4.355l12.837,12.836
+       L62.387,57.766z M16.147,31.758c0-8.607,7.002-15.611,15.609-15.611c8.61,0,15.614,7.003,15.614,15.611
+       c0,8.609-7.004,15.613-15.614,15.613C23.149,47.371,16.147,40.367,16.147,31.758z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_delete_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_delete_mtrl.svg
new file mode 100644 (file)
index 0000000..5aaff06
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<path fill="#FFFFFF" d="M48.584,19.564v-6.375c0-2.274-1.851-4.125-4.125-4.125h-15.75c-2.274,0-4.125,1.851-4.125,4.125v6.375
+       H12.209v5.25h5.98h0.117l2.25,35.25c0,2.486,2.015,4.5,4.5,4.5h23.25c2.484,0,4.5-2.014,4.5-4.5l2.25-35.25h5.902v-5.25H48.584z
+        M29.834,14.314h13.5v5.25h-13.5V14.314z M33.213,55.582h-5.25V28.586h5.25V55.582z M45.205,55.582h-5.25V28.586h5.25V55.582z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_move_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_move_mtrl.svg
new file mode 100644 (file)
index 0000000..eb15bfb
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
+</style>
+<title>Mobile/Light_theme/ICON/01_ACTION_BAR/Bottom_bar_move</title>
+<desc>Created with Sketch.</desc>
+<g id="Mobile_x2F_Light_x5F_theme_x2F_ICON_x2F_01_x5F_ACTION_x5F_BAR_x2F_Bottom_x5F_bar_x5F_move">
+       <polygon id="Fill-1" class="st0" points="41.4,15 37,19.6 49.7,32.8 10.5,32.8 10.5,39.2 49.7,39.2 37,52.4 41.4,57 61.5,36        "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_share_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/1_App_bar/tw_ic_bb_share_mtrl.svg
new file mode 100644 (file)
index 0000000..98aab86
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<path fill="#FFFFFF" d="M50.91,45.764c-2,0-3.834,0.711-5.262,1.896l-16.537-9.773c0.142-0.607,0.226-1.237,0.226-1.887
+       c0-0.65-0.083-1.279-0.226-1.885l16.534-9.776c1.43,1.185,3.264,1.898,5.265,1.898c4.557,0,8.25-3.694,8.25-8.246
+       c0-4.561-3.693-8.254-8.25-8.254c-4.556,0-8.252,3.693-8.252,8.254c0,0.649,0.084,1.276,0.225,1.882L26.35,29.649
+       c-1.428-1.185-3.262-1.897-5.261-1.897c-4.556,0-8.249,3.695-8.249,8.249c0,4.551,3.692,8.252,8.249,8.252
+       c2,0,3.833-0.715,5.262-1.898l16.535,9.771c-0.144,0.607-0.226,1.236-0.226,1.887c0,4.559,3.694,8.252,8.25,8.252
+       s8.25-3.693,8.25-8.252C59.16,49.457,55.466,45.764,50.91,45.764z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/2_Buttons/tw_ic_ab_add_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/2_Buttons/tw_ic_ab_add_mtrl.svg
new file mode 100644 (file)
index 0000000..87f9388
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<polygon fill="#FFFFFF" points="62.25,32.625 39.375,32.625 39.375,9.75 32.625,9.75 32.625,32.625 9.75,32.625 9.75,39.375 
+       32.625,39.375 32.625,62.25 39.375,62.25 39.375,39.375 62.25,39.375 "/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_000.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_000.svg
new file mode 100644 (file)
index 0000000..03db0e3
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_00_1_">
+               <g>
+                       <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3.2
+                               C32.6,3.2,20.2,15.6,20.2,31c0,15.4,12.5,27.8,27.8,27.8c15.4,0,27.8-12.5,27.8-27.8C75.8,15.6,63.4,3.2,48,3.2z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_001.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_001.svg
new file mode 100644 (file)
index 0000000..5ec318d
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:3.000000e-02;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_01_1_">
+               <g id="_x33__x25_" class="st0">
+                       <path class="st1" d="M48,1.5c16.3,0,29.5,13.2,29.5,29.5c0,16.3-13.2,29.5-29.5,29.5S18.5,47.3,18.5,31
+                               C18.5,14.7,31.7,1.5,48,1.5"/>
+               </g>
+               <g>
+                       <path class="st1" d="M48,61.5c-16.8,0-30.5-13.7-30.5-30.5C17.5,14.2,31.2,0.5,48,0.5c16.8,0,30.5,13.7,30.5,30.5
+                               C78.5,47.8,64.8,61.5,48,61.5z M48,3.6C32.9,3.6,20.6,15.9,20.6,31c0,15.1,12.3,27.4,27.4,27.4S75.4,46.1,75.4,31
+                               C75.4,15.9,63.1,3.6,48,3.6z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_002.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_002.svg
new file mode 100644 (file)
index 0000000..ac5f275
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:5.000000e-02;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_02_1_">
+               <path id="_x35__x25_" class="st0" d="M48,2c16,0,29,13,29,29c0,16-13,29-29,29c-16,0-29-13-29-29C19,15,32,2,48,2"/>
+               <path class="st1" d="M48,61c-16.5,0-30-13.5-30-30C18,14.5,31.5,1,48,1s30,13.5,30,30C78,47.5,64.5,61,48,61z M48,4.1
+                       C33.2,4.1,21.1,16.2,21.1,31c0,14.8,12.1,26.9,26.9,26.9S74.9,45.8,74.9,31C74.9,16.2,62.8,4.1,48,4.1z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_003.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_003.svg
new file mode 100644 (file)
index 0000000..4306f53
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.1;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_03_1_">
+               <path id="_x31_0_x25_" class="st0" d="M48,2.5c15.7,0,28.5,12.8,28.5,28.5c0,15.7-12.8,28.5-28.5,28.5
+                       c-15.7,0-28.5-12.8-28.5-28.5C19.5,15.3,32.3,2.5,48,2.5"/>
+               <path class="st1" d="M48,60.5c-16.3,0-29.5-13.2-29.5-29.5C18.5,14.7,31.7,1.5,48,1.5c16.3,0,29.5,13.2,29.5,29.5
+                       C77.5,47.3,64.3,60.5,48,60.5z M48,4.6C33.4,4.6,21.6,16.4,21.6,31c0,14.6,11.8,26.4,26.4,26.4c14.6,0,26.4-11.8,26.4-26.4
+                       C74.4,16.4,62.6,4.6,48,4.6z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_004.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_004.svg
new file mode 100644 (file)
index 0000000..eb0d57a
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.2;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_04_1_">
+               <g id="_x32_0_x25_" class="st0">
+                       <path class="st1" d="M48,3c15.5,0,28,12.5,28,28c0,15.5-12.5,28-28,28S20,46.5,20,31C20,15.5,32.5,3,48,3"/>
+               </g>
+               <path class="st1" d="M48,60c-16,0-29-13-29-29C19,15,32,2,48,2c16,0,29,13,29,29C77,47,64,60,48,60z M48,5.1
+                       C33.7,5.1,22.1,16.7,22.1,31c0,14.3,11.6,25.9,25.9,25.9c14.3,0,25.9-11.6,25.9-25.9C73.9,16.7,62.3,5.1,48,5.1z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_005.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_005.svg
new file mode 100644 (file)
index 0000000..f5eca30
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.5;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_05_1_">
+               <path id="_x35_0_x25_" class="st0" d="M48,3.5c15.2,0,27.5,12.3,27.5,27.5c0,15.2-12.3,27.5-27.5,27.5S20.5,46.2,20.5,31
+                       C20.5,15.8,32.8,3.5,48,3.5"/>
+               <path class="st1" d="M48,59.5c-15.7,0-28.5-12.8-28.5-28.5C19.5,15.3,32.3,2.5,48,2.5S76.5,15.3,76.5,31
+                       C76.5,46.7,63.7,59.5,48,59.5z M48,5.6C34,5.6,22.6,17,22.6,31C22.6,45,34,56.4,48,56.4C62,56.4,73.4,45,73.4,31
+                       C73.4,17,62,5.6,48,5.6z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_006.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_006.svg
new file mode 100644 (file)
index 0000000..e67d418
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.7;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_06_1_">
+               <path id="_x37_0_x25_" class="st0" d="M48,4c14.9,0,27,12.1,27,27c0,14.9-12.1,27-27,27c-14.9,0-27-12.1-27-27
+                       C21,16.1,33.1,4,48,4"/>
+               <path class="st1" d="M48,59c-15.4,0-28-12.6-28-28C20,15.6,32.6,3,48,3s28,12.6,28,28C76,46.4,63.4,59,48,59z M48,6
+                       C34.2,6,23,17.2,23,31c0,13.8,11.2,25,25,25c13.8,0,25-11.2,25-25C73,17.2,61.8,6,48,6z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_007.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_007.svg
new file mode 100644 (file)
index 0000000..282a6b9
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.8;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_07_1_">
+               <path id="_x38_0_x25_" class="st0" d="M48,4.5c14.6,0,26.5,11.9,26.5,26.5c0,14.6-11.9,26.5-26.5,26.5S21.5,45.6,21.5,31
+                       C21.5,16.4,33.4,4.5,48,4.5"/>
+               <path class="st1" d="M48,58.5c-15.2,0-27.5-12.3-27.5-27.5C20.5,15.8,32.8,3.5,48,3.5c15.2,0,27.5,12.3,27.5,27.5
+                       C75.5,46.2,63.2,58.5,48,58.5z M48,6.5c-13.5,0-24.5,11-24.5,24.5c0,13.5,11,24.5,24.5,24.5s24.5-11,24.5-24.5
+                       C72.5,17.5,61.5,6.5,48,6.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_008.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_008.svg
new file mode 100644 (file)
index 0000000..82ed67f
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.9;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_08_1_">
+               <path id="_x39_0_x25_" class="st0" d="M48,5c14.4,0,26,11.6,26,26c0,14.4-11.6,26-26,26c-14.4,0-26-11.6-26-26
+                       C22,16.6,33.6,5,48,5"/>
+               <path class="st1" d="M48,58c-14.9,0-27-12.1-27-27C21,16.1,33.1,4,48,4c14.9,0,27,12.1,27,27C75,45.9,62.9,58,48,58z M48,7
+                       C34.8,7,24,17.8,24,31c0,13.2,10.8,24,24,24s24-10.8,24-24C72,17.8,61.2,7,48,7z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_009.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_009.svg
new file mode 100644 (file)
index 0000000..6bd0d8d
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.95;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_09_1_">
+               <path id="_x39_5" class="st0" d="M48,5c14.4,0,26,11.6,26,26c0,14.4-11.6,26-26,26c-14.4,0-26-11.6-26-26C22,16.6,33.6,5,48,5"/>
+               <path class="st1" d="M48,58c-14.9,0-27-12.1-27-27C21,16.1,33.1,4,48,4c14.9,0,27,12.1,27,27C75,45.9,62.9,58,48,58z M48,7
+                       C34.8,7,24,17.8,24,31c0,13.2,10.8,24,24,24s24-10.8,24-24C72,17.8,61.2,7,48,7z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_010.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_010.svg
new file mode 100644 (file)
index 0000000..36cc669
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_10_1_" fill="#FFFFFF" d="M47.993,4.509c-14.635,0-26.5,11.865-26.5,26.498c0,14.638,11.865,26.502,26.5,26.502
+               c14.636,0,26.501-11.864,26.501-26.502C74.494,16.374,62.629,4.509,47.993,4.509z M41.913,45.359l-9.984-9.873l2.823-2.789
+               l7.161,7.078l15.147-14.979l2.823,2.792L41.913,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_011.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_011.svg
new file mode 100644 (file)
index 0000000..f666e83
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_11_1_" fill="#FFFFFF" d="M48,4C33.089,4,21,16.089,21,30.998C21,45.911,33.089,58,48,58
+               c14.912,0,27-12.089,27-27.002C75,16.089,62.912,4,48,4z M41.917,45.359l-10.073-9.963l2.849-2.813l7.225,7.142l15.283-15.112
+               l2.848,2.817L41.917,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_012.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_012.svg
new file mode 100644 (file)
index 0000000..31d1263
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_12_1_" fill="#FFFFFF" d="M48,3.5c-15.188,0-27.5,12.313-27.5,27.498C20.5,46.188,32.813,58.5,48,58.5
+               c15.188,0,27.5-12.313,27.5-27.502C75.5,15.813,63.188,3.5,48,3.5z M41.91,45.359L31.39,34.956l2.975-2.938l7.544,7.457
+               l15.959-15.782l2.975,2.942L41.91,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_013.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_013.svg
new file mode 100644 (file)
index 0000000..ccc3a28
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_13_1_" fill="#FFFFFF" d="M48,3C32.536,3,20,15.537,20,30.998C20,46.464,32.536,59,48,59s28-12.536,28-28.002
+               C76,15.537,63.464,3,48,3z M41.915,45.359l-11.29-11.166l3.193-3.153l8.097,8.004l17.128-16.937l3.191,3.158L41.915,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_014.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_014.svg
new file mode 100644 (file)
index 0000000..8727436
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_14_1_" fill="#FFFFFF" d="M48,2.5c-15.74,0-28.5,12.76-28.5,28.498C19.5,46.74,32.26,59.5,48,59.5
+               s28.5-12.76,28.5-28.502C76.5,15.26,63.74,2.5,48,2.5z M41.891,45.359L29.552,33.157l3.49-3.448l8.849,8.748l18.72-18.511
+               l3.488,3.451L41.891,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_015.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_015.svg
new file mode 100644 (file)
index 0000000..d9919a1
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_15_1_" fill="#FFFFFF" d="M48,2C31.983,2,19,14.984,19,30.998C19,47.018,31.983,60,48,60
+               c16.018,0,29-12.982,29-29.002C77,14.984,64.018,2,48,2z M41.915,45.359L28.706,32.297l3.736-3.69l9.473,9.364l20.04-19.816
+               l3.734,3.694L41.915,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_016.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_016.svg
new file mode 100644 (file)
index 0000000..be25a6f
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_16_1_" fill="#FFFFFF" d="M48,1.5c-16.293,0-29.5,13.208-29.5,29.498C18.5,47.293,31.707,60.5,48,60.5
+               s29.5-13.207,29.5-29.502C77.5,14.708,64.293,1.5,48,1.5z M41.896,45.359L28.063,31.68l3.913-3.866l9.921,9.808l20.988-20.753
+               l3.912,3.869L41.896,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_017.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_017.svg
new file mode 100644 (file)
index 0000000..7d01500
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_17_1_" fill="#FFFFFF" d="M48,1C31.431,1,18,14.431,18,30.998C18,47.568,31.431,61,48,61
+               c16.568,0,30-13.432,30-30.002C78,14.431,64.568,1,48,1z M41.904,45.359L27.52,31.134l4.068-4.02l10.316,10.198l21.825-21.58
+               l4.066,4.023L41.904,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_018.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_018.svg
new file mode 100644 (file)
index 0000000..8a147a7
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_18_1_" fill="#FFFFFF" d="M48,0.5c-16.846,0-30.5,13.655-30.5,30.498C17.5,47.846,31.154,61.5,48,61.5
+               c16.846,0,30.5-13.654,30.5-30.502C78.5,14.155,64.846,0.5,48,0.5z M41.894,45.359L27.141,30.77l4.172-4.123l10.58,10.46
+               l22.382-22.133l4.172,4.126L41.894,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_019.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_019.svg
new file mode 100644 (file)
index 0000000..5175afc
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_19_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.91,45.359L26.881,30.497l4.25-4.2L41.91,36.953l22.803-22.548l4.25,4.204L41.91,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_020.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_020.svg
new file mode 100644 (file)
index 0000000..978d6ad
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_20_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.91,45.359L26.881,30.497l4.25-4.2L41.91,36.953l22.803-22.548l4.25,4.204L41.91,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_021.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_021.svg
new file mode 100644 (file)
index 0000000..404091f
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_21_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.921,45.359L27.038,30.64l4.209-4.159l10.674,10.553l22.583-22.331l4.209,4.164L41.921,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_022.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_022.svg
new file mode 100644 (file)
index 0000000..d62dcc6
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_22_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.928,45.359L27.1,30.695l4.194-4.144l10.634,10.514l22.498-22.247l4.193,4.148L41.928,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_023.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_023.svg
new file mode 100644 (file)
index 0000000..20fc97b
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_23_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.92,45.359L27.209,30.811L31.37,26.7l10.55,10.431L64.24,15.06l4.16,4.115L41.92,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_024.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_024.svg
new file mode 100644 (file)
index 0000000..efbb5ae
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_24_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.826,45.359L27.209,30.905l4.134-4.084l10.482,10.363L64,15.255l4.134,4.089L41.826,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_025.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_025.svg
new file mode 100644 (file)
index 0000000..fe3399b
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_25_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.913,45.359L27.428,31.035l4.097-4.047l10.388,10.27l21.976-21.731l4.098,4.052L41.913,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_026.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_026.svg
new file mode 100644 (file)
index 0000000..9ef9ac5
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_26_1_" fill="#FFFFFF" d="M47.999,0C30.879,0,17,13.877,17,31c0,17.124,13.879,31,30.999,31
+               C65.122,62,79,48.124,79,31C79,13.877,65.122,0,47.999,0z M41.905,45.359L27.599,31.214l4.046-4l10.261,10.146l21.704-21.464
+               l4.048,4.001L41.905,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_000.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_000.svg
new file mode 100644 (file)
index 0000000..7d688ae
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_00_1_">
+               <g>
+                       <path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+                               c-16,0-28,12-28,28c0,16,12,28,28,28c16,0,28-12,28-28C76,32,64,20,48,20z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_001.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_001.svg
new file mode 100644 (file)
index 0000000..5d5fd17
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:3.000000e-02;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_01_1_">
+               <g id="_x33__x25_" class="st0">
+                       <path class="st1" d="M48,18.5c16.3,0,29.5,13.2,29.5,29.5c0,16.3-13.2,29.5-29.5,29.5S18.5,64.3,18.5,48
+                               C18.5,31.7,31.7,18.5,48,18.5"/>
+               </g>
+               <g>
+                       <path class="st1" d="M48,78.5c-16.8,0-30.5-13.7-30.5-30.5c0-16.8,13.7-30.5,30.5-30.5c16.8,0,30.5,13.7,30.5,30.5
+                               C78.5,64.8,64.8,78.5,48,78.5z M48,20.5c-15.7,0-27.5,11.8-27.5,27.5c0,15.7,11.8,27.5,27.5,27.5S75.5,63.7,75.5,48
+                               C75.5,32.3,63.7,20.5,48,20.5z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_002.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_002.svg
new file mode 100644 (file)
index 0000000..e658ca0
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:5.000000e-02;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_02_1_">
+               <path id="_x35__x25_" class="st0" d="M48,19c16,0,29,13,29,29c0,16-13,29-29,29c-16,0-29-13-29-29C19,32,32,19,48,19"/>
+               <path class="st1" d="M48,78c-16.5,0-30-13.5-30-30c0-16.5,13.5-30,30-30s30,13.5,30,30C78,64.5,64.5,78,48,78z M48,21
+                       c-15.4,0-27,11.6-27,27c0,15.4,11.6,27,27,27s27-11.6,27-27C75,32.6,63.4,21,48,21z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_003.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_003.svg
new file mode 100644 (file)
index 0000000..df31ec1
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.1;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_03_1_">
+               <path id="_x31_0_x25_" class="st0" d="M48,19.5c15.7,0,28.5,12.8,28.5,28.5c0,15.7-12.8,28.5-28.5,28.5
+                       c-15.7,0-28.5-12.8-28.5-28.5C19.5,32.3,32.3,19.5,48,19.5"/>
+               <path class="st1" d="M48,77.5c-16.3,0-29.5-13.2-29.5-29.5c0-16.3,13.2-29.5,29.5-29.5c16.3,0,29.5,13.2,29.5,29.5
+                       C77.5,64.3,64.3,77.5,48,77.5z M48,21.5c-15.2,0-26.5,11.3-26.5,26.5c0,15.2,11.3,26.5,26.5,26.5c15.2,0,26.5-11.3,26.5-26.5
+                       C74.5,32.8,63.2,21.5,48,21.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_004.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_004.svg
new file mode 100644 (file)
index 0000000..5ccb9bf
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.2;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_04_1_">
+               <g id="_x32_0_x25_" class="st0">
+                       <path class="st1" d="M48,20c15.5,0,28,12.5,28,28c0,15.5-12.5,28-28,28S20,63.5,20,48C20,32.5,32.5,20,48,20"/>
+               </g>
+               <path class="st1" d="M48,77c-16,0-29-13-29-29c0-16,13-29,29-29c16,0,29,13,29,29C77,64,64,77,48,77z M48,22
+                       c-14.9,0-26,11.1-26,26c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,33.1,62.9,22,48,22z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_005.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_005.svg
new file mode 100644 (file)
index 0000000..0fb4b8e
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.5;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_05_1_">
+               <path id="_x35_0_x25_" class="st0" d="M48,20.5c15.2,0,27.5,12.3,27.5,27.5c0,15.2-12.3,27.5-27.5,27.5S20.5,63.2,20.5,48
+                       C20.5,32.8,32.8,20.5,48,20.5"/>
+               <path class="st1" d="M48,76.5c-15.7,0-28.5-12.8-28.5-28.5c0-15.7,12.8-28.5,28.5-28.5S76.5,32.3,76.5,48
+                       C76.5,63.7,63.7,76.5,48,76.5z M48,22.5c-14.6,0-25.5,10.9-25.5,25.5c0,14.6,10.9,25.5,25.5,25.5c14.6,0,25.5-10.9,25.5-25.5
+                       C73.5,33.4,62.6,22.5,48,22.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_006.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_006.svg
new file mode 100644 (file)
index 0000000..a8538b8
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.7;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_06_1_">
+               <path id="_x37_0_x25_" class="st0" d="M48,21c14.9,0,27,12.1,27,27c0,14.9-12.1,27-27,27c-14.9,0-27-12.1-27-27
+                       C21,33.1,33.1,21,48,21"/>
+               <path class="st1" d="M48,76c-15.4,0-28-12.6-28-28c0-15.4,12.6-28,28-28s28,12.6,28,28C76,63.4,63.4,76,48,76z M48,23
+                       c-14.3,0-25,10.7-25,25c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,33.7,62.3,23,48,23z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_007.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_007.svg
new file mode 100644 (file)
index 0000000..fecdcbd
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.8;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_07_1_">
+               <path id="_x38_0_x25_" class="st0" d="M48,21.5c14.6,0,26.5,11.9,26.5,26.5c0,14.6-11.9,26.5-26.5,26.5S21.5,62.6,21.5,48
+                       C21.5,33.4,33.4,21.5,48,21.5"/>
+               <path class="st1" d="M48,75.5c-15.2,0-27.5-12.3-27.5-27.5c0-15.2,12.3-27.5,27.5-27.5c15.2,0,27.5,12.3,27.5,27.5
+                       C75.5,63.2,63.2,75.5,48,75.5z M48,23.5c-14.1,0-24.5,10.4-24.5,24.5c0,14.1,10.4,24.5,24.5,24.5S72.5,62.1,72.5,48
+                       C72.5,33.9,62.1,23.5,48,23.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_008.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_008.svg
new file mode 100644 (file)
index 0000000..eace498
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.9;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_08_1_">
+               <path id="_x39_0_x25_" class="st0" d="M48,22c14.4,0,26,11.6,26,26c0,14.4-11.6,26-26,26c-14.4,0-26-11.6-26-26
+                       C22,33.6,33.6,22,48,22"/>
+               <path class="st1" d="M48,75c-14.9,0-27-12.1-27-27c0-14.9,12.1-27,27-27c14.9,0,27,12.1,27,27C75,62.9,62.9,75,48,75z M48,24
+                       c-13.8,0-24,10.2-24,24c0,13.8,10.2,24,24,24s24-10.2,24-24C72,34.2,61.8,24,48,24z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_009.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_009.svg
new file mode 100644 (file)
index 0000000..03c14bc
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.95;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_09_1_">
+               <path id="_x39_5" class="st0" d="M48,22c14.4,0,26,11.6,26,26c0,14.4-11.6,26-26,26c-14.4,0-26-11.6-26-26C22,33.6,33.6,22,48,22"
+                       />
+               <path class="st1" d="M48,75c-14.9,0-27-12.1-27-27c0-14.9,12.1-27,27-27c14.9,0,27,12.1,27,27C75,62.9,62.9,75,48,75z M48,24
+                       c-13.8,0-24,10.2-24,24c0,13.8,10.2,24,24,24s24-10.2,24-24C72,34.2,61.8,24,48,24z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_010.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_010.svg
new file mode 100644 (file)
index 0000000..aa0b9e2
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_10" fill="#FFFFFF" d="M47.993,21.509c-14.635,0-26.5,11.865-26.5,26.498c0,14.638,11.865,26.502,26.5,26.502\r
+               c14.636,0,26.501-11.864,26.501-26.502C74.494,33.374,62.629,21.509,47.993,21.509z M41.913,62.359l-9.984-9.873l2.823-2.789\r
+               l7.161,7.078l15.147-14.979l2.823,2.792L41.913,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_011.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_011.svg
new file mode 100644 (file)
index 0000000..e8b7c80
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_11_1_" fill="#FFFFFF" d="M48,21c-14.911,0-27,12.089-27,26.998C21,62.911,33.089,75,48,75\r
+               c14.912,0,27-12.089,27-27.002C75,33.089,62.912,21,48,21z M41.917,62.359l-10.073-9.963l2.849-2.813l7.225,7.142l15.283-15.112\r
+               l2.848,2.817L41.917,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_012.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_012.svg
new file mode 100644 (file)
index 0000000..ed480b3
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_12" fill="#FFFFFF" d="M48,20.5c-15.188,0-27.5,12.313-27.5,27.498C20.5,63.188,32.813,75.5,48,75.5\r
+               c15.188,0,27.5-12.313,27.5-27.502C75.5,32.813,63.188,20.5,48,20.5z M41.91,62.359L31.39,51.956l2.975-2.938l7.544,7.457\r
+               l15.959-15.782l2.975,2.942L41.91,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_013.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_013.svg
new file mode 100644 (file)
index 0000000..b90d769
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_13" fill="#FFFFFF" d="M48,20c-15.464,0-28,12.537-28,27.998C20,63.464,32.536,76,48,76s28-12.536,28-28.002\r
+               C76,32.537,63.464,20,48,20z M41.915,62.359l-11.29-11.166l3.193-3.153l8.097,8.004l17.128-16.937l3.191,3.158L41.915,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_014.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_014.svg
new file mode 100644 (file)
index 0000000..1a9c783
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_14" fill="#FFFFFF" d="M48,19.5c-15.74,0-28.5,12.76-28.5,28.498C19.5,63.74,32.26,76.5,48,76.5\r
+               s28.5-12.76,28.5-28.502C76.5,32.26,63.74,19.5,48,19.5z M41.891,62.359L29.552,50.157l3.49-3.448l8.849,8.748l18.72-18.511\r
+               l3.488,3.451L41.891,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_015.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_015.svg
new file mode 100644 (file)
index 0000000..9313e40
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_15_1_" fill="#FFFFFF" d="M48,19c-16.017,0-29,12.984-29,28.998C19,64.018,31.983,77,48,77\r
+               c16.018,0,29-12.982,29-29.002C77,31.984,64.018,19,48,19z M41.915,62.359L28.706,49.297l3.736-3.69l9.473,9.364l20.04-19.816\r
+               l3.734,3.694L41.915,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_016.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_016.svg
new file mode 100644 (file)
index 0000000..3c1f955
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_16" fill="#FFFFFF" d="M48,18.5c-16.293,0-29.5,13.208-29.5,29.498C18.5,64.293,31.707,77.5,48,77.5\r
+               s29.5-13.207,29.5-29.502C77.5,31.708,64.293,18.5,48,18.5z M41.896,62.359L28.063,48.68l3.913-3.866l9.921,9.808l20.988-20.753\r
+               l3.912,3.869L41.896,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_017.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_017.svg
new file mode 100644 (file)
index 0000000..4b4e9ca
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_17" fill="#FFFFFF" d="M48,18c-16.569,0-30,13.431-30,29.998C18,64.568,31.431,78,48,78\r
+               c16.568,0,30-13.432,30-30.002C78,31.431,64.568,18,48,18z M41.904,62.359L27.52,48.134l4.068-4.02l10.316,10.198l21.825-21.58\r
+               l4.066,4.023L41.904,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_018.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_018.svg
new file mode 100644 (file)
index 0000000..df93745
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_18_1_" fill="#FFFFFF" d="M48,17.5c-16.846,0-30.5,13.655-30.5,30.498C17.5,64.846,31.154,78.5,48,78.5\r
+               c16.846,0,30.5-13.654,30.5-30.502C78.5,31.155,64.846,17.5,48,17.5z M41.894,62.359L27.141,47.77l4.172-4.123l10.58,10.46\r
+               l22.382-22.133l4.172,4.126L41.894,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_019.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_019.svg
new file mode 100644 (file)
index 0000000..fbc7eb2
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_19_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.91,62.359L26.881,47.497l4.25-4.2L41.91,53.953l22.803-22.548l4.25,4.204L41.91,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_020.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_020.svg
new file mode 100644 (file)
index 0000000..976d946
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_20" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.91,62.359L26.881,47.497l4.25-4.2L41.91,53.953l22.803-22.548l4.25,4.204L41.91,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_021.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_021.svg
new file mode 100644 (file)
index 0000000..fc607e3
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_21_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.921,62.359L27.038,47.64l4.209-4.159l10.674,10.553l22.583-22.331l4.209,4.164L41.921,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_022.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_022.svg
new file mode 100644 (file)
index 0000000..fbd72a8
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_22_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.928,62.359L27.1,47.695l4.194-4.144l10.634,10.514l22.498-22.247l4.193,4.148L41.928,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_023.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_023.svg
new file mode 100644 (file)
index 0000000..6ee1043
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_23_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.92,62.359L27.209,47.811L31.37,43.7l10.55,10.431L64.24,32.06l4.16,4.115L41.92,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_024.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_024.svg
new file mode 100644 (file)
index 0000000..2635d45
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_24_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.826,62.359L27.209,47.905l4.134-4.084l10.482,10.363L64,32.255l4.134,4.089L41.826,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_025.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_025.svg
new file mode 100644 (file)
index 0000000..fd48538
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_25_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.913,62.359L27.428,48.035l4.097-4.047l10.388,10.27l21.976-21.731l4.098,4.052L41.913,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_026.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_026.svg
new file mode 100644 (file)
index 0000000..b07bf29
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_26_1_" fill="#FFFFFF" d="M47.999,17C30.879,17,17,30.877,17,48c0,17.124,13.879,31,30.999,31\r
+               C65.122,79,79,65.124,79,48C79,30.877,65.122,17,47.999,17z M41.905,62.359L27.599,48.214l4.046-4l10.261,10.146l21.704-21.464\r
+               l4.048,4.001L41.905,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg
new file mode 100644 (file)
index 0000000..89366d8
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="2592" height="96" viewBox="0 0 2592 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_000" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Check"><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-16 0-28 12-28 28s12 28 28 28 28-12 28-28-12-28-28-28z" id="_x30_00_1_"/></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_001" x="96" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:3.000000e-02}.st1{fill:#fff}</style><g id="Check"><g id="_x30_01_1_"><g id="_x33__x25_" class="st0"><path class="st1" d="M48 18.5c16.3 0 29.5 13.2 29.5 29.5S64.3 77.5 48 77.5 18.5 64.3 18.5 48 31.7 18.5 48 18.5"/></g><path class="st1" d="M48 78.5c-16.8 0-30.5-13.7-30.5-30.5S31.2 17.5 48 17.5 78.5 31.2 78.5 48 64.8 78.5 48 78.5zm0-58c-15.7 0-27.5 11.8-27.5 27.5S32.3 75.5 48 75.5 75.5 63.7 75.5 48 63.7 20.5 48 20.5z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_002" x="192" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:5.000000e-02;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_02_1_"><path id="_x35__x25_" class="st0" d="M48 19c16 0 29 13 29 29S64 77 48 77 19 64 19 48s13-29 29-29"/><path class="st1" d="M48 78c-16.5 0-30-13.5-30-30s13.5-30 30-30 30 13.5 30 30-13.5 30-30 30zm0-57c-15.4 0-27 11.6-27 27s11.6 27 27 27 27-11.6 27-27-11.6-27-27-27z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_003" x="288" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.1;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_03_1_"><path id="_x31_0_x25_" class="st0" d="M48 19.5c15.7 0 28.5 12.8 28.5 28.5S63.7 76.5 48 76.5 19.5 63.7 19.5 48 32.3 19.5 48 19.5"/><path class="st1" d="M48 77.5c-16.3 0-29.5-13.2-29.5-29.5S31.7 18.5 48 18.5 77.5 31.7 77.5 48 64.3 77.5 48 77.5zm0-56c-15.2 0-26.5 11.3-26.5 26.5S32.8 74.5 48 74.5 74.5 63.2 74.5 48 63.2 21.5 48 21.5z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_004" x="384" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.2}.st1{fill:#fff}</style><g id="Check"><g id="_x30_04_1_"><g id="_x32_0_x25_" class="st0"><path class="st1" d="M48 20c15.5 0 28 12.5 28 28S63.5 76 48 76 20 63.5 20 48s12.5-28 28-28"/></g><path class="st1" d="M48 77c-16 0-29-13-29-29s13-29 29-29 29 13 29 29-13 29-29 29zm0-55c-14.9 0-26 11.1-26 26s11.1 26 26 26 26-11.1 26-26-11.1-26-26-26z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_005" x="480" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.5;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_05_1_"><path id="_x35_0_x25_" class="st0" d="M48 20.5c15.2 0 27.5 12.3 27.5 27.5S63.2 75.5 48 75.5 20.5 63.2 20.5 48 32.8 20.5 48 20.5"/><path class="st1" d="M48 76.5c-15.7 0-28.5-12.8-28.5-28.5S32.3 19.5 48 19.5 76.5 32.3 76.5 48 63.7 76.5 48 76.5zm0-54c-14.6 0-25.5 10.9-25.5 25.5S33.4 73.5 48 73.5 73.5 62.6 73.5 48 62.6 22.5 48 22.5z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_006" x="576" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.7;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_06_1_"><path id="_x37_0_x25_" class="st0" d="M48 21c14.9 0 27 12.1 27 27S62.9 75 48 75 21 62.9 21 48s12.1-27 27-27"/><path class="st1" d="M48 76c-15.4 0-28-12.6-28-28s12.6-28 28-28 28 12.6 28 28-12.6 28-28 28zm0-53c-14.3 0-25 10.7-25 25s10.7 25 25 25 25-10.7 25-25-10.7-25-25-25z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_007" x="672" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.8;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_07_1_"><path id="_x38_0_x25_" class="st0" d="M48 21.5c14.6 0 26.5 11.9 26.5 26.5S62.6 74.5 48 74.5 21.5 62.6 21.5 48 33.4 21.5 48 21.5"/><path class="st1" d="M48 75.5c-15.2 0-27.5-12.3-27.5-27.5S32.8 20.5 48 20.5 75.5 32.8 75.5 48 63.2 75.5 48 75.5zm0-52c-14.1 0-24.5 10.4-24.5 24.5S33.9 72.5 48 72.5 72.5 62.1 72.5 48 62.1 23.5 48 23.5z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_008" x="768" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.9;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_08_1_"><path id="_x39_0_x25_" class="st0" d="M48 22c14.4 0 26 11.6 26 26S62.4 74 48 74 22 62.4 22 48s11.6-26 26-26"/><path class="st1" d="M48 75c-14.9 0-27-12.1-27-27s12.1-27 27-27 27 12.1 27 27-12.1 27-27 27zm0-51c-13.8 0-24 10.2-24 24s10.2 24 24 24 24-10.2 24-24-10.2-24-24-24z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_009" x="864" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.95;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_09_1_"><path id="_x39_5" class="st0" d="M48 22c14.4 0 26 11.6 26 26S62.4 74 48 74 22 62.4 22 48s11.6-26 26-26"/><path class="st1" d="M48 75c-14.9 0-27-12.1-27-27s12.1-27 27-27 27 12.1 27 27-12.1 27-27 27zm0-51c-13.8 0-24 10.2-24 24s10.2 24 24 24 24-10.2 24-24-10.2-24-24-24z"/></g></g></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_010" x="960" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M47.993 21.509c-14.635 0-26.5 11.865-26.5 26.498 0 14.638 11.865 26.502 26.5 26.502 14.636 0 26.501-11.864 26.501-26.502 0-14.633-11.865-26.498-26.501-26.498zm-6.08 40.85l-9.984-9.873 2.823-2.789 7.161 7.078L57.06 41.796l2.823 2.792-17.97 17.771z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_011" x="1056" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 21c-14.911 0-27 12.089-27 26.998C21 62.911 33.089 75 48 75c14.912 0 27-12.089 27-27.002C75 33.089 62.912 21 48 21zm-6.083 41.359l-10.073-9.963 2.849-2.813 7.225 7.142 15.283-15.112 2.848 2.817-18.132 17.929z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_012" x="1152" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 20.5c-15.188 0-27.5 12.313-27.5 27.498C20.5 63.188 32.813 75.5 48 75.5c15.188 0 27.5-12.313 27.5-27.502C75.5 32.813 63.188 20.5 48 20.5zm-6.09 41.859L31.39 51.956l2.975-2.938 7.544 7.457 15.959-15.782 2.975 2.942L41.91 62.359z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_013" x="1248" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 20c-15.464 0-28 12.537-28 27.998C20 63.464 32.536 76 48 76s28-12.536 28-28.002C76 32.537 63.464 20 48 20zm-6.085 42.359l-11.29-11.166 3.193-3.153 8.097 8.004 17.128-16.937 3.191 3.158-20.319 20.094z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_014" x="1344" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 19.5c-15.74 0-28.5 12.76-28.5 28.498C19.5 63.74 32.26 76.5 48 76.5s28.5-12.76 28.5-28.502C76.5 32.26 63.74 19.5 48 19.5zm-6.109 42.859L29.552 50.157l3.49-3.448 8.849 8.748 18.72-18.511 3.488 3.451-22.208 21.962z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_015" x="1440" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 19c-16.017 0-29 12.984-29 28.998C19 64.018 31.983 77 48 77c16.018 0 29-12.982 29-29.002C77 31.984 64.018 19 48 19zm-6.085 43.359L28.706 49.297l3.736-3.69 9.473 9.364 20.04-19.816 3.734 3.694-23.774 23.51z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_016" x="1536" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 18.5c-16.293 0-29.5 13.208-29.5 29.498C18.5 64.293 31.707 77.5 48 77.5s29.5-13.207 29.5-29.502C77.5 31.708 64.293 18.5 48 18.5zm-6.104 43.859L28.063 48.68l3.913-3.866 9.921 9.808 20.988-20.753 3.912 3.869-24.901 24.621z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_017" x="1632" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 18c-16.569 0-30 13.431-30 29.998C18 64.568 31.431 78 48 78c16.568 0 30-13.432 30-30.002C78 31.431 64.568 18 48 18zm-6.096 44.359L27.52 48.134l4.068-4.02 10.316 10.198 21.825-21.58 4.066 4.023-25.891 25.604z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_018" x="1728" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17.5c-16.846 0-30.5 13.655-30.5 30.498C17.5 64.846 31.154 78.5 48 78.5s30.5-13.654 30.5-30.502C78.5 31.155 64.846 17.5 48 17.5zm-6.106 44.859L27.141 47.77l4.172-4.123 10.58 10.46 22.382-22.133 4.172 4.126-26.553 26.259z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_019" x="1824" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.09 45.359L26.881 47.497l4.25-4.2L41.91 53.953l22.803-22.548 4.25 4.204-27.053 26.75z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_020" x="1920" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.09 45.359L26.881 47.497l4.25-4.2L41.91 53.953l22.803-22.548 4.25 4.204-27.053 26.75z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_021" x="2016" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.079 45.359L27.038 47.64l4.209-4.159 10.674 10.553 22.583-22.331 4.209 4.164-26.792 26.492z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_022" x="2112" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.072 45.359L27.1 47.695l4.194-4.144 10.634 10.514 22.498-22.247 4.193 4.148-26.691 26.393z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_023" x="2208" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.08 45.359L27.209 47.811 31.37 43.7l10.55 10.431L64.24 32.06l4.16 4.115-26.48 26.184z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_024" x="2304" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.174 45.359L27.209 47.905l4.134-4.084 10.482 10.363L64 32.255l4.134 4.089-26.308 26.015z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_025" x="2400" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.087 45.359L27.428 48.035l4.097-4.047 10.388 10.27 21.976-21.731 4.098 4.052-26.074 25.78z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_026" x="2496" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M47.999 17C30.879 17 17 30.877 17 48c0 17.124 13.879 31 30.999 31C65.122 79 79 65.124 79 48c0-17.123-13.878-31-31.001-31zm-6.094 45.359L27.599 48.214l4.046-4L41.906 54.36 63.61 32.896l4.048 4.001-25.753 25.462z"/></svg></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg
new file mode 100644 (file)
index 0000000..fdea996
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_00" class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z
+                M48,3C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg
new file mode 100644 (file)
index 0000000..2393785
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_01" class="st0" d="M48,61c-16.5,0-30-13.5-30-30C18,14.5,31.5,1,48,1s30,13.5,30,30C78,47.5,64.5,61,48,61z M48,4
+               C32.6,4,21,15.6,21,31c0,15.4,11.6,27,27,27s27-11.6,27-27C75,15.6,63.4,4,48,4z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg
new file mode 100644 (file)
index 0000000..1769f8b
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_02" class="st0" d="M48,60c-16,0-29-13-29-29C19,15,32,2,48,2c16,0,29,13,29,29C77,47,64,60,48,60z M48,5
+               C33.1,5,22,16.1,22,31c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,16.1,62.9,5,48,5z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg
new file mode 100644 (file)
index 0000000..546fb5a
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_03" class="st0" d="M48,59c-15.4,0-28-12.6-28-28C20,15.6,32.6,3,48,3s28,12.6,28,28C76,46.4,63.4,59,48,59z M48,6
+               C33.7,6,23,16.7,23,31c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,16.7,62.3,6,48,6z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg
new file mode 100644 (file)
index 0000000..0be12f5
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_04" class="st0" d="M48,58c-14.9,0-27-12.1-27-27C21,16.1,33.1,4,48,4c14.9,0,27,12.1,27,27C75,45.9,62.9,58,48,58z
+                M48,7C34.2,7,24,17.2,24,31c0,13.8,10.2,24,24,24s24-10.2,24-24C72,17.2,61.8,7,48,7z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg
new file mode 100644 (file)
index 0000000..9ffc0fc
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_05" class="st0" d="M48,57c-14.3,0-26-11.7-26-26C22,16.7,33.7,5,48,5c14.3,0,26,11.7,26,26C74,45.3,62.3,57,48,57z
+                M48,8c-13.2,0-23,9.8-23,23c0,13.2,9.8,23,23,23c13.2,0,23-9.8,23-23C71,17.8,61.2,8,48,8z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg
new file mode 100644 (file)
index 0000000..a827265
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_06" class="st0" d="M48,57c-14.3,0-26-11.7-26-26C22,16.7,33.7,5,48,5c14.3,0,26,11.7,26,26C74,45.3,62.3,57,48,57z
+                M48,8c-13.2,0-23,9.8-23,23c0,13.2,9.8,23,23,23c13.2,0,23-9.8,23-23C71,17.8,61.2,8,48,8z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg
new file mode 100644 (file)
index 0000000..6fb4af1
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_07_2_">
+               <path class="st0" d="M48,57.5c-14.6,0-26.5-11.9-26.5-26.5C21.5,16.4,33.4,4.5,48,4.5c14.6,0,26.5,11.9,26.5,26.5
+                       C74.5,45.6,62.6,57.5,48,57.5z M48,7.5c-13.5,0-23.5,10-23.5,23.5c0,13.5,10,23.5,23.5,23.5c13.5,0,23.5-10,23.5-23.5
+                       C71.5,17.5,61.5,7.5,48,7.5z"/>
+               <circle class="st0" cx="48" cy="31" r="2"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg
new file mode 100644 (file)
index 0000000..634997b
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_08">
+               <path class="st0" d="M48,58c-14.9,0-27-12.1-27-27C21,16.1,33.1,4,48,4c14.9,0,27,12.1,27,27C75,45.9,62.9,58,48,58z M48,7
+                       C34.2,7,24,17.2,24,31c0,13.8,10.2,24,24,24s24-10.2,24-24C72,17.2,61.8,7,48,7z"/>
+               <circle class="st0" cx="48" cy="31" r="4"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg
new file mode 100644 (file)
index 0000000..7842a47
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_09">
+               <path class="st0" d="M48,58.5c-15.2,0-27.5-12.3-27.5-27.5C20.5,15.8,32.8,3.5,48,3.5c15.2,0,27.5,12.3,27.5,27.5
+                       C75.5,46.2,63.2,58.5,48,58.5z M48,6.5C33.9,6.5,23.5,16.9,23.5,31c0,14.1,10.4,24.5,24.5,24.5S72.5,45.1,72.5,31
+                       C72.5,16.9,62.1,6.5,48,6.5z"/>
+               <circle class="st0" cx="48" cy="31" r="6"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg
new file mode 100644 (file)
index 0000000..dff1c33
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_10">
+               <path class="st0" d="M48,59c-15.4,0-28-12.6-28-28C20,15.6,32.6,3,48,3s28,12.6,28,28C76,46.4,63.4,59,48,59z M48,6
+                       C33.7,6,23,16.7,23,31c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,16.7,62.3,6,48,6z"/>
+               <circle class="st0" cx="48" cy="31" r="8"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg
new file mode 100644 (file)
index 0000000..cf9e55e
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_11">
+               <path class="st0" d="M48,59.5c-15.7,0-28.5-12.8-28.5-28.5C19.5,15.3,32.3,2.5,48,2.5S76.5,15.3,76.5,31
+                       C76.5,46.7,63.7,59.5,48,59.5z M48,5.5C33.4,5.5,22.5,16.4,22.5,31c0,14.6,10.9,25.5,25.5,25.5c14.6,0,25.5-10.9,25.5-25.5
+                       C73.5,16.4,62.6,5.5,48,5.5z"/>
+               <circle class="st0" cx="48" cy="31" r="10"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg
new file mode 100644 (file)
index 0000000..59ce2b1
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_12">
+               <path class="st0" d="M48,60c-16,0-29-13-29-29C19,15,32,2,48,2c16,0,29,13,29,29C77,47,64,60,48,60z M48,5C33.1,5,22,16.1,22,31
+                       c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,16.1,62.9,5,48,5z"/>
+               <path class="st0" d="M60,31c0,6.6-5.4,12-12,12c-6.6,0-12-5.4-12-12c0-6.6,5.4-12,12-12C54.6,19,60,24.4,60,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg
new file mode 100644 (file)
index 0000000..c5edb25
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_13">
+               <path class="st0" d="M48,60.5c-16.3,0-29.5-13.2-29.5-29.5C18.5,14.7,31.7,1.5,48,1.5c16.3,0,29.5,13.2,29.5,29.5
+                       C77.5,47.3,64.3,60.5,48,60.5z M48,4.5C32.8,4.5,21.5,15.8,21.5,31c0,15.2,11.3,26.5,26.5,26.5c15.2,0,26.5-11.3,26.5-26.5
+                       C74.5,15.8,63.2,4.5,48,4.5z"/>
+               <path class="st0" d="M62,31c0,7.7-6.3,14-14,14c-7.7,0-14-6.3-14-14s6.3-14,14-14C55.7,17,62,23.3,62,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg
new file mode 100644 (file)
index 0000000..a4376fb
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_14">
+               <path class="st0" d="M48,61c-16.5,0-30-13.5-30-30C18,14.5,31.5,1,48,1s30,13.5,30,30C78,47.5,64.5,61,48,61z M48,4
+                       C32.6,4,21,15.6,21,31c0,15.4,11.6,27,27,27s27-11.6,27-27C75,15.6,63.4,4,48,4z"/>
+               <path class="st0" d="M64,31c0,8.8-7.2,16-16,16c-8.8,0-16-7.2-16-16c0-8.8,7.2-16,16-16C56.8,15,64,22.2,64,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg
new file mode 100644 (file)
index 0000000..5e5d247
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_15">
+               <path class="st0" d="M48,61.5c-16.8,0-30.5-13.7-30.5-30.5C17.5,14.2,31.2,0.5,48,0.5c16.8,0,30.5,13.7,30.5,30.5
+                       C78.5,47.8,64.8,61.5,48,61.5z M48,3.5C32.3,3.5,20.5,15.3,20.5,31c0,15.7,11.8,27.5,27.5,27.5S75.5,46.7,75.5,31
+                       C75.5,15.3,63.7,3.5,48,3.5z"/>
+               <path class="st0" d="M66,31c0,9.9-8.1,18-18,18c-9.9,0-18-8.1-18-18c0-9.9,8.1-18,18-18C57.9,13,66,21.1,66,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg
new file mode 100644 (file)
index 0000000..24edcda
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_16">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M68,31c0,11-9,20-20,20c-11.1,0-20-9-20-20c0-11,8.9-20,20-20C59,11,68,20,68,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg
new file mode 100644 (file)
index 0000000..7277061
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_17">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M67.6,31c0,10.8-8.8,19.6-19.6,19.6c-10.8,0-19.6-8.8-19.6-19.6c0-10.8,8.8-19.6,19.6-19.6
+                       C58.8,11.4,67.6,20.2,67.6,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg
new file mode 100644 (file)
index 0000000..5678539
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_18">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M67.2,31c0,10.6-8.6,19.2-19.2,19.2c-10.6,0-19.2-8.6-19.2-19.2c0-10.6,8.6-19.2,19.2-19.2
+                       C58.6,11.7,67.2,20.4,67.2,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg
new file mode 100644 (file)
index 0000000..2da187b
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_19">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M66.9,31c0,10.4-8.4,18.9-18.9,18.9c-10.4,0-18.9-8.4-18.9-18.9c0-10.4,8.4-18.9,18.9-18.9
+                       C58.4,12.1,66.9,20.6,66.9,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg
new file mode 100644 (file)
index 0000000..3751068
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_20">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M66.5,31c0,10.2-8.3,18.5-18.5,18.5c-10.2,0-18.5-8.3-18.5-18.5c0-10.2,8.3-18.5,18.5-18.5
+                       C58.2,12.5,66.5,20.8,66.5,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg
new file mode 100644 (file)
index 0000000..8f4f548
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_21">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M66.1,31c0,10-8.1,18.1-18.1,18.1C38,49.1,29.9,41,29.9,31c0-10,8.1-18.1,18.1-18.1C58,12.9,66.1,21,66.1,31z
+                       "/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg
new file mode 100644 (file)
index 0000000..eabda7c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_22">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32.6,3,20,15.6,20,31c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,15.6,63.4,3,48,3z"/>
+               <path class="st0" d="M65.7,31c0,9.8-7.9,17.8-17.8,17.8c-9.8,0-17.8-7.9-17.8-17.8c0-9.8,7.9-17.8,17.8-17.8
+                       C57.8,13.2,65.7,21.2,65.7,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg
new file mode 100644 (file)
index 0000000..bdd327c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_23">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32.6,3,20,15.6,20,31c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,15.6,63.4,3,48,3z"/>
+               <path class="st0" d="M65.4,31c0,9.6-7.8,17.4-17.4,17.4c-9.6,0-17.4-7.8-17.4-17.4c0-9.6,7.8-17.4,17.4-17.4
+                       C57.6,13.6,65.4,21.4,65.4,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg
new file mode 100644 (file)
index 0000000..f1e5d37
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_24">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32.6,3,20,15.6,20,31c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,15.6,63.4,3,48,3z"/>
+               <path class="st0" d="M65.2,31c0,9.5-7.7,17.2-17.2,17.2c-9.5,0-17.2-7.7-17.2-17.2c0-9.5,7.7-17.2,17.2-17.2
+                       C57.5,13.7,65.2,21.5,65.2,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg
new file mode 100644 (file)
index 0000000..f0627c1
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_25">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32.6,3,20,15.6,20,31c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,15.6,63.4,3,48,3z"/>
+               <path class="st0" d="M65.1,31c0,9.5-7.7,17.1-17.1,17.1c-9.5,0-17.1-7.7-17.1-17.1c0-9.5,7.7-17.1,17.1-17.1
+                       C57.5,13.9,65.1,21.5,65.1,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg
new file mode 100644 (file)
index 0000000..8b680a9
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_26">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M65,31c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17c0-9.4,7.6-17,17-17C57.4,14,65,21.6,65,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_000.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_000.svg
new file mode 100644 (file)
index 0000000..81c3804
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_00" class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z
+                M48,20c-16,0-28,12-28,28c0,16,12,28,28,28c16,0,28-12,28-28C76,32,64,20,48,20z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_001.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_001.svg
new file mode 100644 (file)
index 0000000..eedb6bc
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_01" class="st0" d="M48,78c-16.5,0-30-13.5-30-30c0-16.5,13.5-30,30-30s30,13.5,30,30C78,64.5,64.5,78,48,78z M48,21
+               c-15.4,0-27,11.6-27,27c0,15.4,11.6,27,27,27s27-11.6,27-27C75,32.6,63.4,21,48,21z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_002.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_002.svg
new file mode 100644 (file)
index 0000000..65a2f45
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_02" class="st0" d="M48,77c-16,0-29-13-29-29c0-16,13-29,29-29c16,0,29,13,29,29C77,64,64,77,48,77z M48,22
+               c-14.9,0-26,11.1-26,26c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,33.1,62.9,22,48,22z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_003.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_003.svg
new file mode 100644 (file)
index 0000000..ababc5e
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_03" class="st0" d="M48,76c-15.4,0-28-12.6-28-28c0-15.4,12.6-28,28-28s28,12.6,28,28C76,63.4,63.4,76,48,76z M48,23
+               c-14.3,0-25,10.7-25,25c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,33.7,62.3,23,48,23z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_004.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_004.svg
new file mode 100644 (file)
index 0000000..8b0b9ca
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_04" class="st0" d="M48,75c-14.9,0-27-12.1-27-27c0-14.9,12.1-27,27-27c14.9,0,27,12.1,27,27C75,62.9,62.9,75,48,75z
+                M48,24c-13.8,0-24,10.2-24,24c0,13.8,10.2,24,24,24s24-10.2,24-24C72,34.2,61.8,24,48,24z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_005.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_005.svg
new file mode 100644 (file)
index 0000000..6561850
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_05" class="st0" d="M48,74c-14.3,0-26-11.7-26-26c0-14.3,11.7-26,26-26c14.3,0,26,11.7,26,26C74,62.3,62.3,74,48,74z
+                M48,25c-13.2,0-23,9.8-23,23c0,13.2,9.8,23,23,23c13.2,0,23-9.8,23-23C71,34.8,61.2,25,48,25z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_006.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_006.svg
new file mode 100644 (file)
index 0000000..77becb2
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_06" class="st0" d="M48,74c-14.3,0-26-11.7-26-26c0-14.3,11.7-26,26-26c14.3,0,26,11.7,26,26C74,62.3,62.3,74,48,74z
+                M48,25c-13.2,0-23,9.8-23,23c0,13.2,9.8,23,23,23c13.2,0,23-9.8,23-23C71,34.8,61.2,25,48,25z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_007.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_007.svg
new file mode 100644 (file)
index 0000000..f6e2b70
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_07_2_">
+               <path class="st0" d="M48,74.5c-14.6,0-26.5-11.9-26.5-26.5c0-14.6,11.9-26.5,26.5-26.5c14.6,0,26.5,11.9,26.5,26.5
+                       C74.5,62.6,62.6,74.5,48,74.5z M48,24.5c-13.5,0-23.5,10-23.5,23.5c0,13.5,10,23.5,23.5,23.5c13.5,0,23.5-10,23.5-23.5
+                       C71.5,34.5,61.5,24.5,48,24.5z"/>
+               <circle class="st0" cx="48" cy="48" r="2"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_008.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_008.svg
new file mode 100644 (file)
index 0000000..9180257
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_08">
+               <path class="st0" d="M48,75c-14.9,0-27-12.1-27-27c0-14.9,12.1-27,27-27c14.9,0,27,12.1,27,27C75,62.9,62.9,75,48,75z M48,24
+                       c-13.8,0-24,10.2-24,24c0,13.8,10.2,24,24,24s24-10.2,24-24C72,34.2,61.8,24,48,24z"/>
+               <circle class="st0" cx="48" cy="48" r="4"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_009.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_009.svg
new file mode 100644 (file)
index 0000000..5999420
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_09">
+               <path class="st0" d="M48,75.5c-15.2,0-27.5-12.3-27.5-27.5c0-15.2,12.3-27.5,27.5-27.5c15.2,0,27.5,12.3,27.5,27.5
+                       C75.5,63.2,63.2,75.5,48,75.5z M48,23.5c-14.1,0-24.5,10.4-24.5,24.5c0,14.1,10.4,24.5,24.5,24.5S72.5,62.1,72.5,48
+                       C72.5,33.9,62.1,23.5,48,23.5z"/>
+               <circle class="st0" cx="48" cy="48" r="6"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_010.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_010.svg
new file mode 100644 (file)
index 0000000..8b5146e
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_10">
+               <path class="st0" d="M48,76c-15.4,0-28-12.6-28-28c0-15.4,12.6-28,28-28s28,12.6,28,28C76,63.4,63.4,76,48,76z M48,23
+                       c-14.3,0-25,10.7-25,25c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,33.7,62.3,23,48,23z"/>
+               <circle class="st0" cx="48" cy="48" r="8"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_011.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_011.svg
new file mode 100644 (file)
index 0000000..fbe560d
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_11">
+               <path class="st0" d="M48,76.5c-15.7,0-28.5-12.8-28.5-28.5c0-15.7,12.8-28.5,28.5-28.5S76.5,32.3,76.5,48
+                       C76.5,63.7,63.7,76.5,48,76.5z M48,22.5c-14.6,0-25.5,10.9-25.5,25.5c0,14.6,10.9,25.5,25.5,25.5c14.6,0,25.5-10.9,25.5-25.5
+                       C73.5,33.4,62.6,22.5,48,22.5z"/>
+               <circle class="st0" cx="48" cy="48" r="10"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_012.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_012.svg
new file mode 100644 (file)
index 0000000..1098932
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_12">
+               <path class="st0" d="M48,77c-16,0-29-13-29-29c0-16,13-29,29-29c16,0,29,13,29,29C77,64,64,77,48,77z M48,22
+                       c-14.9,0-26,11.1-26,26c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,33.1,62.9,22,48,22z"/>
+               <path class="st0" d="M60,48c0,6.6-5.4,12-12,12c-6.6,0-12-5.4-12-12c0-6.6,5.4-12,12-12C54.6,36,60,41.4,60,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_013.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_013.svg
new file mode 100644 (file)
index 0000000..6c497df
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_13">
+               <path class="st0" d="M48,77.5c-16.3,0-29.5-13.2-29.5-29.5c0-16.3,13.2-29.5,29.5-29.5c16.3,0,29.5,13.2,29.5,29.5
+                       C77.5,64.3,64.3,77.5,48,77.5z M48,21.5c-15.2,0-26.5,11.3-26.5,26.5c0,15.2,11.3,26.5,26.5,26.5c15.2,0,26.5-11.3,26.5-26.5
+                       C74.5,32.8,63.2,21.5,48,21.5z"/>
+               <path class="st0" d="M62,48c0,7.7-6.3,14-14,14c-7.7,0-14-6.3-14-14s6.3-14,14-14C55.7,34,62,40.3,62,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_014.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_014.svg
new file mode 100644 (file)
index 0000000..1f71fd7
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_14">
+               <path class="st0" d="M48,78c-16.5,0-30-13.5-30-30c0-16.5,13.5-30,30-30s30,13.5,30,30C78,64.5,64.5,78,48,78z M48,21
+                       c-15.4,0-27,11.6-27,27c0,15.4,11.6,27,27,27s27-11.6,27-27C75,32.6,63.4,21,48,21z"/>
+               <path class="st0" d="M64,48c0,8.8-7.2,16-16,16c-8.8,0-16-7.2-16-16c0-8.8,7.2-16,16-16C56.8,32,64,39.2,64,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_015.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_015.svg
new file mode 100644 (file)
index 0000000..66a948e
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_15">
+               <path class="st0" d="M48,78.5c-16.8,0-30.5-13.7-30.5-30.5c0-16.8,13.7-30.5,30.5-30.5c16.8,0,30.5,13.7,30.5,30.5
+                       C78.5,64.8,64.8,78.5,48,78.5z M48,20.5c-15.7,0-27.5,11.8-27.5,27.5c0,15.7,11.8,27.5,27.5,27.5S75.5,63.7,75.5,48
+                       C75.5,32.3,63.7,20.5,48,20.5z"/>
+               <path class="st0" d="M66,48c0,9.9-8.1,18-18,18c-9.9,0-18-8.1-18-18c0-9.9,8.1-18,18-18C57.9,30,66,38.1,66,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_016.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_016.svg
new file mode 100644 (file)
index 0000000..ef9847b
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_16">
+               <path class="st0" d="M68,48c0,11-9,20-20,20c-11.1,0-20-9-20-20c0-11,8.9-20,20-20C59,28,68,37,68,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_017.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_017.svg
new file mode 100644 (file)
index 0000000..9e81377
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_17">
+               <path class="st0" d="M67.6,48c0,10.8-8.8,19.6-19.6,19.6c-10.8,0-19.6-8.8-19.6-19.6c0-10.8,8.8-19.6,19.6-19.6
+                       C58.8,28.4,67.6,37.2,67.6,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_018.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_018.svg
new file mode 100644 (file)
index 0000000..2056b2c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_18">
+               <path class="st0" d="M67.2,48c0,10.6-8.6,19.2-19.2,19.2c-10.6,0-19.2-8.6-19.2-19.2c0-10.6,8.6-19.2,19.2-19.2
+                       C58.6,28.7,67.2,37.4,67.2,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_019.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_019.svg
new file mode 100644 (file)
index 0000000..897e7cc
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_19">
+               <path class="st0" d="M66.9,48c0,10.4-8.4,18.9-18.9,18.9c-10.4,0-18.9-8.4-18.9-18.9c0-10.4,8.4-18.9,18.9-18.9
+                       C58.4,29.1,66.9,37.6,66.9,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_020.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_020.svg
new file mode 100644 (file)
index 0000000..c37c017
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_20">
+               <path class="st0" d="M66.5,48c0,10.2-8.3,18.5-18.5,18.5c-10.2,0-18.5-8.3-18.5-18.5c0-10.2,8.3-18.5,18.5-18.5
+                       C58.2,29.5,66.5,37.8,66.5,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_021.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_021.svg
new file mode 100644 (file)
index 0000000..05d9d56
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_21">
+               <path class="st0" d="M66.1,48c0,10-8.1,18.1-18.1,18.1C38,66.1,29.9,58,29.9,48c0-10,8.1-18.1,18.1-18.1C58,29.9,66.1,38,66.1,48z
+                       "/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_022.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_022.svg
new file mode 100644 (file)
index 0000000..f984c11
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_22">
+               <path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+                       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+               <path class="st0" d="M65.7,48c0,9.8-7.9,17.8-17.8,17.8c-9.8,0-17.8-7.9-17.8-17.8c0-9.8,7.9-17.8,17.8-17.8
+                       C57.8,30.2,65.7,38.2,65.7,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_023.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_023.svg
new file mode 100644 (file)
index 0000000..075772f
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_23">
+               <path class="st0" d="M65.4,48c0,9.6-7.8,17.4-17.4,17.4c-9.6,0-17.4-7.8-17.4-17.4c0-9.6,7.8-17.4,17.4-17.4
+                       C57.6,30.6,65.4,38.4,65.4,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_024.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_024.svg
new file mode 100644 (file)
index 0000000..94dbc43
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_24">
+               <path class="st0" d="M65.2,48c0,9.5-7.7,17.2-17.2,17.2c-9.5,0-17.2-7.7-17.2-17.2c0-9.5,7.7-17.2,17.2-17.2
+                       C57.5,30.7,65.2,38.5,65.2,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_025.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_025.svg
new file mode 100644 (file)
index 0000000..f0e9d49
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_25">
+               <path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+                       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+               <path class="st0" d="M65.1,48c0,9.5-7.7,17.1-17.1,17.1c-9.5,0-17.1-7.7-17.1-17.1c0-9.5,7.7-17.1,17.1-17.1
+                       C57.5,30.9,65.1,38.5,65.1,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_026.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_026.svg
new file mode 100644 (file)
index 0000000..1a6e41c
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_26">
+               <path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+                       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+               <path class="st0" d="M65,48c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17c0-9.4,7.6-17,17-17C57.4,31,65,38.6,65,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg
new file mode 100644 (file)
index 0000000..ec21dc3
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="2592" height="96" viewBox="0 0 2592 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_000" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_00" class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-16 0-28 12-28 28s12 28 28 28 28-12 28-28-12-28-28-28z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_001" x="96" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_01" class="st0" d="M48 78c-16.5 0-30-13.5-30-30s13.5-30 30-30 30 13.5 30 30-13.5 30-30 30zm0-57c-15.4 0-27 11.6-27 27s11.6 27 27 27 27-11.6 27-27-11.6-27-27-27z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_002" x="192" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_02" class="st0" d="M48 77c-16 0-29-13-29-29s13-29 29-29 29 13 29 29-13 29-29 29zm0-55c-14.9 0-26 11.1-26 26s11.1 26 26 26 26-11.1 26-26-11.1-26-26-26z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_003" x="288" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_03" class="st0" d="M48 76c-15.4 0-28-12.6-28-28s12.6-28 28-28 28 12.6 28 28-12.6 28-28 28zm0-53c-14.3 0-25 10.7-25 25s10.7 25 25 25 25-10.7 25-25-10.7-25-25-25z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_004" x="384" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_04" class="st0" d="M48 75c-14.9 0-27-12.1-27-27s12.1-27 27-27 27 12.1 27 27-12.1 27-27 27zm0-51c-13.8 0-24 10.2-24 24s10.2 24 24 24 24-10.2 24-24-10.2-24-24-24z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_005" x="480" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_05" class="st0" d="M48 74c-14.3 0-26-11.7-26-26s11.7-26 26-26 26 11.7 26 26-11.7 26-26 26zm0-49c-13.2 0-23 9.8-23 23s9.8 23 23 23 23-9.8 23-23-9.8-23-23-23z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_006" x="576" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_06" class="st0" d="M48 74c-14.3 0-26-11.7-26-26s11.7-26 26-26 26 11.7 26 26-11.7 26-26 26zm0-49c-13.2 0-23 9.8-23 23s9.8 23 23 23 23-9.8 23-23-9.8-23-23-23z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_007" x="672" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_07_2_"><path class="st0" d="M48 74.5c-14.6 0-26.5-11.9-26.5-26.5S33.4 21.5 48 21.5 74.5 33.4 74.5 48 62.6 74.5 48 74.5zm0-50c-13.5 0-23.5 10-23.5 23.5s10 23.5 23.5 23.5 23.5-10 23.5-23.5-10-23.5-23.5-23.5z"/><circle class="st0" cx="48" cy="48" r="2"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_008" x="768" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_08"><path class="st0" d="M48 75c-14.9 0-27-12.1-27-27s12.1-27 27-27 27 12.1 27 27-12.1 27-27 27zm0-51c-13.8 0-24 10.2-24 24s10.2 24 24 24 24-10.2 24-24-10.2-24-24-24z"/><circle class="st0" cx="48" cy="48" r="4"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_009" x="864" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_09"><path class="st0" d="M48 75.5c-15.2 0-27.5-12.3-27.5-27.5S32.8 20.5 48 20.5 75.5 32.8 75.5 48 63.2 75.5 48 75.5zm0-52c-14.1 0-24.5 10.4-24.5 24.5S33.9 72.5 48 72.5 72.5 62.1 72.5 48 62.1 23.5 48 23.5z"/><circle class="st0" cx="48" cy="48" r="6"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_010" x="960" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_10"><path class="st0" d="M48 76c-15.4 0-28-12.6-28-28s12.6-28 28-28 28 12.6 28 28-12.6 28-28 28zm0-53c-14.3 0-25 10.7-25 25s10.7 25 25 25 25-10.7 25-25-10.7-25-25-25z"/><circle class="st0" cx="48" cy="48" r="8"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_011" x="1056" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_11"><path class="st0" d="M48 76.5c-15.7 0-28.5-12.8-28.5-28.5S32.3 19.5 48 19.5 76.5 32.3 76.5 48 63.7 76.5 48 76.5zm0-54c-14.6 0-25.5 10.9-25.5 25.5S33.4 73.5 48 73.5 73.5 62.6 73.5 48 62.6 22.5 48 22.5z"/><circle class="st0" cx="48" cy="48" r="10"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_012" x="1152" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_12"><path class="st0" d="M48 77c-16 0-29-13-29-29s13-29 29-29 29 13 29 29-13 29-29 29zm0-55c-14.9 0-26 11.1-26 26s11.1 26 26 26 26-11.1 26-26-11.1-26-26-26z"/><path class="st0" d="M60 48c0 6.6-5.4 12-12 12s-12-5.4-12-12 5.4-12 12-12 12 5.4 12 12z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_013" x="1248" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_13"><path class="st0" d="M48 77.5c-16.3 0-29.5-13.2-29.5-29.5S31.7 18.5 48 18.5 77.5 31.7 77.5 48 64.3 77.5 48 77.5zm0-56c-15.2 0-26.5 11.3-26.5 26.5S32.8 74.5 48 74.5 74.5 63.2 74.5 48 63.2 21.5 48 21.5z"/><path class="st0" d="M62 48c0 7.7-6.3 14-14 14s-14-6.3-14-14 6.3-14 14-14 14 6.3 14 14z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_014" x="1344" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_14"><path class="st0" d="M48 78c-16.5 0-30-13.5-30-30s13.5-30 30-30 30 13.5 30 30-13.5 30-30 30zm0-57c-15.4 0-27 11.6-27 27s11.6 27 27 27 27-11.6 27-27-11.6-27-27-27z"/><path class="st0" d="M64 48c0 8.8-7.2 16-16 16s-16-7.2-16-16 7.2-16 16-16 16 7.2 16 16z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_015" x="1440" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_15"><path class="st0" d="M48 78.5c-16.8 0-30.5-13.7-30.5-30.5S31.2 17.5 48 17.5 78.5 31.2 78.5 48 64.8 78.5 48 78.5zm0-58c-15.7 0-27.5 11.8-27.5 27.5S32.3 75.5 48 75.5 75.5 63.7 75.5 48 63.7 20.5 48 20.5z"/><path class="st0" d="M66 48c0 9.9-8.1 18-18 18s-18-8.1-18-18 8.1-18 18-18 18 8.1 18 18z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_016" x="1536" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M68 48c0 11-9 20-20 20-11.1 0-20-9-20-20s8.9-20 20-20c11 0 20 9 20 20z" id="_x30_16"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_017" x="1632" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M67.6 48c0 10.8-8.8 19.6-19.6 19.6S28.4 58.8 28.4 48 37.2 28.4 48 28.4 67.6 37.2 67.6 48z" id="_x30_17"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_018" x="1728" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M67.2 48c0 10.6-8.6 19.2-19.2 19.2S28.8 58.6 28.8 48 37.4 28.8 48 28.8c10.6-.1 19.2 8.6 19.2 19.2z" id="_x30_18"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_019" x="1824" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M66.9 48c0 10.4-8.4 18.9-18.9 18.9-10.4 0-18.9-8.4-18.9-18.9 0-10.4 8.4-18.9 18.9-18.9 10.4 0 18.9 8.5 18.9 18.9z" id="_x30_19"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_020" x="1920" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M66.5 48c0 10.2-8.3 18.5-18.5 18.5S29.5 58.2 29.5 48 37.8 29.5 48 29.5 66.5 37.8 66.5 48z" id="_x30_20"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_021" x="2016" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M66.1 48c0 10-8.1 18.1-18.1 18.1-10 0-18.1-8.1-18.1-18.1 0-10 8.1-18.1 18.1-18.1 10 0 18.1 8.1 18.1 18.1z" id="_x30_21"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_022" x="2112" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_22"><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/><path class="st0" d="M65.7 48c0 9.8-7.9 17.8-17.8 17.8-9.8 0-17.8-7.9-17.8-17.8 0-9.8 7.9-17.8 17.8-17.8s17.8 8 17.8 17.8z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_023" x="2208" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M65.4 48c0 9.6-7.8 17.4-17.4 17.4-9.6 0-17.4-7.8-17.4-17.4 0-9.6 7.8-17.4 17.4-17.4 9.6 0 17.4 7.8 17.4 17.4z" id="_x30_23"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_024" x="2304" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M65.2 48c0 9.5-7.7 17.2-17.2 17.2S30.8 57.5 30.8 48 38.5 30.8 48 30.8c9.5-.1 17.2 7.7 17.2 17.2z" id="_x30_24"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_025" x="2400" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_25"><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/><path class="st0" d="M65.1 48c0 9.5-7.7 17.1-17.1 17.1-9.5 0-17.1-7.7-17.1-17.1 0-9.5 7.7-17.1 17.1-17.1 9.5 0 17.1 7.6 17.1 17.1z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_026" x="2496" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_26"><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/><path class="st0" d="M65 48c0 9.4-7.6 17-17 17s-17-7.6-17-17 7.6-17 17-17 17 7.6 17 17z"/></g></g></svg></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/gallery_btn_check_bg_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/gallery_btn_check_bg_mtrl.svg
new file mode 100644 (file)
index 0000000..fce19cf
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<path fill="#777777" fill-opacity="0.6588" d="M47.999,16.25C30.493,16.25,16.25,30.493,16.25,48\r
+       c0,17.507,14.243,31.75,31.749,31.75C65.507,79.75,79.75,65.507,79.75,48C79.75,30.493,65.507,16.25,47.999,16.25z M47.999,79\r
+       C30.88,79,17,65.122,17,48s13.88-31,30.999-31C65.123,17,79,30.877,79,48S65.123,79,47.999,79z"/>\r
+<path fill="#231F20" fill-opacity="0.3176" d="M48,17c-17.112,0-31,13.888-31,31c0,17.112,13.888,31,31,31c17.112,0,31-13.888,31-31\r
+       C79,30.888,65.112,17,48,17z"/>\r
+<path fill="#797979" fill-opacity="0.6471" d="M63.611,32.895L41.905,54.358l-10.26-10.146l-4.046,4.001l14.307,14.146\r
+       l25.751-25.463L63.611,32.895z M28.666,48.214l2.979-2.947l10.26,10.146L63.611,33.95l2.979,2.947L41.905,61.305L28.666,48.214z"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg
new file mode 100644 (file)
index 0000000..854e16c
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<path fill="#797979" fill-opacity="0.498" d="M47.999,16.25C30.492,16.25,16.25,30.493,16.25,48c0,17.508,14.242,31.75,31.749,31.75\r
+       C65.507,79.75,79.75,65.508,79.75,48C79.75,30.493,65.507,16.25,47.999,16.25z M47.999,79C30.881,79,17,65.123,17,48\r
+       s13.881-31,30.999-31C65.123,17,79,30.877,79,48S65.123,79,47.999,79z"/>\r
+<path fill="#231F20" fill-opacity="0.3176" d="M48,17c-17.112,0-31,13.888-31,31c0,17.112,13.888,31,31,31c17.112,0,31-13.888,31-31\r
+       C79,30.888,65.112,17,48,17z"/>\r
+<path fill="#797979" fill-opacity="0.498" d="M48,20c-15.464,0-28,12.536-28,28c0,15.465,12.536,28,28,28s28-12.535,28-28\r
+       C76,32.536,63.464,20,48,20z M48,75.25c-15.026,0-27.25-12.225-27.25-27.25c0-15.026,12.224-27.25,27.25-27.25\r
+       c15.025,0,27.25,12.224,27.25,27.25C75.25,63.025,63.025,75.25,48,75.25z"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_chips_icon_add_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_chips_icon_add_mtrl.svg
new file mode 100644 (file)
index 0000000..ef498c6
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="60px" height="60px" viewBox="0 0 60 60" enable-background="new 0 0 60 60" xml:space="preserve">\r
+<rect x="11.627" y="27.85" fill="#231F20" width="36" height="5"/>\r
+<rect x="27.141" y="12.131" fill="#231F20" width="5" height="36"/>\r
+<rect fill="none" width="60" height="60"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_chips_icon_delete_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_chips_icon_delete_mtrl.svg
new file mode 100644 (file)
index 0000000..64ea5d9
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="60px" height="60px" viewBox="0 0 60 60" enable-background="new 0 0 60 60" xml:space="preserve">\r
+<rect x="11.627" y="27.85" fill="#231F20" width="36" height="5"/>\r
+<rect fill="none" width="60" height="60"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_expander_close_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_expander_close_mtrl.svg
new file mode 100644 (file)
index 0000000..4a48058
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="70.53 64.5 48 40.78 25.47 64.5 21 59.92 48 31.5 75 59.92 70.53 64.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_expander_open_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_expander_open_mtrl.svg
new file mode 100644 (file)
index 0000000..f6597b9
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="70.53 31.5 48 55.22 25.47 31.5 21 36.08 48 64.5 75 36.08 70.53 31.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_add_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_add_mtrl.svg
new file mode 100644 (file)
index 0000000..bfa2535
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<polygon points="71.25,45 51,45 51,24.75 45,24.75 45,45 24.75,45 24.75,51.001 45,51.001 45,71.25 51,71.25 51,51.001 \r
+       71.25,51.001 "/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_delete_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_delete_mtrl.svg
new file mode 100644 (file)
index 0000000..ee3a127
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<rect x="24.75" y="45" width="46.5" height="6.001"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_reorder.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/3_Controllers/tw_list_icon_reorder.svg
new file mode 100644 (file)
index 0000000..58ffad3
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">
+<path d="M60.992,41.771L47.969,28.696L34.998,41.769l-3.158-3.14l16.123-16.246l16.184,16.244L60.992,41.771L60.992,41.771z"/>
+<path d="M48.024,73.615L31.795,57.379l3.149-3.149l13.074,13.081L61.04,54.231l3.153,3.145L48.024,73.615L48.024,73.615z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/4_Dialogs/tw_numberpicker_next_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/4_Dialogs/tw_numberpicker_next_mtrl.svg
new file mode 100644 (file)
index 0000000..34762a3
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="108px" height="108px" viewBox="0 0 108 108" enable-background="new 0 0 108 108" xml:space="preserve">
+<g>
+       <polygon points="52.993,72.433 50.696,70.144 66.883,53.999 50.695,37.856 52.993,35.567 71.477,53.999    "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/4_Dialogs/tw_numberpicker_prev_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/4_Dialogs/tw_numberpicker_prev_mtrl.svg
new file mode 100644 (file)
index 0000000..22f62bc
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="108px" height="108px" viewBox="0 0 108 108" enable-background="new 0 0 108 108" xml:space="preserve">
+<g>
+       <polygon points="53.307,72.433 55.604,70.144 39.417,53.999 55.605,37.856 53.308,35.567 34.823,53.999    "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_expander_close_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_expander_close_mtrl.svg
new file mode 100644 (file)
index 0000000..4a48058
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="70.53 64.5 48 40.78 25.47 64.5 21 59.92 48 31.5 75 59.92 70.53 64.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_expander_open_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_expander_open_mtrl.svg
new file mode 100644 (file)
index 0000000..f6597b9
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="70.53 31.5 48 55.22 25.47 31.5 21 36.08 48 64.5 75 36.08 70.53 31.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_connections.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_connections.svg
new file mode 100644 (file)
index 0000000..3e97dd5
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/01_connections copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_01_x5F_connections-copy">
+       <g id="Settings_x2F_Menu-tree_x2F_connections" transform="translate(8.000000, 8.000000)">
+               <path id="Connections" d="M52,68.4c1.2,0,2.4,0.5,3.3,1.4c0.7,0.7,1.1,1.6,1.3,2.5c0,0.2,0.1,0.3,0.1,0.5c0.1,1.3-0.4,2.6-1.3,3.6
+                       c-0.9,0.9-2.1,1.4-3.3,1.4c-1.2,0-2.4-0.5-3.3-1.4c-1-1.1-1.5-2.5-1.3-4c0-0.1,0-0.2,0.1-0.3c0.2-0.9,0.6-1.7,1.2-2.3
+                       C49.5,68.8,50.7,68.4,52,68.4z M51.9,55.1c6,0,11.4,2.5,15.2,6.5l0,0l-4.8,4.8c-2.6-2.8-6.3-4.5-10.5-4.5c-4.1,0-7.7,1.7-10.3,4.4
+                       l0,0l-4.8-4.8C40.7,57.5,46,55.1,51.9,55.1z M51.9,40.6c10,0,19,4.1,25.5,10.7l0,0l-4.7,4.7c-5.3-5.4-12.6-8.8-20.7-8.8
+                       c-8.1,0-15.4,3.3-20.6,8.6l0,0l-4.7-4.7C33,44.7,42,40.6,51.9,40.6z M51.9,26.3c13.9,0,26.5,5.7,35.6,14.9l0,0L82.8,46
+                       C74.9,38,64,33,51.9,33c-12,0-22.9,4.9-30.7,12.8l0,0l-4.7-4.7C25.5,32,38.1,26.3,51.9,26.3z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_display.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_display.svg
new file mode 100644 (file)
index 0000000..262c8be
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/04_display copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_04_x5F_display-copy">
+       <g id="Common_x2F_brightness" transform="translate(6.000000, 6.000000)">
+               <path id="Brightness" d="M57.7,77.8v10.5h-7V77.8H57.7z M34.5,68.1l5,4.9l-7.3,7.5l-5-4.9L34.5,68.1z M73.5,67.9l7.3,7.5l-5,4.9
+                       l-7.3-7.5L73.5,67.9z M54.2,39c8.3,0,15.1,6.7,15.1,15s-6.7,15.1-15.1,15.1s-15-6.7-15-15.1S45.9,39,54.2,39z M88.1,51.6v7H78v-7
+                       H88.1z M30,51.6v7H19.9v-7H30z M32.5,27.7l7.3,7.5l-5,4.9l-7.3-7.5L32.5,27.7z M75.7,27.5l5,4.9l-7.3,7.5l-5-4.9L75.7,27.5z
+                        M57.7,19.7v10.5h-7V19.7H57.7z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_notifications.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_notifications.svg
new file mode 100644 (file)
index 0000000..c97ee90
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/03_notifications copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_03_x5F_notifications-copy">
+       <g id="Settings_x2F_Menu-tree_x2F_notifications" transform="translate(8.000000, 8.000000)">
+               <path id="Notifications" d="M59.4,35.9c-0.1,0.4-0.2,0.9-0.3,1.4c-0.1,0.5-0.1,0.9-0.2,1.4c0,0.4-0.1,0.8-0.1,1.3
+                       c0,9,7.3,16.4,16.4,16.4c0,0,0.1,0,0.1,0c0.5,0,0.9,0,1.4-0.1c0.5,0,0.9-0.1,1.4-0.2l0,0v4.9c0,6.8-5.5,12.3-12.3,12.3l0,0H33
+                       c-6.8,0-12.3-5.5-12.3-12.3l0,0h0V48.2c0-6.8,5.5-12.3,12.3-12.3l0,0H59.4z M75.3,29.9c5.5,0,10,4.5,10,10c0,4.6-3,8.4-7.2,9.6
+                       c-0.4,0.1-0.9,0.2-1.4,0.3c-0.4,0.1-0.9,0.1-1.4,0.1c0,0-0.1,0-0.1,0c-5.5,0-10-4.5-10-10c0-0.4,0-0.9,0.1-1.3
+                       c0.1-0.5,0.1-0.9,0.3-1.4c0.1-0.5,0.3-0.9,0.5-1.3C67.6,32.4,71.2,29.9,75.3,29.9z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_sound.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_sound.svg
new file mode 100644 (file)
index 0000000..1a23692
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/02_sound copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_02_x5F_sound-copy">
+       <g id="Common_x2F_volume_x5F_media" transform="translate(8.000000, 8.000000)">
+               <path id="Volume-_x2F_-Media" d="M50.3,28.3c1.8-1.8,3.6-1.2,3.6,1.2l0,0v44.4c0,3-1.5,3.6-3.6,1.8l0,0L35,61.9H24.5
+                       c-1.8,0-3.3-1.5-3.3-3.3l0,0V45.4c0-1.8,1.5-3.3,3.3-3.3l0,0H35L50.3,28.3z M73.4,28.9C86,41.8,86,62.5,73.4,75.4l0,0l-4.8-4.8
+                       c10.2-10.2,10.2-26.7,0-36.9l0,0L73.4,28.9z M63.8,38.5c3.6,3.6,5.7,8.4,5.7,13.8s-2.1,10.2-5.7,13.8l0,0L59,61.3
+                       c2.4-2.4,3.6-5.4,3.6-9c0-3.6-1.2-6.6-3.6-9l0,0L63.8,38.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_wallpaper.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_icon_wallpaper.svg
new file mode 100644 (file)
index 0000000..aa75360
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/05_wallpaper copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_05_x5F_wallpaper-copy">
+       <g id="Homescreen_x2F_wallpaper" transform="translate(8.000000, 8.000000)">
+               <g id="Aod_x2F_style_x28_theme_x29_">
+                       <path id="style_x28_theme_x29_" d="M69,75c0,0.7-0.6,1.3-1.3,1.3H36.3c-0.7,0-1.3-0.6-1.3-1.3v-7.6c0-1.2,0.8-1.9,0.8-2l7.4-6.9
+                               c0.5-0.5,1.3-0.5,1.8,0l3.6,3.5c0.5,0.5,1.3,0.5,1.7,0l9.1-8.9c0.5-0.5,1.2-0.5,1.7,0l7.2,7.4c0,0,0.7,0.6,0.7,1.5V75z
+                                M44.7,34.6c2.6,0,4.7,2.1,4.7,4.7c0,2.6-2.1,4.7-4.7,4.7c-2.6,0-4.7-2.1-4.7-4.7C40,36.7,42.1,34.6,44.7,34.6L44.7,34.6z
+                                M70,21.9H34c-2.8,0-5,2.2-5,5v50.2c0,2.8,2.2,5,5,5h36c2.8,0,5-2.3,5-5V26.9C75,24.1,72.8,21.9,70,21.9L70,21.9z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_subheader_dot.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/6_Lists/tw_list_subheader_dot.svg
new file mode 100644 (file)
index 0000000..1437ed0
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 4.5 1.5" style="enable-background:new 0 0 4.5 1.5;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<circle class="st0" cx="0.8" cy="0.8" r="0.8"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/9_Progress/tw_ic_progress_download_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/9_Progress/tw_ic_progress_download_mtrl.svg
new file mode 100644 (file)
index 0000000..73461dc
--- /dev/null
@@ -0,0 +1 @@
+<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m8.54775 1v8.80025h-5.54775l8.876 8.80125 8.87625-8.80125h-5.548v-8.80025zm-5.54775 22h17.75v-2.2h-17.75z" fill="#fff" fill-rule="evenodd"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/9_Progress/tw_ic_progress_refresh_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/9_Progress/tw_ic_progress_refresh_mtrl.svg
new file mode 100644 (file)
index 0000000..d6a4896
--- /dev/null
@@ -0,0 +1 @@
+<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m11.665659 2c-4.41911626 0-8.18833218 2.76607387-9.665659 6.65535226l2.33639931 1.35379614c.97768058-3.10798561 3.88911043-5.36285907 7.32925969-5.36285907 4.24159 0 7.6801955 3.42783858 7.6801955 7.65672027 0 4.2283686-3.4386055 7.6567202-7.6801955 7.6567202-1.84652991 0-3.54049016-.6502223-4.86524735-1.7326436l2.7297871-3.255985-7.41364893.6840801.68206084 7.3448187 2.26873352-2.7060534c1.7770631 1.4333106 4.13610343 2.3118161 6.59831482 2.3118161 5.7075963 0 10.334341-4.6126026 10.334341-10.3027531 0-5.690407-4.6267447-10.3030096-10.334341-10.3030096" fill="#fff" fill-rule="evenodd"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_001.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_001.jpg
new file mode 100644 (file)
index 0000000..011f4c9
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_001.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_002.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_002.jpg
new file mode 100644 (file)
index 0000000..531b7a3
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_002.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_003.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_003.jpg
new file mode 100644 (file)
index 0000000..4ce60ca
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_003.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_004.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_004.jpg
new file mode 100644 (file)
index 0000000..80513f6
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_004.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_005.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_005.jpg
new file mode 100644 (file)
index 0000000..c636bb0
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_005.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_006.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_006.jpg
new file mode 100644 (file)
index 0000000..67e6caa
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_006.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_007.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_007.jpg
new file mode 100644 (file)
index 0000000..c7fa86f
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_007.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_008.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_008.jpg
new file mode 100644 (file)
index 0000000..ea8f184
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_008.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_009.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_009.jpg
new file mode 100644 (file)
index 0000000..6f215e2
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_009.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_010.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_010.jpg
new file mode 100644 (file)
index 0000000..55c89cc
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_010.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_011.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_011.jpg
new file mode 100644 (file)
index 0000000..04b6fc0
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_011.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_012.jpg b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_012.jpg
new file mode 100644 (file)
index 0000000..85433dc
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/Thumbnail/thumbnail_012.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/images/controls/00_button_pause.png b/d2d_app/client/lib/tau/mobile/theme/changeable/images/controls/00_button_pause.png
new file mode 100644 (file)
index 0000000..e32a1fb
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/changeable/images/controls/00_button_pause.png differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/tau.css b/d2d_app/client/lib/tau/mobile/theme/changeable/tau.css
new file mode 100644 (file)
index 0000000..10a50fa
--- /dev/null
@@ -0,0 +1,11672 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/********************************
+ * Tizen Changeable Less Header *
+ *******************************/
+/****************************
+ * Tizen nine-patch images  *
+ ****************************/
+/****************************
+ * Tizen Common Less Header *
+ ****************************/
+:root {
+  --text-secondary-color: #909090;
+  --primary-color: #0381fe;
+  --control-background: #e6e6e6;
+  --textual-background: #FCFCFC;
+  --color-white: #fafafa;
+  --surface: #FCFCFC;
+  --accent-badge: #F56A0D;
+  --on-background: #858585;
+  --border-surface: #e6e6e6;
+  --button-background: rgba(0, 0, 0, 0);
+  --button-background-flat: transparent;
+  --button-text-font-size: 17px;
+  --button-contained-text-font-size: 17px;
+  --button-contained-list-text-font-size: 15px;
+  --btn-add-color: #00b149;
+  --btn-delete-color: #ff3d00;
+  --checkbox-image-checked: rgba(0, 0, 0, 0.3);
+  --slider-bg-color: rgba(3, 129, 254, 0.3);
+  --slider-bg-disabled-color: rgba(102, 102, 102, 0.15);
+  --slider-value-color: #0381fe;
+  --slider-handler-color: #0381fe;
+  --btn-toast-background: rgba(71, 71, 71, 0.9);
+  --btn-toast-text-color: #0381fe;
+  --toast-background: rgba(102, 102, 102, 0.95);
+  --toast-text-color: #FFFFFF;
+  --progress-circle-second-color: #06b485;
+  --on-off-switch-off-button-border: #8f8f8f;
+  --on-off-switch-on-disabled-track-background: rgba(143, 143, 143, 0.4);
+  --on-off-switch-off-track-background: transparent;
+  --on-off-switch-off-disabled-track-border: rgba(143, 143, 143, 0.4);
+}
+body,
+body.ui-theme-light,
+body.ui-theme-default {
+  --primary-color: #0381fe;
+  --primary-dark-color: #0072de;
+  --primary-color-20p: rgba(3, 129, 254, 0.2);
+  --primary-color-30p: rgba(3, 129, 254, 0.3);
+  --control-active-color: #3e91ff;
+  --control-active-disabled-color: rgba(62, 145, 255, 0.4);
+  --control-inactive-color: #8f8f8f;
+  --text-color: #252525;
+  --text-secondary-color: #909090;
+  --color-white: #fafafa;
+  --color-black: #000000;
+  --ripple-color: rgba(0, 0, 0, 0.1);
+  --overlay: rgba(0, 0, 0, 0.45);
+  --background-color: #F2F2F2;
+  --background-area-color: #fcfcfc;
+  --expandable-text-color: #666666;
+  --popup-background: #fcfcfc;
+  --popup-text: #505050;
+  --popup-text-secondary-color: #8f8f8f;
+  --popup-footer-divider-color: #e6e6e6;
+  --popup-scroll-divider-color: #d4d4d4;
+  --icon-color: #3b3b3b;
+  --appbar-main-text-color: #252525;
+  --appbar-subtitle-color: #636363;
+  --appbar-miltiline-title-color: #252525;
+  --tab-text-color: #858585;
+  --tab-text-color-dim: rgba(133, 133, 133, 0.4);
+  --bottom-bar-color: #F2F2F2;
+  --button-icon-color: #252525;
+  --bottom-button-icon-color: #454545;
+  --sub-tab-bg-color: #F2F2F2;
+  --sub-tab-text-color: #858585;
+  --sub-tab-active-text-color: #252525;
+  --sub-tab-border-color: rgba(113, 113, 113, 0.8);
+  --progress-bar-color: #0381fe;
+  --progress-bar-bg-color: rgba(3, 129, 254, 0.3);
+  --button-text-color-disabled: rgba(3, 129, 254, 0.4);
+  --checkbox-favorite-color: #f5ab00;
+  --ripple-button-flat-color: rgba(0, 0, 0, 0.1);
+  --slider-handler-disabled-color: #d2d2d2;
+  --slider-scale-dot: #9c9c9c;
+  --slider-level-bar-bg-color: rgba(151, 151, 151, 0.3);
+  --button-background-contained: rgba(0, 0, 0, 0.06);
+  --on-off-switch-off-disabled-button-border: #d0d0d0;
+  --on-off-switch-on-disabled-button-border: #d0d0d0;
+  --on-off-switch-on-disabled-button-background: #fafafa;
+  --on-off-switch-divider-color: #c4c4c4;
+  --master-on-off-off-color: #fafafa;
+  --master-on-off-on-color: rgba(62, 145, 255, 0.8);
+  --chip-background-color: #e5e5e5;
+  --chip-border-color: rgba(37, 37, 37, 0.2);
+  --chip-btn-background-color: #f2f2f2;
+  --chip-btn-border-color: rgba(37, 37, 37, 0.3);
+  --text-input-invalid-color: #b00020;
+  --dropdown-menu-options-border: 0.25px solid #cccccc;
+  --dropdown-menu-options-background: #fcfcfc;
+  --dropdown-menu-options-color: #000000;
+  --dropdown-menu-options-color-dim: rgba(0, 0, 0, 0.4);
+  --content-area-line-color: #d6d6d6;
+  --list-item-selected-color: rgba(3, 129, 254, 0.08);
+  --divider-color: #e6e6e6;
+  --divider-opacity: 100%;
+  --subheader-divider-color: #979797;
+  --grid-border-color: rgba(0, 0, 0, 0.12);
+  --grid-label-color: #252525;
+  --grid-label-secondary-color: #666666;
+  --expander-color: #747474;
+  --reorder-color: #747474;
+  --holder-reoder-background: #fcfcfc;
+  --holder-reoder-border: #0072de;
+  --spin-item-opacity: 0.1;
+  --grid-selection-color: rgba(0, 0, 0, 0.3);
+  --calendar-weekend-day-color: #c95151;
+  --calendar-weekend-color: #d77e7e;
+  --calendar-text-color: #454545;
+  --calendar-arrow-color: #8e8e8e;
+  --calendar-select-text-color: #fafafa;
+  --date-picker-header-text-color: #454545;
+  --text-input-disabled: #bebebe;
+  --text-input-label-inactive: #8c8c8c;
+  --text-input-underline-inactive: #8c8c8c;
+  --text-input-underline-active: var(--primary-color);
+  --icon-control-color: var(--color-white);
+  --progress-background-color: #cccccc;
+  --on-off-switch-track-off: #8f8f8f;
+  --more-options-background-color: var(--popup-background);
+  --more-options-background-stroke: #cccccc;
+  --more-options-pressed-color: rgba(0, 0, 0, 0.1);
+  --button-text-contained-dim-color: rgba(37, 37, 37, 0.4);
+}
+body.ui-theme-dark {
+  --primary-color: #0381fe;
+  --primary-dark-color: #3e91ff;
+  --primary-color-20p: rgba(3, 129, 254, 0.2);
+  --primary-color-30p: rgba(3, 129, 254, 0.3);
+  --control-active-color: #3e91ff;
+  --control-active-disabled-color: rgba(62, 145, 255, 0.4);
+  --control-inactive-color: #8f8f8f;
+  --text-color: #fafafa;
+  --text-secondary-color: #999999;
+  --color-white: #fafafa;
+  --color-black: #080808;
+  --ripple-color: rgba(255, 255, 255, 0.2);
+  --overlay: rgba(0, 0, 0, 0.65);
+  --background-color: #080808;
+  --background-area-color: #252525;
+  --expandable-text-color: #9c9c9c;
+  --popup-background: #252525;
+  --popup-text: #e5e5e5;
+  --popup-text-secondary-color: #999999;
+  --popup-footer-divider-color: rgba(230, 230, 230, 0.2);
+  --popup-scroll-divider-color: rgba(212, 212, 212, 0.18);
+  --icon-color: #d9d9d9;
+  --appbar-main-text-color: #fafafa;
+  --appbar-subtitle-color: #9c9c9c;
+  --appbar-miltiline-title-color: #e5e5e5;
+  --tab-text-color: #a8a9a9;
+  --tab-text-color-dim: rgba(168, 169, 169, 0.4);
+  --bottom-bar-color: #010101;
+  --button-icon-color: #fafafa;
+  --bottom-button-icon-color: #cccccc;
+  --sub-tab-bg-color: #010101;
+  --sub-tab-text-color: #999999;
+  --sub-tab-active-text-color: #FFFFFF;
+  --sub-tab-border-color: rgba(255, 255, 255, 0.6);
+  --progress-bar-color: #0381fe;
+  --progress-bar-bg-color: rgba(3, 129, 254, 0.3);
+  --button-text-color-disabled: rgba(3, 129, 254, 0.4);
+  --checkbox-favorite-color: #f5ab00;
+  --ripple-button-flat-color: rgba(255, 255, 255, 0.2);
+  --slider-handler-disabled-color: #545454;
+  --slider-scale-dot: #808080;
+  --slider-level-bar-bg-color: rgba(151, 151, 151, 0.3);
+  --button-background-contained: rgba(250, 250, 250, 0.17);
+  --on-off-switch-off-disabled-button-border: #3b3b3b;
+  --on-off-switch-on-disabled-button-border: #3b3b3b;
+  --on-off-switch-on-disabled-button-background: #858585;
+  --on-off-switch-divider-color: rgba(212, 212, 212, 0.15);
+  --master-on-off-off-color: rgba(250, 250, 250, 0.17);
+  --master-on-off-on-color: rgba(62, 145, 255, 0.4);
+  --chip-background-color: #252525;
+  --chip-border-color: rgba(250, 250, 250, 0.2);
+  --chip-btn-background-color: #f2f2f2;
+  --chip-btn-border-color: rgba(37, 37, 37, 0.3);
+  --text-input-invalid-color: #ff6666;
+  --dropdown-menu-options-border: 0.75px solid #525252;
+  --dropdown-menu-options-background: #3d3d3d;
+  --dropdown-menu-options-color: #fafafa;
+  --dropdown-menu-options-color-dim: rgba(250, 250, 250, 0.4);
+  --content-area-line-color: #d6d6d6;
+  --list-item-selected-color: rgba(250, 250, 250, 0.1);
+  --divider-color: #d4d4d4;
+  --divider-opacity: 15%;
+  --subheader-divider-color: #fafafa;
+  --grid-border-color: rgba(250, 250, 250, 0.25);
+  --grid-label-color: #fafafa;
+  --grid-label-secondary-color: #999999;
+  --expander-color: #808080;
+  --reorder-color: #808080;
+  --holder-reoder-background: #252525;
+  --holder-reoder-border: #3e91ff;
+  --spin-item-opacity: 0.2;
+  --grid-selection-color: rgba(0, 0, 0, 0.3);
+  --calendar-weekend-day-color: #c95151;
+  --calendar-weekend-color: #993d3d;
+  --calendar-text-color: #cccccc;
+  --calendar-arrow-color: #737373;
+  --calendar-select-text-color: #000000;
+  --date-picker-header-text-color: #cccccc;
+  --surface: #3d3d3d;
+  --text-input-disabled: #454545;
+  --text-input-label-inactive: #737373;
+  --text-input-underline-inactive: #737373;
+  --text-input-underline-active: var(--primary-color);
+  --icon-control-color: var(--surface);
+  --progress-background-color: #252525;
+  --more-options-background-color: #3d3d3d;
+  --more-options-background-stroke: #525252;
+  --more-options-pressed-color: rgba(255, 255, 255, 0.2);
+  --button-text-contained-dim-color: rgba(250, 250, 250, 0.4);
+}
+@font-face {
+  font-family: Roboto-Light;
+  src: url(fonts/Roboto-Light.ttf);
+}
+@font-face {
+  font-family: Roboto-Regular;
+  src: url(fonts/Roboto-Regular.ttf);
+}
+@font-face {
+  font-family: Roboto-Medium;
+  src: url(fonts/Roboto-Medium.ttf);
+}
+.tau-info-theme {
+  position: absolute;
+  top: -999px;
+  left: -999px;
+}
+.ui-appbar,
+header {
+  position: relative;
+  width: 100%;
+  box-sizing: border-box;
+  background: var(--background-color);
+  overflow: hidden;
+  border: none;
+  height: 56px;
+  margin-bottom: 12px;
+  font-family: Roboto-Regular;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-appbar:not(.ui-appbar-dragging),
+header:not(.ui-appbar-dragging) {
+  transition: height 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
+}
+.ui-appbar:not(.ui-appbar-dragging) .ui-appbar-controls-container,
+header:not(.ui-appbar-dragging) .ui-appbar-controls-container,
+.ui-appbar:not(.ui-appbar-dragging) .ui-appbar-expanded-title-container,
+header:not(.ui-appbar-dragging) .ui-appbar-expanded-title-container {
+  padding-top: 0px;
+  transition: opacity 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
+}
+.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast,
+header:not(.ui-appbar-dragging).ui-appbar-animation-fast {
+  transition-duration: 10ms;
+}
+.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-controls-container,
+header:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-controls-container,
+.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-expanded-title-container,
+header:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-expanded-title-container {
+  transition-duration: 10ms;
+}
+.ui-appbar .ui-btn,
+header .ui-btn {
+  padding: 0;
+}
+.ui-appbar .ui-btn.ui-btn-flat,
+header .ui-btn.ui-btn-flat {
+  font-size: 18px;
+  font-family: Roboto-Medium;
+  color: var(--appbar-main-text-color);
+}
+.ui-appbar .ui-btn.ui-btn-flat::before,
+header .ui-btn.ui-btn-flat::before {
+  height: 48px;
+  border-radius: 24px;
+}
+.ui-appbar .ui-btn.ui-btn-icon,
+header .ui-btn.ui-btn-icon {
+  background-color: transparent;
+  position: relative;
+  width: 24px;
+  height: 24px;
+  min-height: 24px;
+  margin-right: 8px;
+}
+.ui-appbar .ui-btn.ui-btn-icon::before,
+header .ui-btn.ui-btn-icon::before {
+  width: 48px;
+  height: 48px;
+}
+.ui-appbar .ui-btn.ui-btn-icon::after,
+header .ui-btn.ui-btn-icon::after {
+  width: 24px;
+  height: 24px;
+}
+.ui-appbar .ui-btn.ui-btn-icon-back::after,
+header .ui-btn.ui-btn-icon-back::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_back_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_back_mtrl.svg");
+}
+.ui-appbar .ui-btn.ui-btn-icon-more::after,
+header .ui-btn.ui-btn-icon-more::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_more_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_more_mtrl.svg");
+}
+.ui-appbar .ui-btn.ui-btn-icon-search::after,
+header .ui-btn.ui-btn-icon-search::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_search_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_search_mtrl.svg");
+}
+.ui-appbar .ui-btn.ui-btn-icon-add::after,
+header .ui-btn.ui-btn-icon-add::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_add_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_add_mtrl.svg");
+}
+.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat,
+header .ui-btn.ui-btn-icon.ui-btn-flat {
+  min-height: 24px;
+  display: block;
+  margin-top: auto;
+  margin-bottom: auto;
+}
+.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat::after,
+header .ui-btn.ui-btn-icon.ui-btn-flat::after {
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  width: 24px;
+  height: 24px;
+}
+.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat::before,
+header .ui-btn.ui-btn-icon.ui-btn-flat::before {
+  background-color: transparent;
+  width: 48px;
+  height: 48px;
+}
+.ui-appbar .ui-btn.ui-btn-icon.ui-btn-icon-back,
+header .ui-btn.ui-btn-icon.ui-btn-icon-back {
+  margin-left: 20px;
+  margin-right: 12px;
+}
+.ui-appbar .ui-appbar-controls-container,
+header .ui-appbar-controls-container {
+  -webkit-flex: 0 0 56px;
+      -ms-flex: 0 0 56px;
+          flex: 0 0 56px;
+  width: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-align-items: flex-start;
+      -ms-flex-align: start;
+          align-items: flex-start;
+  position: absolute;
+  bottom: 0;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-left-icons-container,
+header .ui-appbar-controls-container .ui-appbar-left-icons-container {
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  min-width: 24px;
+  margin-top: auto;
+  margin-bottom: auto;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container,
+header .ui-appbar-controls-container .ui-appbar-title-container {
+  height: 56px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  margin: auto 0;
+  overflow: hidden;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: flex-start;
+      -ms-flex-align: start;
+          align-items: flex-start;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container .ui-appbar-title,
+header .ui-appbar-controls-container .ui-appbar-title-container .ui-appbar-title {
+  max-width: 100%;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  font-size: 19px;
+  color: var(--appbar-main-text-color);
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-subtitle .ui-appbar-subtitle,
+header .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-subtitle .ui-appbar-subtitle {
+  font-size: 13px;
+  color: var(--appbar-subtitle-color);
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-multiline .ui-appbar-title,
+header .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-multiline .ui-appbar-title {
+  font-size: 17px;
+  color: var(--appbar-miltiline-title-color);
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container,
+header .ui-appbar-controls-container .ui-appbar-action-buttons-container {
+  height: 100%;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  margin-left: auto;
+  min-width: 24px;
+  margin-top: auto;
+  margin-bottom: auto;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-justify-content: flex-end;
+      -ms-flex-pack: end;
+          justify-content: flex-end;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn,
+header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn {
+  margin-right: 12px;
+  margin-left: 12px;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn:last-child,
+header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn:last-child {
+  margin-right: 20px;
+  margin-left: 15px;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn + .ui-btn-icon,
+header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn + .ui-btn-icon {
+  margin-left: 3px;
+}
+.ui-appbar .ui-appbar-expanded-title-container,
+header .ui-appbar-expanded-title-container {
+  -webkit-flex: 1 1 auto;
+      -ms-flex: 1 1 auto;
+          flex: 1 1 auto;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  opacity: 0;
+  height: 0;
+}
+.ui-appbar .ui-appbar-expanded-title-container .ui-appbar-title,
+header .ui-appbar-expanded-title-container .ui-appbar-title {
+  line-height: 54px;
+  font-size: 38px;
+  font-family: Roboto-Light;
+  margin-left: 24px;
+  margin-right: 24px;
+  text-align: center;
+}
+.ui-appbar .ui-appbar-expanded-title-container .ui-appbar-subtitle,
+header .ui-appbar-expanded-title-container .ui-appbar-subtitle {
+  line-height: 20px;
+  font-size: 15px;
+  text-align: center;
+}
+.ui-appbar h1,
+header h1,
+.ui-appbar h2,
+header h2,
+.ui-appbar h3,
+header h3,
+.ui-appbar h4,
+header h4,
+.ui-appbar h5,
+header h5,
+.ui-appbar h6,
+header h6 {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  outline: 0;
+  font-weight: inherit;
+  font-style: inherit;
+  font-size: 100%;
+  font-family: inherit;
+  vertical-align: baseline;
+}
+.ui-appbar.ui-appbar-expanded,
+header.ui-appbar-expanded {
+  height: calc(39.67% -  12px);
+}
+.ui-appbar.ui-appbar-expanded .ui-appbar-expanded-title-container,
+header.ui-appbar-expanded .ui-appbar-expanded-title-container {
+  opacity: 1;
+}
+.ui-appbar.ui-appbar-dragging .ui-appbar-expanded-title-container,
+header.ui-appbar-dragging .ui-appbar-expanded-title-container {
+  overflow: hidden;
+}
+.ui-appbar .ui-label-select-all,
+header .ui-label-select-all {
+  font-family: Roboto-Regular;
+  font-size: 12px;
+  width: 32px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  padding-top: 10px;
+  line-height: 14px;
+  margin-left: 18px;
+  margin-right: 18px;
+}
+.ui-appbar .ui-label-select-all input[type="checkbox"].ui-checkbox,
+header .ui-label-select-all input[type="checkbox"].ui-checkbox {
+  margin: 0 0 -3px 0;
+}
+.ui-appbar .ui-appbar-container,
+header .ui-appbar-container {
+  height: 70px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-order: 10;
+      -ms-flex-order: 10;
+          order: 10;
+  background-color: var(--background-area-color);
+  border-radius: 26px;
+  overflow: hidden;
+  box-sizing: border-box;
+  box-shadow: 0 0 0 0.25px var(--content-area-line-color) inset;
+}
+.ui-appbar .ui-appbar-container > :first-child,
+header .ui-appbar-container > :first-child {
+  margin-left: 24px;
+}
+.ui-appbar .ui-appbar-container .ui-title,
+header .ui-appbar-container .ui-title {
+  font-size: 18px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-appbar .ui-appbar-container .ui-icon,
+header .ui-appbar-container .ui-icon {
+  width: 21px;
+  height: 21px;
+  overflow: hidden;
+  margin-right: 22px;
+}
+.ui-appbar .ui-appbar-container .ui-icon img,
+header .ui-appbar-container .ui-icon img {
+  width: 100%;
+}
+.ui-appbar .ui-appbar-container .ui-btn.ui-btn-icon.ui-btn-icon-only,
+header .ui-appbar-container .ui-btn.ui-btn-icon.ui-btn-icon-only {
+  height: 48px;
+  max-width: 48px;
+}
+@media all and (min-height: 580px) and (orientation: landscape) {
+  .ui-appbar.ui-appbar-expanded {
+    height: calc(30% -  12px);
+  }
+}
+@media all and (min-height: 960px) {
+  .ui-appbar.ui-appbar-expanded {
+    height: calc(25% -  12px);
+  }
+}
+.ui-card {
+  border-radius: 26px;
+  overflow: hidden;
+  box-sizing: border-box;
+  margin-bottom: 10px;
+}
+.ui-card.ui-card-service {
+  background-color: var(--background-area-color);
+  border-radius: 26px;
+  overflow: hidden;
+  box-sizing: border-box;
+  box-shadow: 0 0 0 0.25px var(--content-area-line-color) inset;
+}
+.ui-card.ui-card-service *::-webkit-scrollbar {
+  display: none;
+}
+.ui-card.ui-card-service .ui-subheader-text {
+  color: #7b7b7b;
+}
+.ui-card.ui-card-service .ui-content-subheader {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-card.ui-card-service .ui-content-subheader::after {
+  content: "";
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  width: calc(100% - 20px);
+  border-bottom: 1px solid var(--subheader-divider-color);
+  height: 0;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  margin-right: 20px;
+  margin-left: 10px;
+}
+.ui-card.ui-card-service .ui-content-thumbnail {
+  width: 100%;
+}
+.ui-card.ui-card-service .ui-content .ui-title.ui-title-medium {
+  font-size: 18px;
+  font-family: Roboto-Medium;
+}
+.ui-card.ui-card-service .ui-content.ui-scrollview-clip {
+  border-radius: 0;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-icon {
+  width: 58px;
+  height: 58px;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-icon img {
+  width: 58px;
+  height: 58px;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-text {
+  padding: 25px 0 23px;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-text-title {
+  font-size: 16px;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-text-sub {
+  font-size: 12px;
+}
+.ui-card .ui-header {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  height: 46px;
+  padding: 0 20px;
+}
+.ui-card .ui-header .ui-title {
+  margin-top: 24px;
+  margin-bottom: 3px;
+  font-size: 15px;
+  color: var(--text-color);
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  display: inline-block;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-card .ui-header .ui-icon {
+  margin-right: 10px;
+  margin-top: 20px;
+  width: 26px;
+  height: 26px;
+  -webkit-order: 0;
+      -ms-flex-order: 0;
+          order: 0;
+  display: inline-block;
+}
+.ui-card .ui-header .ui-icon img {
+  width: 100%;
+  height: 100%;
+}
+.ui-card .ui-header .ui-controls {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  margin-top: 20px;
+  height: 26px;
+}
+.ui-card .ui-header .ui-controls .ui-btn {
+  width: 26px;
+  height: 26px;
+  background-color: transparent;
+  min-height: 26px;
+  padding: 0;
+  display: inline-block;
+}
+.ui-card .ui-header .ui-controls .ui-btn ~ .ui-btn {
+  margin-left: 14px;
+}
+.ui-card .ui-header .ui-controls .ui-btn::before {
+  height: 26px;
+}
+.ui-card .ui-header .ui-controls .ui-btn::after {
+  background-color: var(--background-area-color);
+  height: 26px;
+  width: 26px;
+}
+.ui-card .ui-content,
+.ui-card .ui-content.ui-scrollview-clip {
+  padding: 10px 20px;
+}
+.ui-card .ui-content.ui-tabs,
+.ui-card .ui-content.ui-scrollview-clip.ui-tabs {
+  padding: 0;
+}
+.ui-card .ui-content .ui-section-changer .ui-content,
+.ui-card .ui-content.ui-scrollview-clip .ui-section-changer .ui-content {
+  padding: 0;
+}
+.ui-card .ui-content .ui-title,
+.ui-card .ui-content.ui-scrollview-clip .ui-title {
+  font-size: 16px;
+}
+.ui-card .ui-content .ui-description,
+.ui-card .ui-content.ui-scrollview-clip .ui-description {
+  font-size: 14px;
+}
+.ui-card .ui-content video,
+.ui-card .ui-content.ui-scrollview-clip video {
+  border-radius: 26px;
+}
+.ui-card .ui-content .ui-btn,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn {
+  width: 86px;
+  padding: 0;
+}
+.ui-card .ui-content .ui-btn .ui-btn-content,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content {
+  width: 86px;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-card .ui-content .ui-btn .ui-btn-content img,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content img {
+  border-radius: 15px;
+  width: 80px;
+  height: 80px;
+  margin-bottom: 8px;
+}
+.ui-card .ui-content .ui-btn .ui-btn-content .ui-title,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content .ui-title {
+  font-size: 14px;
+  color: var(--text-color);
+  line-height: 16px;
+}
+.ui-card .ui-content .ui-btn .ui-btn-content .ui-subtitle,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content .ui-subtitle {
+  font-size: 12px;
+  color: var(--text-secondary-color);
+  line-height: 14px;
+}
+.ui-card .ui-container-item img {
+  border-radius: 16px;
+  width: 188px;
+  height: 126px;
+  margin-bottom: 17px;
+}
+.ui-card .ui-container-item .ui-title {
+  font-family: Roboto-Medium;
+  color: var(--text-color);
+  font-size: 16px;
+  line-height: 19px;
+  text-align: left;
+  white-space: normal;
+  margin-bottom: 6px;
+}
+.ui-card .ui-container-item .ui-subtitle {
+  font-family: Roboto-Regular;
+  color: var(--text-secondary-color);
+  font-size: 14px;
+  line-height: 16px;
+  text-align: left;
+  white-space: normal;
+}
+.ui-card .ui-footer {
+  height: 63px;
+  -webkit-justify-content: flex-end;
+      -ms-flex-pack: end;
+          justify-content: flex-end;
+  padding: 0 20px;
+}
+.ui-card .ui-footer .ui-btn {
+  display: inline-block;
+  width: auto;
+  height: 43px;
+  color: var(--color-white);
+  font-size: 14px;
+  background-color: var(--primary-dark-color);
+}
+.ui-card .ui-sub-tab {
+  background-color: transparent;
+}
+.ui-card.ui-card-ads {
+  background-color: var(--background-area-color);
+  min-height: 200px;
+}
+.ui-card.ui-card-ads .ui-content {
+  padding: 0;
+  border-radius: 0;
+}
+.ui-card.ui-card-ads .ui-content .ui-scrollview-view {
+  overflow: hidden;
+}
+.ui-card.ui-card-ads .ui-content video,
+.ui-card.ui-card-ads .ui-content img {
+  border-radius: 0;
+  width: 100%;
+}
+.ui-card.ui-card-ads .ui-content .ui-title {
+  font-family: Roboto-Medium;
+  color: var(--text-color);
+  font-size: 16px;
+  white-space: normal;
+  margin: 0 20px;
+}
+.ui-card.ui-card-ads .ui-content .ui-title:last-child {
+  margin-top: 15px;
+}
+.ui-card.ui-card-ads .ui-content .ui-subtitle {
+  font-family: Roboto-Regular;
+  color: var(--text-secondary-color);
+  font-size: 14px;
+  white-space: normal;
+  margin: 0 20px;
+}
+.ui-card.ui-card-ads .ui-content .ui-banner {
+  position: relative;
+  width: 100%;
+  height: 150px;
+  overflow: hidden;
+}
+.ui-card.ui-card-ads .ui-content .ui-banner img {
+  width: 100%;
+  position: absolute;
+}
+.ui-card.ui-card-ads .ui-footer .ui-title {
+  font-family: Roboto-Medium;
+  color: var(--text-color);
+  font-size: 16px;
+  white-space: normal;
+  margin: 0 20px 0 0;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: left;
+}
+.LESSui-footer {
+  box-sizing: border-box;
+  padding: 12px 24px;
+  text-align: center;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+}
+.LESSui-footer .ui-btn:not(.ui-btn-contained) {
+  height: 52px;
+  line-height: 52px;
+  margin: 0 auto;
+  max-width: 248px;
+}
+.LESSui-footer .ui-btn.ui-btn-contained:not(.ui-btn-inline) {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained) {
+  background-color: var(--button-background);
+}
+.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-btn-active::before {
+  background-color: var(--ripple-color);
+}
+.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-state-disabled {
+  background-color: var(--button-background);
+}
+.LESSui-footer .ui-btn ~ .ui-btn {
+  margin-left: 16px;
+}
+.LESSui-footer .ui-btn.ui-btn-contained ~ .ui-btn.ui-btn-contained {
+  margin-left: 8px;
+}
+.LESSui-footer.ui-grid-col-1 .ui-btn.ui-inline,
+.LESSui-footer.ui-grid-col-2 .ui-btn.ui-inline,
+.LESSui-footer.ui-grid-col-3 .ui-btn.ui-inline {
+  display: block;
+  width: 100%;
+}
+.LESSui-footer.ui-bottom-button {
+  height: 56px;
+  padding-left: 24px;
+  padding-right: 24px;
+}
+.ui-footer {
+  width: 100%;
+  box-sizing: border-box;
+  padding: 12px 24px;
+  text-align: center;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+}
+.ui-footer .ui-btn:not(.ui-btn-contained) {
+  height: 52px;
+  line-height: 52px;
+  margin: 0 auto;
+  max-width: 248px;
+}
+.ui-footer .ui-btn.ui-btn-contained:not(.ui-btn-inline) {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained) {
+  background-color: var(--button-background);
+}
+.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-btn-active::before {
+  background-color: var(--ripple-color);
+}
+.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-state-disabled {
+  background-color: var(--button-background);
+}
+.ui-footer .ui-btn ~ .ui-btn {
+  margin-left: 16px;
+}
+.ui-footer .ui-btn.ui-btn-contained ~ .ui-btn.ui-btn-contained {
+  margin-left: 8px;
+}
+.ui-footer.ui-grid-col-1 .ui-btn.ui-inline,
+.ui-footer.ui-grid-col-2 .ui-btn.ui-inline,
+.ui-footer.ui-grid-col-3 .ui-btn.ui-inline {
+  display: block;
+  width: 100%;
+}
+.ui-footer.ui-bottom-button {
+  height: 56px;
+  padding-left: 24px;
+  padding-right: 24px;
+}
+.ui-page:not(.ui-page-flex) .ui-footer {
+  position: fixed;
+  bottom: 0;
+}
+.ui-page.ui-page-flex .ui-footer {
+  overflow: visible;
+}
+.ui-page-container,
+.ui-page-container body {
+  height: 100%;
+  font-size: 22px;
+}
+@media all and (max-width: 359px) {
+  .ui-page-container,
+  .ui-page-container body {
+    font-size: 19px;
+  }
+}
+.ui-page-container fieldset,
+.ui-page {
+  padding: 0;
+  margin: 0;
+}
+.ui-page-container a img,
+.ui-page-container fieldset {
+  border: 0;
+}
+.ui-page-container {
+  margin: 0;
+  overflow-x: hidden;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+[data-role=page],
+[data-role=dialog],
+.ui-page {
+  top: 0;
+  left: 0;
+  width: 100%;
+  position: absolute;
+  display: none;
+  border: 0;
+}
+[data-role=page].ui-page-build,
+[data-role=dialog].ui-page-build,
+.ui-page.ui-page-build {
+  display: block;
+  visibility: hidden;
+}
+[data-role=page].ui-pre-in,
+[data-role=dialog].ui-pre-in,
+.ui-page.ui-pre-in {
+  z-index: 100;
+}
+[data-role=page].ui-pre-in,
+[data-role=dialog].ui-pre-in,
+.ui-page.ui-pre-in,
+[data-role=page].ui-page-active,
+[data-role=dialog].ui-page-active,
+.ui-page.ui-page-active {
+  display: block;
+  overflow: hidden;
+}
+[data-role=page].ui-pre-in.ui-page-flex,
+[data-role=dialog].ui-pre-in.ui-page-flex,
+.ui-page.ui-pre-in.ui-page-flex,
+[data-role=page].ui-page-active.ui-page-flex,
+[data-role=dialog].ui-page-active.ui-page-flex,
+.ui-page.ui-page-active.ui-page-flex {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-align-content: stretch;
+      -ms-flex-line-pack: stretch;
+          align-content: stretch;
+}
+[data-role=page].ui-pre-in.ui-page-flex .ui-header,
+[data-role=dialog].ui-pre-in.ui-page-flex .ui-header,
+.ui-page.ui-pre-in.ui-page-flex .ui-header,
+[data-role=page].ui-page-active.ui-page-flex .ui-header,
+[data-role=dialog].ui-page-active.ui-page-flex .ui-header,
+.ui-page.ui-page-active.ui-page-flex .ui-header {
+  position: relative;
+}
+[data-role=page].ui-pre-in.ui-page-flex .ui-content,
+[data-role=dialog].ui-pre-in.ui-page-flex .ui-content,
+.ui-page.ui-pre-in.ui-page-flex .ui-content,
+[data-role=page].ui-page-active.ui-page-flex .ui-content,
+[data-role=dialog].ui-page-active.ui-page-flex .ui-content,
+.ui-page.ui-page-active.ui-page-flex .ui-content {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-page-container,
+.ui-page-container .ui-page {
+  color: var(--text-color);
+  background-image: none;
+  background-color: var(--background-color);
+}
+.ui-page-container.ui-page-light,
+.ui-page-container .ui-page.ui-page-light {
+  background-image: none;
+}
+.ui-page.ui-mobile-touch-overflow,
+.ui-mobile-touch-overflow.ui-native-fixed .ui-content {
+  overflow: auto;
+  height: 100%;
+  -webkit-overflow-scrolling: touch;
+}
+.ui-page.ui-mobile-touch-overflow,
+.ui-page.ui-mobile-touch-overflow * {
+  transform: rotateY(0);
+  -ms-transform: rotateY(0);
+  -moz-transform: rotateY(0);
+  -webkit-transform: rotateY(0);
+  -o-transform: rotateY(0);
+}
+.ui-page.ui-mobile-pre-transition {
+  display: block;
+}
+.ui-blocker {
+  width: 100%;
+  height: 100%;
+  z-index: 2147483647;
+}
+.ui-mobile-rendering > * {
+  visibility: hidden;
+}
+.ui-bar,
+.ui-body {
+  position: relative;
+  padding: .4em 15px;
+  overflow: hidden;
+  display: block;
+  clear: both;
+}
+.ui-bar {
+  font-size: 16px;
+  margin: 0;
+}
+.ui-bar h1,
+.ui-bar h2,
+.ui-bar h3,
+.ui-bar h4,
+.ui-bar h5,
+.ui-bar h6 {
+  margin: 0;
+  padding: 0;
+  font-size: 16px;
+  display: inline-block;
+}
+.ui-content {
+  border-width: 0;
+  overflow-y: visible;
+  overflow-x: hidden;
+  -webkit-flex-shrink: 1;
+      -ms-flex-negative: 1;
+          flex-shrink: 1;
+  border-radius: 26px;
+}
+.ui-content.ui-content-padding,
+.ui-content.ui-content-padding.ui-scrollview-clip {
+  padding-left: 12px;
+  padding-right: 12px;
+}
+.ui-content.ui-content-under-popup {
+  pointer-events: none;
+}
+.ui-content .ui-content-area {
+  background-color: var(--background-area-color);
+  border-radius: 26px;
+  overflow: hidden;
+  box-sizing: border-box;
+  box-shadow: 0 0 0 0.25px var(--content-area-line-color) inset;
+  margin: auto auto 16px auto;
+}
+@media (min-width: 673px) and (min-height: 411px) {
+  .ui-content .ui-content-area {
+    width: 90%;
+  }
+}
+@media (min-width: 960px) {
+  .ui-content .ui-content-area {
+    width: 75%;
+  }
+}
+.ui-content .ui-content-area-disabled-top-rounding {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  -webkit-mask-box-image-width: 0 26px 26px;
+          mask-border-width: 0 26px 26px;
+}
+.ui-content .ui-content-area ~ .ui-content-subheader {
+  margin-top: -16px;
+}
+.ui-content .ui-content-subheader {
+  color: var(--text-secondary-color);
+  font-family: Roboto-Medium;
+  font-size: 14px;
+  padding-bottom: 7px;
+  padding-top: 13px;
+  margin-left: 24px;
+  line-height: 16px;
+}
+body.ui-theme-dark .ui-content-area {
+  box-shadow: unset;
+}
+.ui-page-fullscreen .ui-content {
+  padding: 0;
+}
+.ui-mobile-touch-overflow.ui-native-fixed .ui-content {
+  padding-top: 2.5em;
+  padding-bottom: 3em;
+  top: 0;
+  bottom: 0;
+  height: auto;
+  position: absolute;
+}
+.ui-mobile-touch-overflow.ui-native-fullscreen .ui-content {
+  padding-top: 0;
+  padding-bottom: 0;
+}
+.ui-native-bars-hidden {
+  display: none;
+}
+.ui-screen-hidden {
+  display: none;
+}
+.ui-icon {
+  width: 18px;
+  height: 18px;
+}
+.ui-fullscreen img {
+  max-width: 100%;
+}
+.ui-nojs {
+  position: absolute;
+  left: -9999px;
+}
+.scrolling-scrollbar {
+  position: absolute;
+  pointer-events: none;
+}
+.scrolling-scrollbar .scrolling-scrollthumb {
+  background-color: #71cbd9;
+  position: absolute;
+}
+.scrolling-scrollbar.scrolling-direction-y {
+  right: 11px;
+  width: 10px;
+}
+.scrolling-scrollbar.scrolling-direction-y .scrolling-scrollthumb {
+  width: 10px;
+  min-height: 44px;
+  top: 0;
+  left: 50%;
+  margin-left: -5px;
+}
+.scrolling-scrollbar.scrolling-direction-x {
+  bottom: 11px;
+  height: 10px;
+}
+.scrolling-scrollbar.scrolling-direction-x .scrolling-scrollthumb {
+  height: 10px;
+  min-width: 37px;
+  left: 0;
+  top: 50%;
+  margin-top: -5px;
+}
+input[type="checkbox"].ui-checkbox:not(.ui-toggle-switch) {
+  position: relative;
+  height: 32px;
+  width: 32px;
+  box-sizing: border-box;
+  outline: none;
+  -webkit-appearance: none;
+  margin: 0 18px;
+}
+@-webkit-keyframes checkbox-in {
+  from {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+  to {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+}
+@keyframes checkbox-in {
+  from {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+  to {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+}
+@-webkit-keyframes checkbox-out {
+  from {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+  to {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+}
+@keyframes checkbox-out {
+  from {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+  to {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+}
+input[type="checkbox"].ui-checkbox::before {
+  content: "";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 32px;
+  height: 32px;
+  background-color: var(--ripple-color);
+  border-radius: 100%;
+  opacity: 0;
+}
+input[type="checkbox"].ui-checkbox::after {
+  content: "";
+  position: absolute;
+  bottom: 0;
+  opacity: 0.8;
+  background-color: var(--control-inactive-color);
+  -webkit-animation-duration: 250ms;
+          animation-duration: 250ms;
+  -webkit-animation-fill-mode: both;
+          animation-fill-mode: both;
+  -webkit-animation-timing-function: steps(26);
+          animation-timing-function: steps(26);
+  width: 100%;
+  height: 100%;
+  -webkit-mask-image: url("images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg");
+          mask-image: url("images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg");
+  -webkit-mask-size: auto 100%;
+          mask-size: auto 100%;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  -webkit-mask-position: 0 0;
+          mask-position: 0 0;
+}
+input[type="checkbox"].ui-checkbox.ui-checkbox-backward-animation::after {
+  -webkit-animation-name: checkbox-out;
+          animation-name: checkbox-out;
+}
+input[type="checkbox"].ui-checkbox:checked::after {
+  background-color: var(--control-active-color);
+  -webkit-animation-name: checkbox-in;
+          animation-name: checkbox-in;
+}
+input[type="checkbox"].ui-checkbox:active::before {
+  opacity: 1;
+}
+input[type="checkbox"].ui-checkbox:disabled {
+  opacity: 0.4;
+}
+input[type="checkbox"].ui-checkbox.ui-checkbox-focus {
+  outline: 2px solid var(--primary-color);
+}
+@-webkit-keyframes radio-in {
+  from {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+  to {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+}
+@keyframes radio-in {
+  from {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+  to {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+}
+@-webkit-keyframes radio-out {
+  from {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+  to {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+}
+@keyframes radio-out {
+  from {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+  to {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+}
+input[type="radio"].ui-radio {
+  position: relative;
+  height: 32px;
+  width: 32px;
+  box-sizing: border-box;
+  outline: none;
+  -webkit-appearance: none;
+  margin: 0 18px;
+}
+input[type="radio"].ui-radio::before {
+  content: "";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 32px;
+  height: 32px;
+  background-color: var(--ripple-color);
+  border-radius: 100%;
+  opacity: 0;
+}
+input[type="radio"].ui-radio::after {
+  content: "";
+  position: absolute;
+  bottom: 0;
+  opacity: 0.8;
+  background-color: var(--control-inactive-color);
+  -webkit-animation-fill-mode: forwards;
+          animation-fill-mode: forwards;
+  -webkit-animation-duration: 250ms;
+          animation-duration: 250ms;
+  -webkit-animation-timing-function: steps(26);
+          animation-timing-function: steps(26);
+  width: 100%;
+  height: 100%;
+  -webkit-mask-image: url("images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg");
+          mask-image: url("images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg");
+  -webkit-mask-size: auto 100%;
+          mask-size: auto 100%;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  -webkit-mask-position: 0 0;
+          mask-position: 0 0;
+}
+input[type="radio"].ui-radio.ui-radio-backward-animation::after {
+  -webkit-animation-name: radio-out;
+          animation-name: radio-out;
+}
+input[type="radio"].ui-radio:checked::after {
+  background-color: var(--control-active-color);
+  -webkit-animation-name: radio-in;
+          animation-name: radio-in;
+}
+input[type="radio"].ui-radio:active::before {
+  opacity: 1;
+}
+input[type="radio"].ui-radio:disabled {
+  opacity: 0.4;
+}
+@-webkit-keyframes EXPAND {
+  0% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+  50% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1.3);
+    -ms-transform: translate(-50%, -50%) scale(1.3);
+    transform: translate(-50%, -50%) scale(1.3);
+  }
+  100% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(1.3);
+    -ms-transform: translate(-50%, -50%) scale(1.3);
+    transform: translate(-50%, -50%) scale(1.3);
+  }
+}
+@keyframes EXPAND {
+  0% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+  50% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1.3);
+    -ms-transform: translate(-50%, -50%) scale(1.3);
+    transform: translate(-50%, -50%) scale(1.3);
+  }
+  100% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(1.3);
+    -ms-transform: translate(-50%, -50%) scale(1.3);
+    transform: translate(-50%, -50%) scale(1.3);
+  }
+}
+.ui-text-input-container {
+  width: 100%;
+}
+textarea.ui-text-input {
+  resize: none;
+  overflow: hidden;
+  white-space: normal;
+  transition: height 200ms linear;
+}
+.ui-group-index + .ui-li-static input.ui-text-input,
+.ui-group-index + .ui-li-static textarea.ui-text-input {
+  padding: 0 13px 0 5px;
+}
+.ui-group-index + .ui-li-static input.ui-text-input + .ui-text-input-textline,
+.ui-group-index + .ui-li-static textarea.ui-text-input + .ui-text-input-textline {
+  margin: 5.5px 8px 10px 0px;
+}
+.ui-group-index + .ui-li-static input.ui-text-input ~ .ui-text-input-clear,
+.ui-group-index + .ui-li-static textarea.ui-text-input ~ .ui-text-input-clear {
+  right: 0;
+}
+.ui-group-index + .ui-li-static input.ui-text-input:focus.ui-text-input-clear-active,
+.ui-group-index + .ui-li-static textarea.ui-text-input:focus.ui-text-input-clear-active {
+  padding-right: 40px;
+}
+.ui-li-static input.ui-text-input + .ui-text-input-textline,
+.ui-li-static textarea.ui-text-input + .ui-text-input-textline {
+  position: absolute;
+  width: calc(100% -  32px);
+}
+.ui-li-static input.ui-text-input + .ui-text-input-textline + .ui-text-input-error-message,
+.ui-li-static textarea.ui-text-input + .ui-text-input-textline + .ui-text-input-error-message {
+  margin: 8px 0 0 0;
+}
+.ui-li-flex input.ui-text-input,
+.ui-li-flex textarea.ui-text-input {
+  padding: 0 5px;
+}
+.ui-li-flex input.ui-text-input + .ui-text-input-textline,
+.ui-li-flex textarea.ui-text-input + .ui-text-input-textline {
+  margin: 5.5px 0 -6px 0;
+}
+.ui-li-flex input.ui-text-input ~ .ui-text-input-clear,
+.ui-li-flex textarea.ui-text-input ~ .ui-text-input-clear {
+  top: 0;
+  margin-top: -35px;
+  margin-bottom: -6px;
+  right: 0;
+}
+.ui-popup textarea.ui-text-input {
+  min-height: 27px;
+  padding: 0;
+}
+.ui-popup textarea.ui-text-input + .ui-text-input-textline {
+  margin-left: 0;
+  margin-right: 0;
+  margin-bottom: 5.5px;
+}
+input.ui-text-input,
+textarea.ui-text-input {
+  border: 0;
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  box-sizing: border-box;
+  display: block;
+  width: 100%;
+  line-height: 26px;
+  font-family: Roboto-Regular;
+  -webkit-text-fill-color: transparent;
+  font-size: 19px;
+  background-color: transparent;
+  border: none;
+  caret-color: var(--primary-color);
+  margin: 8px 0 8px 0;
+}
+input.ui-text-input.ui-text-input-disabled,
+textarea.ui-text-input.ui-text-input-disabled,
+input.ui-text-input:disabled,
+textarea.ui-text-input:disabled {
+  text-shadow: 0 0 0 var(--text-input-disabled);
+}
+input.ui-text-input.ui-text-input-disabled::-webkit-input-placeholder,
+textarea.ui-text-input.ui-text-input-disabled::-webkit-input-placeholder,
+input.ui-text-input:disabled::-webkit-input-placeholder,
+textarea.ui-text-input:disabled::-webkit-input-placeholder {
+  text-shadow: 0 0 0 var(--text-input-disabled);
+}
+input.ui-text-input:not([disabled]),
+textarea.ui-text-input:not([disabled]) {
+  text-shadow: 0 0 0 var(--text-color);
+}
+input.ui-text-input:not([disabled])::-webkit-input-placeholder,
+textarea.ui-text-input:not([disabled])::-webkit-input-placeholder {
+  text-shadow: 0 0 0 var(--text-input-underline-inactive);
+}
+input.ui-text-input + .ui-text-input-textline,
+textarea.ui-text-input + .ui-text-input-textline {
+  height: 1px;
+  background: var(--text-input-underline-inactive);
+  box-sizing: border-box;
+  display: block;
+}
+input.ui-text-input + .ui-text-input-textline + .ui-text-input-error-message,
+textarea.ui-text-input + .ui-text-input-textline + .ui-text-input-error-message {
+  display: none;
+  color: var(--text-input-invalid-color);
+  font-size: 12px;
+}
+input.ui-text-input:focus,
+textarea.ui-text-input:focus {
+  outline: none;
+}
+input.ui-text-input:focus.ui-text-input-clear-active,
+textarea.ui-text-input:focus.ui-text-input-clear-active {
+  padding-right: 11px;
+}
+input.ui-text-input:focus + .ui-text-input-textline,
+textarea.ui-text-input:focus + .ui-text-input-textline {
+  height: 2px;
+  background: var(--primary-color);
+}
+input.ui-text-input:invalid + .ui-text-input-textline,
+textarea.ui-text-input:invalid + .ui-text-input-textline {
+  background: var(--text-input-invalid-color);
+}
+input.ui-text-input:invalid + .ui-text-input-textline + .ui-text-input-error-message,
+textarea.ui-text-input:invalid + .ui-text-input-textline + .ui-text-input-error-message {
+  display: block;
+}
+input.ui-text-input ~ .ui-text-input-clear,
+textarea.ui-text-input ~ .ui-text-input-clear {
+  display: block;
+  float: right;
+  top: -33.5px;
+  box-sizing: border-box;
+  margin-right: -8.5px;
+  margin-left: 8.5px;
+  position: relative;
+  width: 40px;
+  height: 40px;
+}
+input.ui-text-input ~ .ui-text-input-clear.ui-btn.ui-btn-icon.ui-btn-nobg::after,
+textarea.ui-text-input ~ .ui-text-input-clear.ui-btn.ui-btn-icon.ui-btn-nobg::after {
+  -webkit-mask-image: url("images/controls/core_button_icon_clear.png");
+          mask-image: url("images/controls/core_button_icon_clear.png");
+  width: 40px;
+  height: 40px;
+}
+input.ui-text-input ~ .ui-text-input-clear-hidden,
+textarea.ui-text-input ~ .ui-text-input-clear-hidden {
+  visibility: hidden;
+}
+input.ui-text-input.ui-text-input-widget-focused,
+textarea.ui-text-input.ui-text-input-widget-focused {
+  background-color: var(--textual-background);
+}
+/*special case of buttons and text-inputs:
+- wrapper is added
+- animation for buttons on white background
+*/
+.ui-textinput-box-with-right-button {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-wrap: nowrap;
+  -ms-flex-wrap: nowrap;
+  -o-flex-wrap: nowrap;
+  flex-wrap: nowrap;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  height: 40px;
+}
+.ui-textinput-box-with-right-button > * {
+  height: 33.5px;
+  margin-top: 3.5px;
+  -webkit-flex-grow: 1;
+      -ms-flex-positive: 1;
+          flex-grow: 1;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item),
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item),
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg {
+  max-width: 64px;
+  min-width: 40px;
+  -ms-flex-basis: auto;
+  -o-flex-basis: auto;
+  -webkit-flex-basis: auto;
+      -ms-flex-preferred-size: auto;
+          flex-basis: auto;
+  -webkit-order: 1;
+  -moz-order: 1;
+  -ms-order: 1;
+  -o-order: 1;
+  -ms-flex-order: 1;
+      order: 1;
+  width: auto;
+  box-sizing: content-box;
+  margin: 0 10px 0 0;
+  height: 40px;
+  min-height: 40px;
+  max-height: 40px;
+  padding: 0 6px;
+  background-color: transparent;
+  overflow-x: visible;
+  overflow-y: visible;
+  color: #52c7d9;
+  -webkit-mask-box-image-source: none;
+  -webkit-align-self: flex-start;
+  -ms-align-self: flex-start;
+  -o-align-self: flex-start;
+  -ms-flex-item-align: start;
+      align-self: flex-start;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::after,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::after,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg::after,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg::after {
+  background-color: #52c7d9;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg::before,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg::before {
+  background-color: var(--ripple-color);
+  opacity: 0;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active::before,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active::before,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-active::before,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-active::before {
+  -webkit-animation: EXPAND 200ms;
+  animation: EXPAND 200ms;
+  -webkit-animation-fill-mode: both;
+  animation-fill-mode: both;
+  opacity: 0;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon {
+  padding: 0 8.5px;
+  margin-right: 0;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::before,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::before,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon::before,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon::before {
+  border-radius: 20px;
+  width: 40px;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::after,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::after,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon::after,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon::after {
+  -webkit-mask-size: 40px, 40px;
+  -moz-mask-size: 40px, 40px;
+  -ms-mask-size: 40px, 40px;
+  -o-mask-size: 40px, 40px;
+  mask-size: 40px, 40px;
+  -webkit-mask-repeat: none;
+  -moz-mask-repeat: none;
+  -ms-mask-repeat: none;
+  -o-mask-repeat: none;
+  mask-repeat: none;
+  -webkit-mask-position: center center;
+  -moz-mask-position: center center;
+  -ms-mask-position: center center;
+  -o-mask-position: center center;
+  mask-position: center center;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-text-light::before,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-text-light::before,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-text-light::before,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-text-light::before {
+  border-radius: 5px;
+  width: 58px;
+  height: 32.5px;
+}
+.ui-textinput-box-with-right-button input.ui-text-input ~ .ui-text-input-clear {
+  right: 5px;
+  left: 5px;
+}
+.ui-textinput-box-with-right-button input.ui-text-input:focus.ui-text-input-clear-active {
+  padding-right: 20px;
+  margin-right: -15px;
+}
+.ui-listview li.ui-textinput-box-with-right-button {
+  padding-right: 0;
+}
+.ui-controlgroup .ui-radio > .ui-btn {
+  background: var(--background-color);
+}
+.ui-controlgroup .ui-btn-inner.ui-corner-left {
+  border-radius: 0;
+  background-clip: padding-box;
+}
+.ui-controlgroup .ui-btn-inner.ui-corner-right.ui-controlgroup-last {
+  border-radius: 0;
+  background-clip: padding-box;
+}
+.ui-controlgroup .ui-radio-on .ui-btn-inner {
+  color: #3b7796;
+}
+.ui-controlgroup .ui-radio-off .ui-btn-inner {
+  color: #c7c7c7;
+}
+.ui-controlgroup.ui-controlgroup-horizontal .ui-radio-on .ui-btn-inner {
+  color: #fafafa;
+}
+.ui-page {
+  border-top: none;
+  background: var(--background-color);
+  color: var(--text-color);
+  font-weight: normal;
+  font-family: Roboto-Regular;
+}
+.ui-page .ui-link-inherit {
+  color: #fff;
+}
+.ui-page .ui-link {
+  color: #2489CE;
+  font-weight: bold;
+}
+.ui-page .ui-link:hover {
+  color: #2489CE;
+}
+.ui-page .ui-link:active {
+  color: #2489CE;
+}
+.ui-page .ui-link:visited {
+  color: #2489CE;
+}
+a.ui-link-inherit {
+  text-decoration: none !important;
+}
+.ui-btn-active {
+  color: var(--primary-color);
+  cursor: pointer;
+  text-decoration: none;
+  background: var(--on-background);
+  outline: none;
+}
+.ui-btn-active a.ui-link-inherit {
+  color: var(--primary-color);
+}
+.ui-corner-tl {
+  border-top-left-radius: 0.3em;
+}
+.ui-corner-tr {
+  border-top-right-radius: 0.3em;
+}
+.ui-corner-bl {
+  border-bottom-left-radius: 0.3em;
+}
+.ui-corner-br {
+  border-bottom-right-radius: 0.3em;
+}
+.ui-corner-top {
+  border-top-left-radius: 0.3em;
+  border-top-right-radius: 0.3em;
+}
+.ui-corner-bottom {
+  border-bottom-left-radius: 0.3em;
+  border-bottom-right-radius: 0.3em;
+}
+.ui-corner-right {
+  border-top-right-radius: 0.3em;
+  border-bottom-right-radius: 0.3em;
+}
+.ui-corner-left {
+  border-top-left-radius: 0.3em;
+  border-bottom-left-radius: 0.3em;
+}
+.ui-corner-none {
+  border-radius: 0;
+}
+.ui-btn .ui-icon.ui-icon-naviframe-edit,
+.ui-btn .ui-icon.ui-icon-naviframe-plus,
+.ui-btn .ui-icon.ui-icon-naviframe-delete,
+.ui-btn .ui-icon.ui-icon-naviframe-search,
+.ui-btn .ui-icon.ui-icon-naviframe-selectall,
+.ui-btn .ui-icon.ui-icon-naviframe-drawer {
+  -webkit-mask-size: 100%;
+  -moz-mask-size: 100%;
+  -ms-mask-size: 100%;
+  -o-mask-size: 100%;
+  mask-size: 100%;
+}
+.ui-popup.ui-ctxpopup {
+  width: auto;
+  padding: 0;
+  background-color: transparent;
+  margin-top: 0;
+  max-width: 100%;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content {
+  width: auto;
+  padding: 0;
+  overflow: hidden;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content > ul {
+  overflow: auto;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content > ul::-webkit-scrollbar {
+  height: 4px;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content > ul::-webkit-scrollbar-thumb {
+  background-color: var(--primary-color);
+  border-radius: 1.5px;
+  border-bottom: 1px solid #fff;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content > ul::-webkit-scrollbar-button {
+  width: 2px;
+  height: 4px;
+  background-color: transparent;
+}
+.ui-popup.ui-ctxpopup .ui-popup-wrapper {
+  background-color: var(--more-options-background-color);
+  border: 1px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+  overflow: auto;
+  margin-left: 16px;
+  margin-right: 16px;
+  width: auto;
+}
+.ui-popup.ui-ctxpopup :focus {
+  outline: none;
+}
+.ui-popup.ui-ctxpopup.slideup.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: slideupfadeinfrombottom 250ms;
+          animation: slideupfadeinfrombottom 250ms;
+}
+.ui-popup.ui-ctxpopup.slideup.out {
+  -webkit-transform: translate3d(0, 5%, 0);
+  -ms-transform: translate3d(0, 5%, 0);
+  transform: translate3d(0, 5%, 0);
+  -webkit-animation: slideupfadeouttobottom 200ms;
+          animation: slideupfadeouttobottom 200ms;
+}
+.ui-popup.ui-ctxpopup .ui-listview {
+  margin: 0;
+  border: none;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-popup.ui-ctxpopup .ui-listview li {
+  -webkit-flex: 1 0 auto;
+  -moz-flex: 1 0 auto;
+  -ms-flex: 1 0 auto;
+  -o-flex: 1 0 auto;
+  flex: 1 0 auto;
+}
+.ui-popup.ui-ctxpopup .ui-listview .ui-li-anchor a {
+  font-size: 15px;
+  line-height: 20.5px;
+  padding: 0 16px;
+  min-height: 36px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview {
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview .ui-li-anchor a {
+  height: 40px;
+  -webkit-flex-direction: row;
+  -moz-flex-direction: row;
+  -ms-flex-direction: row;
+  -o-flex-direction: row;
+  flex-direction: row;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  -webkit-justify-content: flex-start;
+  -moz-justify-content: flex-start;
+  -ms-justify-content: flex-start;
+  -o-justify-content: flex-start;
+  -ms-flex-pack: start;
+      justify-content: flex-start;
+  text-align: left;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+.ui-popup.ui-ctxpopup .ui-listview li {
+  color: var(--text-color);
+  font-size: 15px;
+  border-top: 0;
+  border-bottom: 0;
+  border-right: 0;
+  border-left: 1px solid var(--more-options-background-color);
+}
+.ui-popup.ui-ctxpopup .ui-listview li:first-of-type {
+  border-left-width: 0;
+}
+.ui-popup.ui-ctxpopup .ui-listview li.ui-li-anchor > a {
+  box-sizing: border-box;
+  padding-top: 7.5px;
+  padding-bottom: 7.5px;
+}
+.ui-popup.ui-ctxpopup .ui-listview li.ui-li-anchor.ui-li-active {
+  background-color: var(--more-options-pressed-color);
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-basic .ui-li-anchor {
+  padding: 0 16px;
+  height: 36px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-basic .ui-li-anchor > a {
+  padding: 0;
+  margin: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor {
+  padding: 0;
+  height: 40px;
+  width: 53px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor > a {
+  padding: 0;
+  margin: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor > a > span {
+  padding: 0;
+  margin: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor {
+  padding: 0 16px;
+  height: 59px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor > a {
+  padding: 0;
+  margin: 0;
+  font-size: 13px;
+  line-height: 20px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor > a > span {
+  padding: 0;
+  margin: 0 0 2px 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li {
+  border-top: 1px solid var(--more-options-background-color);
+  border-bottom: 0;
+  border-right: 0;
+  border-left: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li:first-of-type {
+  border-top-width: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li.ui-li-anchor {
+  padding: 0 12px;
+  height: 40px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li.ui-li-anchor > a {
+  margin: 0;
+  padding: 0;
+  overflow: visible;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-icon {
+  display: inline-block;
+  vertical-align: middle;
+  margin-top: 0;
+  margin-bottom: 0;
+  margin-right: 10px;
+  margin-left: -2px;
+}
+.ui-popup.ui-ctxpopup .ui-icon {
+  width: 20px;
+  height: 20px;
+  display: block;
+  vertical-align: middle;
+  margin: 2px auto;
+}
+.ui-text-ellipsis {
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+  overflow: hidden !important;
+}
+/* Popup Toast and smallpopup will be integrated */
+/* Popup Toast */
+.ui-popup.ui-popup-toast {
+  background-color: transparent;
+  margin: 0 auto;
+  position: relative;
+  bottom: 0;
+  width: 100%;
+}
+.ui-popup.ui-popup-toast .ui-popup-content {
+  margin: auto;
+  margin-bottom: 64px;
+  width: -webkit-fit-content;
+  width: fit-content;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: space-between;
+      -ms-flex-pack: justify;
+          justify-content: space-between;
+  border-radius: 22px;
+  background-color: var(--toast-background);
+  padding: 12px 20px;
+  line-height: 20px;
+  color: var(--toast-text-color);
+  font-size: 16px;
+  font-family: Roboto-Regular;
+}
+@media all and (max-width: 479px) {
+  .ui-popup.ui-popup-toast .ui-popup-content {
+    max-width: 84%;
+  }
+  .ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button {
+    width: 84%;
+  }
+}
+@media all and (min-width: 480px) and (max-width: 959px) {
+  .ui-popup.ui-popup-toast .ui-popup-content {
+    max-width: 68%;
+  }
+  .ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button {
+    width: 68%;
+  }
+}
+@media all and (min-width: 960px) and (max-width: 1919px) {
+  .ui-popup.ui-popup-toast .ui-popup-content {
+    max-width: 37.5%;
+  }
+  .ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button {
+    width: 37.5%;
+  }
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button {
+  text-align: left;
+  min-height: 44px;
+  padding: 0px 20px;
+  background-color: var(--btn-toast-background);
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn {
+  padding: 4px 0 4px 20px;
+  margin: 0;
+  width: -webkit-fit-content;
+  width: fit-content;
+  color: var(--btn-toast-text-color);
+  font-size: 18px;
+  font-family: Roboto-Medium;
+  background-color: transparent;
+  line-height: 36px;
+  overflow: visible;
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item) {
+  background-color: transparent;
+  border: none;
+  border-radius: 0;
+  padding-right: 20px;
+  margin-right: -20px;
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before {
+  background-color: var(--ripple-color);
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active {
+  background-color: transparent;
+}
+.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content {
+  display: block;
+  padding: 12px 20px;
+}
+.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content.ui-popup-toast-has-button {
+  padding-top: 9px;
+  padding-bottom: 4px;
+}
+.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content.ui-popup-toast-has-button .ui-btn {
+  margin-left: auto;
+  padding-top: 5px;
+  padding-bottom: 0;
+}
+/* smallpopup */
+@-webkit-keyframes ui-smallpopup-show {
+  from {
+    display: none;
+    opacity: 0;
+    -webkit-transform: scaleY(0);
+    -ms-transform: scaleY(0);
+    transform: scaleY(0);
+  }
+  to {
+    display: block;
+    opacity: 1;
+    -webkit-transform: scaleY(1);
+    -ms-transform: scaleY(1);
+    transform: scaleY(1);
+  }
+}
+@keyframes ui-smallpopup-show {
+  from {
+    display: none;
+    opacity: 0;
+    -webkit-transform: scaleY(0);
+    -ms-transform: scaleY(0);
+    transform: scaleY(0);
+  }
+  to {
+    display: block;
+    opacity: 1;
+    -webkit-transform: scaleY(1);
+    -ms-transform: scaleY(1);
+    transform: scaleY(1);
+  }
+}
+.ui-smallpopup {
+  position: fixed;
+  display: none;
+  margin-bottom: 32px;
+  max-width: 236px;
+  z-index: 1100;
+  vertical-align: middle;
+  font-size: 16px;
+  word-break: break-all;
+}
+.ui-smallpopup::before {
+  position: absolute;
+  content: '';
+  width: 100%;
+  height: 100%;
+}
+.ui-smallpopup.fix {
+  display: block;
+}
+.ui-smallpopup.show {
+  display: block;
+  -webkit-animation: ui-smallpopup-show 500ms 1 ease;
+  animation: ui-smallpopup-show 500ms 1 ease;
+}
+.ui-smallpopup.hide {
+  display: none;
+}
+.ui-smallpopup-text-bg {
+  position: relative;
+  padding: 3.5px 12px 5px 12px;
+  line-height: 18.5px;
+  margin: 0;
+  color: var(--toast-text-color);
+  font-size: 16px;
+}
+.ui-popup {
+  display: none;
+  position: absolute;
+  left: 0;
+  margin-bottom: 16px;
+  margin-top: 32px;
+  z-index: 1201 !important;
+  background-color: var(--popup-background);
+  border-radius: 26px;
+}
+@media (max-width: 479px) {
+  .ui-popup {
+    width: 100%;
+  }
+}
+@media (min-width: 480px) and (max-width: 672px) {
+  .ui-popup {
+    width: 63%;
+  }
+}
+@media (min-width: 673px) and (max-width: 985px) {
+  .ui-popup {
+    width: 55%;
+  }
+}
+@media (min-width: 986px) {
+  .ui-popup {
+    width: 35%;
+  }
+}
+.ui-popup .ui-popup-wrapper {
+  width: 100%;
+}
+.ui-popup.ui-popup-active {
+  display: block;
+}
+.ui-popup.in {
+  display: block;
+}
+.ui-popup.ui-build {
+  display: block;
+  visibility: hidden;
+}
+.ui-popup .ui-popup-header {
+  width: 100%;
+  text-align: left;
+  background-color: var(--popup-background);
+  position: -webkit-sticky;
+  position: sticky;
+  font-size: 20px;
+  color: var(--text-color);
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  font-family: Roboto-Medium;
+}
+.ui-popup .ui-popup-header::after {
+  content: "";
+  position: absolute;
+  left: 24px;
+  width: calc(100% - 48px);
+  height: 0.75px;
+  stroke-width: 0.5;
+  visibility: hidden;
+  background-color: var(--popup-scroll-divider-color);
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-header::after {
+    top: 68px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-header::after {
+    top: 45px;
+  }
+}
+.ui-popup .ui-popup-header.topDivider::after {
+  visibility: visible;
+}
+.ui-popup .ui-popup-header.ui-popup-header-has-subtitle {
+  padding: 9.75px 16px;
+  line-height: 28.5px;
+  font-size: 20px;
+  color: T1212;
+}
+.ui-popup .ui-popup-header .ui-popup-subtitle {
+  line-height: 19px;
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-header {
+    padding: 26px 24px 19px 24px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-header {
+    padding: 14px 24px 8px 24px;
+  }
+}
+.ui-popup .ui-popup-content {
+  width: 100%;
+  background-color: var(--popup-background);
+  color: var(--popup-text);
+  text-align: left;
+  font-size: 16px;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+  -moz-overflow-scrolling: touch;
+  -o-overflow-scrolling: touch;
+  -ms-overflow-scrolling: touch;
+  overflow-scrolling: touch;
+  line-height: 23px;
+}
+.ui-popup .ui-popup-content img {
+  display: block;
+  margin: 0 auto;
+  padding-bottom: 12px;
+}
+.ui-popup .ui-popup-content.ui-date-picker-calendar {
+  padding-left: 16px;
+  padding-right: 16px;
+}
+.ui-popup .ui-popup-content .ui-popup-body-text {
+  margin-top: 8px;
+}
+.ui-popup .ui-popup-content .ui-popup-body-checkbox {
+  margin-top: 8px;
+  height: 32px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-popup .ui-popup-content .ui-popup-body-checkbox input[type="Checkbox"] {
+  margin: 0 12px 0 -4px;
+}
+.ui-popup .ui-popup-content .ui-popup-body-checkbox span {
+  margin-top: 5px;
+}
+.ui-popup .ui-popup-content ul .ui-li-has-checkbox .ui-li-text span {
+  font-size: 18px;
+}
+.ui-popup .ui-popup-content ul .ui-li-has-checkbox input {
+  margin-left: 18px;
+  margin-right: 18px;
+}
+.ui-popup .ui-popup-content .ui-popup-container-text {
+  width: 100%;
+  height: 19px;
+  line-height: 19px;
+  color: var(--popup-text-color);
+  font-size: 14px;
+  font-family: Roboto-Regular;
+}
+.ui-popup .ui-popup-content .ui-popup-container-text .text-left {
+  float: left;
+}
+.ui-popup .ui-popup-content .ui-popup-container-text .text-right {
+  float: right;
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-content {
+    padding: 0 24px 0 24px;
+    margin-bottom: 24px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-content {
+    padding: 0 24px 0 24px;
+    margin-bottom: 11px;
+  }
+}
+.ui-popup .ui-popup-content.ui-popup-has-time-picker,
+.ui-popup .ui-popup-content.ui-popup-has-date-picker {
+  padding-left: unset;
+  padding-right: unset;
+}
+.ui-popup .ui-popup-footer {
+  background-color: var(--popup-background);
+  position: -webkit-sticky;
+  position: sticky;
+  box-sizing: border-box;
+  padding: 12px 24px;
+  text-align: center;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+  width: 100%;
+}
+.ui-popup .ui-popup-footer::before {
+  content: "";
+  position: absolute;
+  left: 24px;
+  width: calc(100% - 48px);
+  height: 0.75px;
+  stroke-width: 0.5;
+  visibility: hidden;
+  background-color: var(--popup-scroll-divider-color);
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-footer::before {
+    bottom: 80px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-footer::before {
+    bottom: 50px;
+  }
+}
+.ui-popup .ui-popup-footer.bottomDivider::before {
+  visibility: visible;
+}
+.ui-popup .ui-popup-footer .ui-btn {
+  height: 36px;
+  margin: 0 auto;
+  max-width: 248px;
+}
+.ui-popup .ui-popup-footer .ui-btn.ui-btn-flat {
+  font-size: 16px;
+}
+.ui-popup .ui-popup-footer div.ui-li-divider::after {
+  content: "";
+  position: absolute;
+  width: 1px;
+  height: 16px;
+  top: 10px;
+  background-color: var(--popup-footer-divider-color);
+}
+.ui-popup .ui-popup-footer .ui-popup-stack .ui-btn {
+  margin-bottom: 16px;
+}
+.ui-popup .ui-popup-footer .ui-popup-stack .ui-btn:nth-last-child(1) {
+  margin-bottom: 0;
+}
+.ui-popup .ui-popup-footer .ui-li-action {
+  width: 50%;
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-footer {
+    padding: 0px 24px 20px 24px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-footer {
+    padding: 0px 24px 4px 24px;
+  }
+}
+.ui-popup .ui-listview {
+  margin-left: -24px;
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-notitle {
+    margin-top: 26px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-notitle {
+    margin-top: 14px;
+  }
+}
+.ui-popup .ui-popup-2level-description {
+  height: auto;
+  margin-top: 8px;
+  margin-left: 8px;
+  color: var(--popup-text-secondary-color);
+}
+.ui-popup .ui-popup-2level-description span {
+  padding-right: 12px;
+}
+.ui-popup .ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a {
+  margin-top: 14px;
+  margin-bottom: 14px;
+}
+.ui-popup .ui-popup-header,
+.ui-popup .ui-popup-content,
+.ui-popup .ui-popup-footer {
+  box-sizing: border-box;
+}
+.ui-popup.ui-popup-listview {
+  background-image: url("images/page/core_theme_bg_01.png");
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  overflow: hidden;
+  background-color: transparent;
+}
+.ui-popup.ui-popup-listview .ui-popup-header {
+  padding-top: 8px;
+  padding-bottom: 8px;
+}
+.ui-popup.ui-popup-listview .ui-popup-content {
+  padding: 0;
+  background-color: transparent;
+  position: relative;
+}
+.ui-popup.ui-popup-listview .ui-listview {
+  position: relative;
+  overflow: hidden;
+  -webkit-transform: translate3d(0, 0, 0);
+          transform: translate3d(0, 0, 0);
+}
+.ui-popup.ui-popup-listview .ui-listview::before {
+  content: "";
+  background-color: var(--overlay);
+  width: 100%;
+  height: 100%;
+  display: block;
+  position: absolute;
+  top: 0;
+  z-index: 1;
+  pointer-events: none;
+}
+.ui-popup.ui-popup-moremenu {
+  max-height: 420px;
+  overflow: hidden;
+}
+@media (orientation: landscape) {
+  .ui-popup.ui-popup-moremenu {
+    max-height: 300px;
+    width: 360px;
+  }
+}
+.ui-popup-overlay {
+  display: none;
+  background-color: var(--overlay);
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 1200;
+}
+.ui-popup-overlay.ui-popup-overlay-shown {
+  display: block;
+}
+.ui-popup.ui-popup-activity .ui-popup-content {
+  text-align: right;
+}
+@media (orientation: landscape) {
+  .ui-popup.ui-popup-activity .ui-popup-content {
+    width: 100%;
+  }
+}
+@-webkit-keyframes popup-activity {
+  from {
+    -webkit-transform: rotate(0deg);
+    -ms-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  to {
+    -webkit-transform: rotate(360deg);
+    -ms-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+@keyframes popup-activity {
+  from {
+    -webkit-transform: rotate(0deg);
+    -ms-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  to {
+    -webkit-transform: rotate(360deg);
+    -ms-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup.ui-popup-activity {
+    width: 100%;
+  }
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-small .ui-popup-content {
+  text-align: right;
+  height: 39px;
+  padding: 8px 16px;
+  font-size: 20px;
+  color: T120L1;
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-small .ui-popup-content::after {
+  content: "";
+  width: 22px;
+  height: 22px;
+  margin-left: 16px;
+  background-color: W157E1;
+  -webkit-mask-image: url("images/core_activity_indicator_a.svg"), url("images/core_activity_indicator_b.svg"), url("images/core_activity_indicator_c.svg");
+          mask-image: url("images/core_activity_indicator_a.svg"), url("images/core_activity_indicator_b.svg"), url("images/core_activity_indicator_c.svg");
+  -webkit-mask-size: 100% 100%, 100% 100%, 100% 100%;
+          mask-size: 100% 100%, 100% 100%, 100% 100%;
+  float: right;
+  -webkit-animation-name: popup-activity;
+          animation-name: popup-activity;
+  -webkit-animation-duration: 1s;
+          animation-duration: 1s;
+  -webkit-animation-timing-function: linear;
+          animation-timing-function: linear;
+  -webkit-animation-iteration-count: infinite;
+          animation-iteration-count: infinite;
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-medium .ui-popup-content {
+  text-align: left;
+  height: 60px;
+  padding: 16px 16px;
+  font-size: 20px;
+  color: T120L2;
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-medium .ui-popup-content::before {
+  content: "";
+  width: 28px;
+  height: 28px;
+  margin-right: 16px;
+  background-color: W157E1;
+  float: left;
+  -webkit-mask-image: url("images/core_activity_indicator_a.svg"), url("images/core_activity_indicator_b.svg"), url("images/core_activity_indicator_c.svg");
+          mask-image: url("images/core_activity_indicator_a.svg"), url("images/core_activity_indicator_b.svg"), url("images/core_activity_indicator_c.svg");
+  -webkit-mask-size: 100% 100%, 100% 100%, 100% 100%;
+          mask-size: 100% 100%, 100% 100%, 100% 100%;
+  -webkit-animation-name: popup-activity;
+          animation-name: popup-activity;
+  -webkit-animation-duration: 1s;
+          animation-duration: 1s;
+  -webkit-animation-timing-function: linear;
+          animation-timing-function: linear;
+  -webkit-animation-iteration-count: infinite;
+          animation-iteration-count: infinite;
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-large .ui-popup-content {
+  text-align: center;
+  height: 0;
+  background-color: W157E1;
+  -webkit-mask-image: url("images/core_activity_indicator_c.svg");
+          mask-image: url("images/core_activity_indicator_c.svg");
+  -webkit-mask-size: 100% 100%;
+          mask-size: 100% 100%;
+}
+.ui-popup:not(.ui-ctxpopup).slideup.out {
+  -webkit-animation: popupslideouttobottom 400ms ease-out;
+  animation: popupslideouttobottom 400ms ease-out;
+}
+.ui-popup:not(.ui-ctxpopup).slideup.in {
+  -webkit-animation: popupslideinfrombottom 400ms ease-out;
+  animation: popupslideinfrombottom 400ms ease-out;
+}
+.ui-popup.slideup.in:not(.ui-ctxpopup) .ui-popup-wrapper {
+  -webkit-transform: translateY(100%);
+  -ms-transform: translateY(100%);
+  transform: translateY(100%);
+  -webkit-animation: popupwrapperslideinfrombottom 350ms ease-out 50ms;
+  animation: popupwrapperslideinfrombottom 350ms ease-out 50ms;
+}
+.ui-popup.slideup.out:not(.ui-ctxpopup) .ui-popup-wrapper {
+  -webkit-transform: translateY(25px);
+  -ms-transform: translateY(25px);
+  transform: translateY(25px);
+  -webkit-animation: popupwrapperslideouttobottom 4000ms ease-out;
+  animation: popupwrapperslideouttobottom 4000ms ease-out;
+}
+.ui-popup-overlay.slideup.in:not(.ui-ctxpopup-overlay) {
+  -webkit-animation: popupoverlayfadein 400ms ease-out;
+  animation: popupoverlayfadein 400ms ease-out;
+}
+.ui-popup-overlay.slideup.out:not(.ui-ctxpopup-overlay) {
+  -webkit-animation: popupoverlayfadeout 400ms ease-out;
+  animation: popupoverlayfadeout 400ms ease-out;
+}
+@-webkit-keyframes popupslideouttobottom {
+  from {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+  to {
+    -webkit-transform: translateY(100%);
+    -ms-transform: translateY(100%);
+    transform: translateY(100%);
+  }
+}
+@keyframes popupslideouttobottom {
+  from {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+  to {
+    -webkit-transform: translateY(100%);
+    -ms-transform: translateY(100%);
+    transform: translateY(100%);
+  }
+}
+@-webkit-keyframes popupslideinfrombottom {
+  from {
+    -webkit-transform: translateY(100%);
+    -ms-transform: translateY(100%);
+    transform: translateY(100%);
+  }
+  to {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+}
+@keyframes popupslideinfrombottom {
+  from {
+    -webkit-transform: translateY(100%);
+    -ms-transform: translateY(100%);
+    transform: translateY(100%);
+  }
+  to {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+}
+@-webkit-keyframes popupwrapperslideinfrombottom {
+  from {
+    -webkit-transform: translateY(25px);
+    -ms-transform: translateY(25px);
+    transform: translateY(25px);
+  }
+  to {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+}
+@keyframes popupwrapperslideinfrombottom {
+  from {
+    -webkit-transform: translateY(25px);
+    -ms-transform: translateY(25px);
+    transform: translateY(25px);
+  }
+  to {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+}
+@-webkit-keyframes popupwrapperslideouttobottom {
+  from {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+  to {
+    -webkit-transform: translateY(25px);
+    -ms-transform: translateY(25px);
+    transform: translateY(25px);
+  }
+}
+@keyframes popupwrapperslideouttobottom {
+  from {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+  to {
+    -webkit-transform: translateY(25px);
+    -ms-transform: translateY(25px);
+    transform: translateY(25px);
+  }
+}
+@-webkit-keyframes popupoverlayfadein {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@keyframes popupoverlayfadein {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes popupoverlayfadeout {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+@keyframes popupoverlayfadeout {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+.ui-scrollview-clip {
+  display: block;
+  position: relative;
+  z-index: 100;
+  overflow-x: hidden;
+  overflow-y: visible;
+}
+.ui-scrollview-clip[data-scroll="x"] {
+  -webkit-scroll-snap-type: x mandatory;
+      -ms-scroll-snap-type: x mandatory;
+          scroll-snap-type: x mandatory;
+}
+.ui-scrollview-clip[data-scroll="x"] .ui-scrollview-view {
+  overflow: initial;
+}
+.ui-scrollview-view {
+  overflow: hidden;
+  min-height: 100%;
+  min-width: 100%;
+  box-sizing: border-box;
+}
+.ui-scrolllistview .ui-li-divider {
+  z-index: 10;
+}
+.ui-scrollbar {
+  position: absolute;
+  overflow: hidden;
+  opacity: 0;
+}
+.ui-scrollbar-visible {
+  opacity: 1;
+}
+.ui-scrollbar-y {
+  top: 0;
+  right: 1px;
+  bottom: 0;
+  width: 4px;
+}
+.ui-scrollbar-x {
+  right: 1px;
+  bottom: 1px;
+  left: 1px;
+  height: 4px;
+}
+.ui-scrollbar-track {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.ui-scrollbar-thumb {
+  position: absolute;
+  top: 0;
+  left: 0;
+  background-color: var(--primary-color);
+}
+.ui-scrollbar-y .ui-scrollbar-thumb {
+  width: 2.5px;
+  height: 100%;
+  border-radius: 1px;
+  -o-box-shadow: 0.5px 0.5px 2px #080808;
+  -ms-box-shadow: 0.5px 0.5px 2px #080808;
+  box-shadow: 0.5px 0.5px 2px #080808;
+}
+.ui-scrollbar-x .ui-scrollbar-thumb {
+  width: 100%;
+  height: 2.5px;
+  border-radius: 1px;
+}
+.ui-scroll-jump-top-bg {
+  position: absolute;
+  top: 4.5px;
+  right: 6.5px;
+  width: 18.5px;
+  height: 18.5px;
+}
+.ui-scroll-jump-left-bg {
+  position: absolute;
+  bottom: 4.5px;
+  left: 6.5px;
+  width: 18.5px;
+  height: 18.5px;
+}
+.ui-overflow-indicator-top,
+.ui-overflow-indicator-bottom {
+  position: absolute;
+  display: none;
+  width: 100%;
+  height: 14.5px;
+  opacity: 1;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+}
+.ui-overflow-indicator-top {
+  top: 0;
+}
+.ui-overflow-indicator-bottom {
+  bottom: 0;
+}
+.ui-overflow-effect-bottom {
+  position: absolute;
+  display: none;
+  bottom: 0;
+  width: 100%;
+}
+.ui-overflow-top {
+  opacity: 1;
+}
+.ui-overflow-top.ui-overflow-top-hide {
+  height: 0 !important;
+}
+.ui-overflow-bottom {
+  opacity: 1;
+}
+.ui-overflow-bottom.ui-overflow-bottom-hide {
+  height: 0 !important;
+}
+/*
+ * padding here set to zero - otherwise the list scrolls underneith the top heading and can be seen above it
+ */
+.ui-content.ui-scrollview-clip {
+  padding: 0;
+}
+.ui-content.ui-scrollview-clip > div.ui-scrollview-view {
+  margin: 0;
+}
+/*
+ * this seems to effect how far the top divider is place wrt to the scrollview
+ * without this, it is placed too high, so it is clipped in half
+ */
+.ui-content.ui-scrollview-clip > .ui-listview.ui-scrollview-view {
+  margin: 0;
+}
+/*
+ * Section for scroll handler to hide native scrollbar
+ */
+.ui-content.ui-scrollview-clip.ui-hide-scrollbar::-webkit-scrollbar {
+  display: none;
+}
+.ui-slider {
+  position: relative;
+  box-sizing: border-box;
+  height: 32px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: space-around;
+      -ms-flex-pack: distribute;
+          justify-content: space-around;
+}
+.ui-slider .ui-slider-bar {
+  background-color: var(--slider-bg-color);
+  height: 3px;
+  border-radius: 1.5px;
+  overflow: hidden;
+}
+.ui-slider .ui-slider-bar .ui-slider-value {
+  height: 100%;
+  background-color: var(--slider-handler-color);
+}
+.ui-slider:focus {
+  outline: none;
+}
+.ui-slider .ui-slider-handler-track {
+  position: absolute;
+  width: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-slider .ui-slider-handler-track .ui-slider-before-space {
+  height: 1px;
+}
+.ui-slider .ui-slider-handler-track .ui-slider-after-space {
+  height: 1px;
+}
+.ui-slider .ui-slider-handler {
+  width: 17px;
+  height: 17px;
+  min-width: 17px;
+  min-height: 17px;
+  background-color: var(--slider-value-color);
+  position: relative;
+  border-radius: 50%;
+  pointer-events: none;
+  z-index: 9;
+}
+.ui-slider .ui-slider-handler::before {
+  content: "";
+  width: 32px;
+  height: 32px;
+  opacity: 0;
+  position: absolute;
+  left: -5px;
+  top: -5px;
+  border-radius: 100%;
+  background-color: var(--ripple-color);
+}
+.ui-slider.ui-slider-active .ui-slider-handler {
+  min-width: 22px;
+  min-height: 22px;
+}
+.ui-slider.ui-slider-active .ui-slider-handler::before {
+  opacity: 1;
+}
+.ui-slider.ui-disabled .ui-slider-bar {
+  background-color: var(--slider-bg-disabled-color);
+}
+.ui-slider.ui-disabled .ui-slider-bar .ui-slider-value {
+  background-color: var(--slider-handler-disabled-color);
+}
+.ui-slider.ui-disabled .ui-slider-handler {
+  background-color: var(--slider-handler-disabled-color);
+}
+.ui-slider.ui-slider-level-bar {
+  margin-left: 5px;
+  margin-right: 5px;
+  height: 32px;
+}
+.ui-slider.ui-slider-level-bar .ui-slider-bar {
+  background-color: var(--slider-level-bar-bg-color);
+}
+.ui-slider.ui-slider-level-bar .ui-slider-bar .ui-slider-value {
+  display: none;
+}
+.ui-slider.ui-slider-level-bar .ui-slider-bar::before {
+  display: none;
+  border-image: none;
+}
+.ui-slider.ui-slider-level-bar input {
+  width: 100%;
+}
+.ui-slider.ui-slider-level-bar .ui-slider-scale {
+  position: absolute;
+  width: 100%;
+  height: 7px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: space-between;
+      -ms-flex-pack: justify;
+          justify-content: space-between;
+  pointer-events: none;
+}
+.ui-slider.ui-slider-level-bar .ui-slider-scale .ui-slider-scale-dot {
+  width: 7px;
+  height: 7px;
+  border-radius: 100%;
+  background-color: var(--slider-scale-dot);
+}
+.ui-slider.ui-slider-level-bar .ui-slider-handler-track {
+  width: calc(100% +  10px);
+  left: -5px;
+}
+.ui-slider-label {
+  font-size: 12px;
+  color: var(--text-secondary-color);
+}
+.ui-slider-label-min {
+  position: absolute;
+  left: 0;
+  bottom: -2px;
+}
+.ui-slider-label-max {
+  position: absolute;
+  right: 0;
+  bottom: -2px;
+}
+.ui-slider.ui-slider-has-labels {
+  height: 50px;
+}
+input[data-tau-built="Slider"] {
+  opacity: 0;
+  display: block;
+  width: 100%;
+  position: absolute;
+  margin: 0;
+}
+/*new button type like*/
+tau-toggleswitch {
+  display: block;
+}
+.ui-toggle-container {
+  position: relative;
+  width: 36px;
+  height: 36px;
+}
+.ui-toggle-container .ui-switch-handler {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  top: 0;
+  left: 0;
+  background-color: transparent;
+  pointer-events: none;
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
+  -webkit-perspective: 1000px;
+          perspective: 1000px;
+}
+.ui-toggle-container .ui-switch-handler:before,
+.ui-toggle-container .ui-switch-handler:after {
+  content: "";
+  position: absolute;
+  height: 100%;
+  width: 100%;
+  -webkit-mask-position: center center;
+          mask-position: center center;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+}
+.ui-toggle-container .ui-switch-handler:before {
+  background-color: W015L1i;
+  -webkit-mask-image: url("images/controls/core_toggle_icon_off.svg");
+          mask-image: url("images/controls/core_toggle_icon_off.svg");
+  -webkit-transform: scale(1);
+      -ms-transform: scale(1);
+          transform: scale(1);
+  transition: 250ms ease-out 50ms;
+}
+.ui-toggle-container .ui-switch-handler:after {
+  background-color: W015L1i;
+  -webkit-mask-image: url("images/controls/core_toggle_icon_on.svg");
+          mask-image: url("images/controls/core_toggle_icon_on.svg");
+  -webkit-transform: scale(0);
+      -ms-transform: scale(0);
+          transform: scale(0);
+  transition: 100ms ease-out;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch {
+  width: 36px;
+  height: 36px;
+  border-radius: 50%;
+  background-color: W015L1E1;
+  /*@color_toggle_bg;*/
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  outline: 0;
+  margin: 0;
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
+  -webkit-perspective: 1000px;
+          perspective: 1000px;
+  transition: background-color 150ms;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch::before {
+  content: none;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch:checked {
+  background-color: var(--color-white);
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch:checked ~ .ui-switch-handler::before {
+  -webkit-transform: scale(0);
+      -ms-transform: scale(0);
+          transform: scale(0);
+  transition: 100ms ease-out;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch:checked ~ .ui-switch-handler::after {
+  -webkit-transform: scale(1);
+      -ms-transform: scale(1);
+          transform: scale(1);
+  transition: 250ms ease-out 50ms;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch:disabled {
+  background-color: W015L1D;
+}
+.ui-toggle-switch-focus {
+  outline: 2px solid var(--primary-color);
+}
+@-webkit-keyframes move-to-off {
+  to {
+    -webkit-transform: translateX(0);
+            transform: translateX(0);
+  }
+}
+@keyframes move-to-off {
+  to {
+    -webkit-transform: translateX(0);
+            transform: translateX(0);
+  }
+}
+@-webkit-keyframes move-to-on {
+  to {
+    -webkit-transform: translateX(17px);
+            transform: translateX(17px);
+  }
+}
+@keyframes move-to-on {
+  to {
+    -webkit-transform: translateX(17px);
+            transform: translateX(17px);
+  }
+}
+.ui-on-off-switch-container {
+  position: relative;
+  display: inline-block;
+  width: 43px;
+  height: 27px;
+  max-width: 43px;
+  max-height: 27px;
+  min-width: 43px;
+  min-height: 27px;
+  overflow: hidden;
+}
+.ui-on-off-switch-input {
+  position: absolute;
+  width: 37px;
+  height: 18.5px;
+  border-radius: 9.25px;
+  -webkit-appearance: none;
+  display: block;
+  margin: 4.25px 3px;
+  border: 1px solid var(--on-off-switch-off-button-border);
+  background-color: var(--on-off-switch-off-track-background);
+  outline: none;
+  box-sizing: border-box;
+}
+.ui-on-off-switch-input:active ~ .ui-on-off-switch-button::before {
+  opacity: 1;
+}
+.ui-on-off-switch-input:disabled {
+  border-color: var(--on-off-switch-off-disabled-track-border);
+}
+.ui-on-off-switch-input:disabled ~ .ui-on-off-switch-button {
+  border-color: var(--on-off-switch-off-disabled-button-border);
+  background-color: var(--on-off-switch-on-disabled-button-background);
+}
+.ui-on-off-switch-button {
+  width: 22px;
+  height: 22px;
+  border-radius: 100%;
+  margin: 2.5px 2px;
+  box-sizing: border-box;
+  border: 1px solid var(--on-off-switch-off-button-border);
+  background-color: var(--color-white);
+  position: absolute;
+  top: 0;
+  left: 0;
+  pointer-events: none;
+  z-index: 1;
+  transition: -webkit-transform cubic-bezier(0.6, 0.6, 0.8, 1.49) 250ms;
+  transition: transform cubic-bezier(0.6, 0.6, 0.8, 1.49) 250ms;
+  transition: transform cubic-bezier(0.6, 0.6, 0.8, 1.49) 250ms, -webkit-transform cubic-bezier(0.6, 0.6, 0.8, 1.49) 250ms;
+  -webkit-transform: translate3d(0, 0, 0);
+          transform: translate3d(0, 0, 0);
+}
+.ui-on-off-switch-button::before {
+  content: "";
+  width: 27px;
+  height: 27px;
+  opacity: 0;
+  position: absolute;
+  left: -3px;
+  top: -3px;
+  border-radius: 100%;
+  background-color: var(--ripple-color);
+}
+.ui-on-off-switch-button-on-drag {
+  transition: none;
+}
+.ui-on-off-switch-button-on-drag::before {
+  opacity: 1;
+}
+.ui-on-off-switch-button-move-to-off {
+  -webkit-animation: move-to-off 100ms ease-in-out 0s 1 normal both;
+          animation: move-to-off 100ms ease-in-out 0s 1 normal both;
+  transition: none;
+}
+.ui-on-off-switch-button-move-to-on {
+  -webkit-animation: move-to-on 100ms ease-in-out 0s 1 normal both;
+          animation: move-to-on 100ms ease-in-out 0s 1 normal both;
+  transition: none;
+}
+.ui-on-off-switch-input:checked {
+  background-color: var(--primary-color);
+  border-color: var(--primary-color);
+  width: 37px;
+  height: 18.5px;
+  margin: 4.25px 3px;
+}
+.ui-on-off-switch-input:checked:disabled {
+  background-color: var(--on-off-switch-on-disabled-track-background);
+  border-color: transparent;
+}
+.ui-on-off-switch-input:checked:disabled ~ .ui-on-off-switch-button {
+  border-color: var(--on-off-switch-on-disabled-button-border);
+}
+.ui-on-off-switch-input:checked ~ .ui-on-off-switch-button {
+  border-color: var(--primary-color);
+  -webkit-transform: translate3d(17px, 0, 0);
+          transform: translate3d(17px, 0, 0);
+}
+.ui-master-on-off-switch {
+  font-family: Roboto-Regular;
+  font-size: 18px;
+  margin-left: 0;
+  margin-right: 0;
+  margin-bottom: 20px;
+  height: 64px;
+  position: relative;
+}
+.ui-master-on-off-switch .ui-on-off-label {
+  background-color: var(--master-on-off-off-color);
+  position: absolute;
+  left: 0;
+  right: 0;
+  width: 100%;
+  height: 100%;
+  border-radius: 26px;
+  box-sizing: border-box;
+  padding-left: 24px;
+  padding-right: 24px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-master-on-off-switch .ui-on-off-label::before {
+  content: "";
+  width: 100%;
+  height: 64px;
+  opacity: 0;
+  position: absolute;
+  left: 0;
+  top: 0;
+  border-radius: 26px;
+  background-color: var(--ripple-color);
+}
+.ui-master-on-off-switch .ui-on-off-label-active::before {
+  opacity: 1;
+}
+.ui-master-on-off-switch .ui-on-off-label span {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-master-on-off-switch .ui-on-off-label-on {
+  color: var(--color-white);
+  background-color: var(--master-on-off-on-color);
+}
+.ui-master-on-off-switch .ui-on-off-switch-input:active ~ .ui-on-off-switch-button::before {
+  opacity: 0;
+}
+.ui-sub-tab {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: calc(100% -  48px);
+  height: 56px;
+  margin-left: 24px;
+  margin-right: 24px;
+  background-color: var(--sub-tab-bg-color);
+}
+.ui-sub-tab a {
+  font-family: Roboto-Regular;
+  font-size: 15px;
+  line-height: 22px;
+  padding-left: 12px;
+  padding-right: 12px;
+  color: var(--sub-tab-text-color);
+  border-radius: 18px;
+  box-sizing: border-box;
+  border: 0 solid var(--sub-tab-border-color);
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  position: relative;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  width: 100%;
+  min-height: 36px;
+  text-decoration: none;
+}
+.ui-sub-tab a span {
+  position: relative;
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  height: 100%;
+  overflow-x: hidden;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: flex-start;
+      -ms-flex-pack: start;
+          justify-content: flex-start;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-sub-tab a.ui-tab-active {
+  font-family: Roboto-Medium;
+  color: var(--sub-tab-active-text-color);
+  border-width: 1px;
+}
+.ui-sub-tab a.ui-sub-tab-inactive-text-overflow span {
+  display: inline-block;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-sub-tab a::before {
+  content: "";
+  width: 100%;
+  height: 100%;
+  top: 0;
+  left: 0;
+  position: absolute;
+  opacity: 0;
+  background-color: var(--ripple-color);
+  border-radius: 26px;
+}
+.ui-sub-tab a.ui-btn-active {
+  background-color: inherit;
+}
+.ui-sub-tab a.ui-btn-active::before {
+  -webkit-animation: animation_opacity_in linear 100ms,
+                                       animation_opacity_out linear 400ms 100ms;
+          animation: animation_opacity_in linear 100ms,
+                                       animation_opacity_out linear 400ms 100ms;
+}
+.ui-sub-tab ul {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  position: relative;
+  height: 100%;
+  white-space: nowrap;
+  font-size: 0;
+}
+.ui-sub-tab li {
+  text-align: center;
+  margin: auto 0;
+}
+.ui-sub-tab:not(.ui-sub-tab-static) ul li {
+  min-width: 105px;
+}
+.ui-sub-tab:not(.ui-sub-tab-static).ui-sub-tab-landscape ul li {
+  min-width: 135px;
+}
+.ui-main-tab {
+  display: none;
+  width: calc(100% -  32px);
+  height: 60px;
+  margin-left: 16px;
+  margin-right: 16px;
+  background-color: var(--bottom-bar-color);
+  position: fixed;
+  bottom: 0;
+}
+.ui-main-tab-visible {
+  display: block;
+}
+.ui-main-tab a {
+  font-family: Roboto-Regular;
+  font-size: 15px;
+  line-height: 22px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  position: relative;
+  left: 0;
+  top: 0;
+  height: 100%;
+  text-decoration: none;
+  color: var(--tab-text-color);
+  padding-left: 10px;
+  padding-right: 10px;
+}
+.ui-main-tab a > span,
+.ui-main-tab a > div {
+  position: relative;
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: flex-start;
+      -ms-flex-pack: start;
+          justify-content: flex-start;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  padding-bottom: 4px;
+  overflow: hidden;
+}
+.ui-main-tab a > span::before,
+.ui-main-tab a > div::before {
+  content: "";
+  position: absolute;
+  width: 100%;
+  height: 4px;
+  border-bottom: 2.5px dotted var(--primary-dark-color);
+  bottom: 0.75px;
+  box-sizing: border-box;
+  opacity: 0;
+}
+.ui-main-tab a.ui-tab-active {
+  color: var(--primary-dark-color);
+  font-family: Roboto-Medium;
+}
+.ui-main-tab a.ui-tab-active > span::before,
+.ui-main-tab a.ui-tab-active > div::before {
+  opacity: 1;
+}
+.ui-main-tab a:disabled {
+  color: var(--tab-text-color-dim);
+}
+.ui-main-tab a::before {
+  content: "";
+  width: 100%;
+  height: 43px;
+  top: 8.5px;
+  border-radius: 26px;
+  left: 0;
+  position: absolute;
+  opacity: 0;
+  background-color: var(--ripple-color);
+}
+.ui-main-tab a.ui-btn-active {
+  background-color: transparent;
+}
+.ui-main-tab a.ui-btn-active::before {
+  opacity: 1;
+}
+.ui-main-tab ul {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  position: relative;
+  height: 100%;
+  white-space: nowrap;
+  font-size: 0;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-main-tab li {
+  text-align: center;
+  display: block;
+  position: relative;
+  overflow: hidden;
+  height: 100%;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-main-tab .ui-li-active a::before {
+  opacity: 1;
+}
+.ui-main-tab .ui-tabs-badge {
+  position: absolute;
+  border-radius: 25px;
+  min-width: 12px;
+  background-color: var(--accent-badge);
+  color: var(--color-white);
+  top: 1px;
+  right: 7px;
+  text-align: center;
+  padding: 3.5px 7.5px;
+  font-family: Roboto-Medium;
+  font-size: 11px;
+}
+.ui-marquee-content::after {
+  content: attr(title);
+  text-indent: 75px;
+  position: absolute;
+  display: none;
+}
+.ui-marquee-content.ui-visible {
+  padding-right: 75px;
+}
+.ui-marquee-content.ui-visible::after {
+  display: inline;
+}
+.ui-footer {
+  padding: 0;
+  z-index: 100;
+}
+.ui-footer .ui-bottom-bar {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  min-height: 56px;
+  background-color: var(--bottom-bar-color);
+  padding: 0 24px;
+}
+.ui-footer .ui-bottom-bar .ui-btn {
+  font-family: Roboto-Medium;
+  font-size: 18px;
+  text-align: center;
+  line-height: 18px;
+  max-width: 100%;
+  height: 56px;
+}
+.ui-footer .ui-bottom-bar .ui-btn.ui-btn ~ .ui-btn {
+  margin-left: 0;
+}
+.ui-footer .ui-bottom-bar .ui-btn.ui-btn-icon {
+  font-family: Roboto-Regular;
+  font-size: 12px;
+  line-height: normal;
+  max-width: 100%;
+}
+.ui-footer .ui-bottom-bar .ui-btn.ui-btn-icon-top ~ .ui-btn-icon-top {
+  margin-left: 10px;
+}
+.ui-footer .ui-bottom-bar .ui-btn.ui-btn-text {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-footer .ui-bottom-bar.ui-bottom-bar-icons {
+  padding: 0 10px;
+}
+.ui-footer .ui-bottom-bar.ui-hidden {
+  display: none;
+}
+@media all and (min-width: 673px) and (min-height: 411px) {
+  .ui-footer .ui-bottom-bar {
+    margin: 0 auto;
+    width: 75%;
+    min-width: 625px;
+  }
+  .ui-footer .ui-bottom-bar.ui-bottom-bar-icons {
+    min-width: 653px;
+  }
+}
+.ui-tokentextarea {
+  display: table;
+  outline: none;
+  position: relative;
+  background-color: W010;
+  margin-left: -7.5px;
+  margin-right: -7.5px;
+}
+.ui-tokentextarea .ui-tokentextarea-input-area {
+  height: 26.5px;
+}
+.ui-tokentextarea .ui-tokentextarea-input-area .ui-text-line {
+  display: none;
+}
+.ui-scrollview-view > .ui-tokentextarea {
+  margin-left: -4px;
+  margin-right: -4px;
+}
+.ui-tokentextarea .ui-tokentextarea-label {
+  display: inline-block;
+  text-align: center;
+  position: relative;
+  margin-left: 6.5px;
+  margin-right: 3px;
+  padding: 11.5px 0;
+  color: T059L2;
+  font-size: 15px;
+}
+.ui-tokentextarea .ui-tokentextarea-input.ui-input-text {
+  height: 26.5px;
+  outline: none;
+  position: relative;
+  border: 0;
+  padding: 0;
+  color: T059L1;
+  background-color: W010;
+  text-align: left;
+  font-size: 15px;
+}
+.ui-tokentextarea-input-visible {
+  display: inline-block;
+}
+.ui-tokentextarea-input-invisible {
+  display: none;
+}
+.ui-tokentextarea div {
+  display: inline-block;
+  text-align: center;
+  cursor: pointer;
+  position: relative;
+  padding: .2em .5em;
+  font-size: 15px;
+  color: T020;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  margin: 4px 1px;
+}
+.ui-tokentextarea-block {
+  -webkit-mask-box-image-repeat: repeat;
+  -moz-mask-box-image-repeat: repeat;
+  -ms-mask-box-image-repeat: repeat;
+  -o-mask-box-image-repeat: repeat;
+  mask-box-image-repeat: repeat;
+  -webkit-mask-box-image-width: auto;
+  -moz-mask-box-image-width: auto;
+  -ms-mask-box-image-width: auto;
+  -o-mask-box-image-width: auto;
+  mask-box-image-width: auto;
+  -webkit-mask-box-image-source: url('images/nine-patch/core_button_bg.png');
+  -webkit-mask-box-image-slice: 37 38 36 38 fill;
+  -moz-mask-box-image-slice: 37 38 36 38 fill;
+  -ms-mask-box-image-slice: 37 38 36 38 fill;
+  -o-mask-box-image-slice: 37 38 36 38 fill;
+  mask-box-image-slice: 37 38 36 38 fill;
+  background-color: var(--button-background);
+  background-color: W012;
+  margin-left: 7.5px;
+  margin-top: 6px;
+}
+.ui-tokentextarea-sblock {
+  -webkit-mask-box-image-repeat: repeat;
+  -moz-mask-box-image-repeat: repeat;
+  -ms-mask-box-image-repeat: repeat;
+  -o-mask-box-image-repeat: repeat;
+  mask-box-image-repeat: repeat;
+  -webkit-mask-box-image-width: auto;
+  -moz-mask-box-image-width: auto;
+  -ms-mask-box-image-width: auto;
+  -o-mask-box-image-width: auto;
+  mask-box-image-width: auto;
+  -webkit-mask-box-image-source: url('images/nine-patch/core_button_bg.png');
+  -webkit-mask-box-image-slice: 37 38 36 38 fill;
+  -moz-mask-box-image-slice: 37 38 36 38 fill;
+  -ms-mask-box-image-slice: 37 38 36 38 fill;
+  -o-mask-box-image-slice: 37 38 36 38 fill;
+  mask-box-image-slice: 37 38 36 38 fill;
+  background-color: var(--on-background);
+  background-color: W012P;
+  color: T020;
+  margin-left: 7.5px;
+  margin-top: 6px;
+}
+.ui-tokentextarea .ui-tokentextarea-desclabel {
+  display: inline-block;
+  outline: none;
+  position: relative;
+  border: 0;
+  color: T059L2;
+  text-align: left;
+  font-size: 15px;
+  margin-left: 1.5px;
+}
+.ui-tokentextarea-link-base {
+  position: absolute;
+  right: 0;
+  bottom: 2px;
+  margin-right: 4.5px;
+}
+.ui-triangle-container {
+  position: relative;
+}
+.ui-triangle-container .ui-triangle {
+  position: absolute;
+  border-style: solid;
+  border-color: transparent;
+  border-width: 10;
+}
+.ui-triangle-container .ui-triangle-top {
+  top: 0;
+  border-top-width: 0;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  margin-left: -10;
+}
+.ui-triangle-container .ui-triangle-bottom {
+  bottom: 0;
+  border-bottom-width: 0;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  margin-left: -10;
+}
+.ui-triangle-container .ui-triangle-left {
+  left: 0;
+  margin-top: -10;
+  border-left-width: 0;
+  border-left-color: transparent;
+  border-right-color: transparent;
+}
+.ui-triangle-container .ui-triangle-right {
+  right: 0;
+  margin-top: -10;
+  border-right-width: 0;
+  border-left-color: transparent;
+  border-right-color: transparent;
+}
+.ui-triangle-container-top {
+  height: 10;
+  top: 0;
+  margin-top: -10;
+}
+.ui-triangle-container-bottom {
+  height: 10;
+  bottom: 0;
+  margin-bottom: -10;
+}
+.ui-triangle-container-left {
+  width: 10;
+}
+.ui-triangle-container-right {
+  width: 10;
+}
+.ui-virtualgrid {
+  overflow: hidden;
+  position: absolute;
+}
+.ui-virtualgrid-wrapblock {
+  position: absolute;
+  left: 0;
+}
+.ui-virtualgrid-wrapblock-x {
+  float: left;
+  overflow: hidden;
+}
+.ui-virtualgrid-wrapblock-y {
+  float: left;
+  overflow: hidden;
+}
+.ui-scrollbar-thumb-x {
+  width: 1.5rem !important;
+}
+.ui-scrollbar-thumb-y {
+  height: 1.5rem !important;
+}
+.ui-virtualgrid-overflow-indicator-x-top {
+  position: absolute;
+  display: block;
+  left: 0;
+  top: 0;
+  width: 56%;
+  height: 100%;
+  opacity: 0;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  background-image: url('images/00_grid_overscrolling_left.png');
+  pointer-events: none;
+}
+.ui-virtualgrid-overflow-indicator-x-bottom {
+  position: absolute;
+  display: block;
+  right: 0;
+  bottom: 0;
+  width: 56%;
+  height: 100%;
+  opacity: 0;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  background-image: url('images/00_grid_overscrolling_right.png');
+  pointer-events: none;
+}
+.ui-virtualgrid-overflow-indicator-y-top {
+  position: absolute;
+  display: block;
+  top: 0;
+  width: 100%;
+  height: 32%;
+  opacity: 0;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  background-image: url('images/00_grid_overscrolling_top.png');
+  pointer-events: none;
+}
+.ui-virtualgrid-overflow-indicator-y-bottom {
+  position: absolute;
+  display: block;
+  bottom: 0;
+  width: 100%;
+  height: 32%;
+  opacity: 0;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  background-image: url(images/00_grid_overscrolling_bottom.png);
+  pointer-events: none;
+}
+.ui-content.ui-virtualgrid-content {
+  padding: 0;
+}
+.ui-virtualgrid {
+  margin: 4px -4px 0 0;
+}
+.ui-virtualgrid .ui-li-static {
+  padding: 0;
+  border: none;
+  width: 100%;
+}
+.ui-virtualgrid .grid-icon {
+  width: 26.25px;
+  margin: 0 4px 4px 0;
+  display: block;
+  overflow: hidden;
+}
+.ui-virtualgrid .grid-icon.ui-btn-icon-top .ui-btn-inner.ui-btn-hastxt {
+  padding-top: 15.75px;
+}
+.ui-virtualgrid .grid-icon.ui-btn .ui-icon {
+  width: 106px;
+  height: 106px;
+  -webkit-mask-size: 106px 106px;
+  -moz-mask-size: 106px 106px;
+  -ms-mask-size: 106px 106px;
+  -o-mask-size: 106px 106px;
+  mask-size: 106px 106px;
+  margin-left: -53px;
+  background-size: 106px 106px;
+}
+.ui-virtualgrid .grid-icon:not(.ui-focus) {
+  background-color: #1b403d;
+}
+.ui-virtualgrid .grid-thumbnail {
+  width: 38px;
+  margin: 0 4px 4px 0;
+  display: block;
+  overflow: hidden;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn .ui-btn-inner {
+  margin: 0;
+  padding: 0;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn .ui-btn-inner .ui-btn-text {
+  display: block;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-info {
+  left: 2.625px;
+  right: 2.625px;
+  top: 1px;
+  position: absolute;
+  color: #c8c8c8;
+  font-size: 2.75px;
+  text-align: right;
+  z-index: 3;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic {
+  z-index: 2;
+  width: 38px;
+  height: 38px;
+  overflow: hidden;
+  background-color: #1a465f;
+  position: relative;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic img {
+  width: 25px;
+  height: 25px;
+  position: absolute;
+  top: 19px;
+  left: 19px;
+  margin: -12.5px;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic-full {
+  width: 38px;
+  height: 38px;
+  overflow: hidden;
+  position: relative;
+  z-index: 2;
+  box-sizing: border-box;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic-full img {
+  width: 38px;
+  height: 38px;
+  position: absolute;
+  top: 19px;
+  left: 19px;
+  margin: -19px;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents {
+  background: #21240d;
+  padding: 1.875px 2.5px;
+  font-size: 6.5px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  color: #d3d3d3;
+  z-index: 2;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents .grid-thumbnail-content {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  height: 3.875px;
+  line-height: 6.5px;
+  min-height: 6.5px;
+  display: block;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents .grid-thumbnail-subtext {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  color: #808080;
+  font-size: 2.75px;
+  margin-top: -0.75px;
+  display: block;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic {
+  border: solid #458fff;
+  border-top-width: 1px;
+  border-left-width: 1px;
+  border-right-width: 1px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic img {
+  top: 18px;
+  left: 18px;
+  margin: -12.5px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic-full {
+  border: solid #458fff;
+  border-top-width: 1px;
+  border-left-width: 1px;
+  border-right-width: 1px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic-full img {
+  top: 18px;
+  left: 18px;
+  margin: -19px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents {
+  background: #458fff;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents .grid-thumbnail-content,
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents .grid-thumbnail-subtext {
+  color: #ffffff;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-selected .ui-btn-inner {
+  border: solid #ffa955 1.25px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-selected .ui-btn-text {
+  margin: -1.25px;
+}
+.ui-mobile-viewport-transitioning,
+.ui-mobile-viewport-transitioning .ui-page {
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+}
+.in {
+  -webkit-animation-timing-function: ease-out;
+          animation-timing-function: ease-out;
+  -webkit-animation-duration: 350ms;
+          animation-duration: 350ms;
+}
+.out {
+  -webkit-animation-timing-function: ease-in;
+          animation-timing-function: ease-in;
+  -webkit-animation-duration: 225ms;
+          animation-duration: 225ms;
+}
+@-webkit-keyframes fadein {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@keyframes fadein {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes fadeout {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+@keyframes fadeout {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+.fade.out {
+  opacity: 0;
+  -webkit-animation-duration: 125ms;
+          animation-duration: 125ms;
+  -webkit-animation-name: fadeout;
+          animation-name: fadeout;
+}
+.fade.in {
+  opacity: 1;
+  -webkit-animation-duration: 225ms;
+          animation-duration: 225ms;
+  -webkit-animation-name: fadein;
+          animation-name: fadein;
+}
+.viewport-flip {
+  position: absolute;
+  -webkit-perspective: 1000;
+  -ms-perspective: 1000;
+  -o-perspective: 1000;
+  perspective: 1000;
+}
+.flip {
+  backface-visiblity: hidden;
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+}
+.flip.out {
+  -webkit-transform: rotateY(-90 def) scale(0.9);
+          transform: rotateY(-90 def) scale(0.9);
+  -webkit-animation-name: flipouttoleft;
+          animation-name: flipouttoleft;
+  -webkit-animation-duration: 175ms;
+          animation-duration: 175ms;
+}
+.flip.out.ui-ctxpopup-container {
+  border: 2px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+}
+.flip.in {
+  -webkit-animation-name: flipintoright;
+          animation-name: flipintoright;
+  -webkit-animation-duration: 225ms;
+          animation-duration: 225ms;
+}
+.flip.in.ui-ctxpopup-container {
+  border: 2px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+}
+.ui-popup.flip.out,
+.flip.out.reverse {
+  -webkit-transform: rotateY(90deg) scale(0.9);
+          transform: rotateY(90deg) scale(0.9);
+  -webkit-animation-name: flipouttoright;
+          animation-name: flipouttoright;
+}
+.flip.in.reverse {
+  -webkit-animation-name: flipintoleft;
+          animation-name: flipintoleft;
+}
+@-webkit-keyframes flipouttoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipouttoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@-webkit-keyframes flipouttoright {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+}
+@keyframes flipouttoright {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+}
+@-webkit-keyframes flipintoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipintoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@-webkit-keyframes flipintoright {
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipintoright {
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+.flow {
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.4);
+  -webkit-transform-origin: 50% 50%;
+      -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+}
+.ui-dialog.flow {
+  box-shadow: none;
+}
+.flow.out {
+  -webkit-animation: flowouttoleft ease 350ms;
+          animation: flowouttoleft ease 350ms;
+  -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+          transform: translate3d(-100%, 0, 0) scale(0.7);
+}
+.flow.in {
+  -webkit-animation: flowinfromright ease 350ms;
+          animation: flowinfromright ease 350ms;
+  -webkit-transform: translate3d(0, 0, 0) scale(1);
+          transform: translate3d(0, 0, 0) scale(1);
+}
+.ui-popup.flow.out,
+.flow.out.reverse {
+  -webkit-transform: translate3d(100%, 0, 0);
+  -ms-transform: translate3d(100%, 0, 0);
+  transform: translate3d(100%, 0, 0);
+  -webkit-animation-name: flowouttoright;
+          animation-name: flowouttoright;
+}
+.flow.in.reverse {
+  -webkit-animation-name: flowinfromleft;
+          animation-name: flowinfromleft;
+}
+@-webkit-keyframes flowouttoleft {
+  0% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+  60%,
+  70% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+            transform: translate3d(-100%, 0, 0) scale(0.7);
+  }
+}
+@keyframes flowouttoleft {
+  0% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+  60%,
+  70% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+            transform: translate3d(-100%, 0, 0) scale(0.7);
+  }
+}
+@-webkit-keyframes flowouttoright {
+  0% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+  60%,
+  70% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(100%, 0, 0) scale(0.7);
+            transform: translate3d(100%, 0, 0) scale(0.7);
+  }
+}
+@keyframes flowouttoright {
+  0% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+  60%,
+  70% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(100%, 0, 0) scale(0.7);
+            transform: translate3d(100%, 0, 0) scale(0.7);
+  }
+}
+@-webkit-keyframes flowinfromleft {
+  0% {
+    -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+            transform: translate3d(-100%, 0, 0) scale(0.7);
+  }
+  30%,
+  40% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+}
+@keyframes flowinfromleft {
+  0% {
+    -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+            transform: translate3d(-100%, 0, 0) scale(0.7);
+  }
+  30%,
+  40% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+}
+@-webkit-keyframes flowinfromright {
+  0% {
+    -webkit-transform: translate3d(100%, 0, 0) scale(0.7);
+            transform: translate3d(100%, 0, 0) scale(0.7);
+  }
+  30%,
+  40% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+}
+@keyframes flowinfromright {
+  0% {
+    -webkit-transform: translate3d(100%, 0, 0) scale(0.7);
+            transform: translate3d(100%, 0, 0) scale(0.7);
+  }
+  30%,
+  40% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+}
+.pop {
+  -webkit-transform-origin: 50% 50%;
+      -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+}
+.pop.in {
+  -webkit-transform: scale(1);
+  -ms-transform: scale(1);
+  transform: scale(1);
+  opacity: 1;
+  -webkit-animation: popin 350ms;
+          animation: popin 350ms;
+}
+.pop.in.ui-ctxpopup-container {
+  border: 2px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+}
+.pop.out {
+  -webkit-animation: fadeout 100ms;
+          animation: fadeout 100ms;
+}
+.pop.out.ui-ctxpopup-container {
+  border: 2px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+}
+.pop.in.reverse {
+  -webkit-animation-name: fadein;
+          animation-name: fadein;
+}
+.ui-popup.pop.out,
+.pop.out.reverse {
+  -webkit-transform: scale(0.8);
+  -ms-transform: scale(0.8);
+  transform: scale(0.8);
+  -webkit-animation-name: popout;
+          animation-name: popout;
+}
+@-webkit-keyframes popin {
+  from {
+    -webkit-transform: scale(0.8);
+    -ms-transform: scale(0.8);
+    transform: scale(0.8);
+    opacity: 0;
+  }
+  to {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@keyframes popin {
+  from {
+    -webkit-transform: scale(0.8);
+    -ms-transform: scale(0.8);
+    transform: scale(0.8);
+    opacity: 0;
+  }
+  to {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@-webkit-keyframes popout {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0.8);
+    -ms-transform: scale(0.8);
+    transform: scale(0.8);
+    opacity: 0;
+  }
+}
+@keyframes popout {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0.8);
+    -ms-transform: scale(0.8);
+    transform: scale(0.8);
+    opacity: 0;
+  }
+}
+.slide.out,
+.slide.in {
+  -webkit-animation-timing-function: ease-out;
+          animation-timing-function: ease-out;
+  -webkit-animation-duration: 350ms;
+          animation-duration: 350ms;
+}
+.slide.out {
+  -webkit-transform: translate3d(-100%, 0, 0);
+  -ms-transform: translate3d(-100%, 0, 0);
+  transform: translate3d(-100%, 0, 0);
+  -webkit-animation-name: slideouttoleft;
+          animation-name: slideouttoleft;
+}
+.slide.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation-name: slideinfromright;
+          animation-name: slideinfromright;
+}
+.ui-popup.slide.out,
+.slide.out.reverse {
+  -webkit-transform: translate3d(100%, 0, 0);
+  -ms-transform: translate3d(100%, 0, 0);
+  transform: translate3d(100%, 0, 0);
+  -webkit-animation-name: slideouttoright;
+          animation-name: slideouttoright;
+}
+.slide.in.reverse {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation-name: slideinfromleft;
+          animation-name: slideinfromleft;
+}
+@-webkit-keyframes slideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes slideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes slideinfromleft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes slideinfromleft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes slideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+@keyframes slideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+@-webkit-keyframes slideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@keyframes slideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+.slidedown.out {
+  -webkit-animation: fadeout 100ms;
+          animation: fadeout 100ms;
+}
+.slidedown.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: slideinfromtop 250ms;
+          animation: slideinfromtop 250ms;
+}
+.slidedown.in.reverse {
+  -webkit-animation: fade 150ms;
+          animation: fade 150ms;
+}
+.ui-popup.slidedown.out,
+.slidedown.out.reverse {
+  -webkit-transform: translate3d(0, -100%, 0);
+  -ms-transform: translate3d(0, -100%, 0);
+  transform: translate3d(0, -100%, 0);
+  -webkit-animation: slideouttotop 200ms;
+          animation: slideouttotop 200ms;
+}
+@-webkit-keyframes slideinfromtop {
+  from {
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes slideinfromtop {
+  from {
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes slideouttotop {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+@keyframes slideouttotop {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+.slideupfade.out {
+  -webkit-animation: fadeout 100ms;
+          animation: fadeout 100ms;
+}
+.slideupfade.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: slideupfadeinfrombottom 250ms;
+          animation: slideupfadeinfrombottom 250ms;
+}
+.slideupfade.in.reverse {
+  -webkit-animation: fadein 150ms;
+          animation: fadein 150ms;
+}
+.ui-popup.slideupfade.out,
+.slideupfade.out.reverse {
+  -webkit-transform: translate3d(0, 5%, 0);
+  -ms-transform: translate3d(0, 5%, 0);
+  transform: translate3d(0, 5%, 0);
+  -webkit-animation: slideupfadeouttobottom 200ms;
+          animation: slideupfadeouttobottom 200ms;
+}
+@-webkit-keyframes slideupfadeinfrombottom {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 5%, 0);
+    -ms-transform: translate3d(0, 5%, 0);
+    transform: translate3d(0, 5%, 0);
+  }
+  to {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes slideupfadeinfrombottom {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 5%, 0);
+    -ms-transform: translate3d(0, 5%, 0);
+    transform: translate3d(0, 5%, 0);
+  }
+  to {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes slideupfadeouttobottom {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 5%, 0);
+    -ms-transform: translate3d(0, 5%, 0);
+    transform: translate3d(0, 5%, 0);
+  }
+}
+@keyframes slideupfadeouttobottom {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 5%, 0);
+    -ms-transform: translate3d(0, 5%, 0);
+    transform: translate3d(0, 5%, 0);
+  }
+}
+.slidedownfade.out {
+  -webkit-animation: fadeout 100ms;
+          animation: fadeout 100ms;
+}
+.slidedownfade.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: slidedownfadeinfromtop 250ms;
+          animation: slidedownfadeinfromtop 250ms;
+}
+.slidedownfade.in.reverse {
+  -webkit-animation: fadein 150ms;
+          animation: fadein 150ms;
+}
+.ui-popup.slidedownfade.out,
+.slidedownfade.out.reverse {
+  -webkit-transform: translate3d(0, -5%, 0);
+  -ms-transform: translate3d(0, -5%, 0);
+  transform: translate3d(0, -5%, 0);
+  -webkit-animation: slidedownfadeouttotop 200ms;
+          animation: slidedownfadeouttotop 200ms;
+}
+@-webkit-keyframes slidedownfadeinfromtop {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -5%, 0);
+    -ms-transform: translate3d(0, -5%, 0);
+    transform: translate3d(0, -5%, 0);
+  }
+}
+@keyframes slidedownfadeinfromtop {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -5%, 0);
+    -ms-transform: translate3d(0, -5%, 0);
+    transform: translate3d(0, -5%, 0);
+  }
+}
+@-webkit-keyframes slidedownfadeouttotop {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -5%, 0);
+    -ms-transform: translate3d(0, -5%, 0);
+    transform: translate3d(0, -5%, 0);
+  }
+}
+@keyframes slidedownfadeouttotop {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -5%, 0);
+    -ms-transform: translate3d(0, -5%, 0);
+    transform: translate3d(0, -5%, 0);
+  }
+}
+.slidefade.out {
+  -webkit-transform: translate3d(-100%, 0, 0);
+  -ms-transform: translate3d(-100%, 0, 0);
+  transform: translate3d(-100%, 0, 0);
+  -webkit-animation: slideouttoleft 225ms;
+          animation: slideouttoleft 225ms;
+}
+.slidefade.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: fadein 200ms;
+          animation: fadein 200ms;
+}
+.ui-popup.slidefade.out,
+.slidefade.out.reverse {
+  -webkit-transform: translate3d(100%, 0, 0);
+  -ms-transform: translate3d(100%, 0, 0);
+  transform: translate3d(100%, 0, 0);
+  -webkit-animation: slideouttoright 200ms;
+          animation: slideouttoright 200ms;
+}
+.slidefade.in.reverse {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: fadein 200ms;
+          animation: fadein 200ms;
+}
+.viewport-turn {
+  -webkit-perspective: 1000;
+  -ms-perspective: 1000;
+  -o-perspective: 1000;
+  perspective: 1000;
+  position: absolute;
+}
+.turn {
+  backface-visiblity: hidden;
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+}
+.turn.out {
+  -webkit-transform: rotateY(-90deg) scale(0.9);
+          transform: rotateY(-90deg) scale(0.9);
+  -webkit-animation: flipouttoleft 125ms;
+          animation: flipouttoleft 125ms;
+}
+.turn.in {
+  -webkit-animation: flipintoright 250ms;
+          animation: flipintoright 250ms;
+}
+.ui-popup.turn.out,
+.turn.out.reverse {
+  -webkit-transform: rotateY(90deg) scale(0.9);
+          transform: rotateY(90deg) scale(0.9);
+  -webkit-animation-name: flipouttoright;
+          animation-name: flipouttoright;
+}
+.turn.in.reverse {
+  -webkit-animation-name: flipintoleft;
+          animation-name: flipintoleft;
+}
+@-webkit-keyframes flipouttoleft {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+}
+@keyframes flipouttoleft {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+}
+@-webkit-keyframes flipouttoright {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+}
+@keyframes flipouttoright {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+}
+@-webkit-keyframes flipintoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipintoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@-webkit-keyframes flipintoright {
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipintoright {
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+.depth {
+  -webkit-transform-origin: 50% 50%;
+      -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+}
+.depth.out {
+  opacity: 0;
+  -webkit-animation: depthout 250ms ease;
+          animation: depthout 250ms ease;
+}
+.depth.in {
+  -webkit-transform: scale(1);
+  -ms-transform: scale(1);
+  transform: scale(1);
+  opacity: 1;
+  -webkit-animation: depthin 350ms ease;
+          animation: depthin 350ms ease;
+}
+.depth.in.reverse {
+  -webkit-animation-name: depthinreverse;
+          animation-name: depthinreverse;
+}
+.ui-popup.depth.out,
+.depth.out.reverse {
+  -webkit-transform: scale(0.9);
+  -ms-transform: scale(0.9);
+  transform: scale(0.9);
+  -webkit-animation-name: depthoutreverse;
+          animation-name: depthoutreverse;
+}
+@-webkit-keyframes depthout {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+}
+@keyframes depthout {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+}
+@-webkit-keyframes depthin {
+  0% {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+  30% {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@keyframes depthin {
+  0% {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+  30% {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@-webkit-keyframes depthinreverse {
+  0% {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+  30% {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@keyframes depthinreverse {
+  0% {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+  30% {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@-webkit-keyframes depthoutreverse {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+}
+@keyframes depthoutreverse {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+}
+.ui-mobile-viewport-transitioning,
+.ui-mobile-viewport-transitioning .ui-page {
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+}
+/* slide */
+.ui-page.slide.out,
+.ui-page.slide.in {
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
+  -webkit-animation-duration: 400ms;
+  animation-duration: 400ms;
+}
+.ui-page.slide.out {
+  -webkit-animation-name: pageslideouttoleft;
+  animation-name: pageslideouttoleft;
+}
+.ui-page.slide.in {
+  -webkit-animation-name: pageslideinfromright;
+  animation-name: pageslideinfromright;
+}
+.ui-page.slide.out.reverse {
+  -webkit-animation-name: pageslideouttoright;
+  animation-name: pageslideouttoright;
+  z-index: 2000;
+}
+.ui-page.slide.in.reverse {
+  -webkit-animation-name: pageslideinfromleft;
+  animation-name: pageslideinfromleft;
+}
+.ui-page.slide.in.reverse::after,
+.ui-page.slide.out:not(.reverse)::after {
+  content: "";
+  background-image: url("images/page/core_theme_bg_01.png");
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 2000;
+  opacity: 0;
+}
+.ui-page.slide.in.reverse::after {
+  -webkit-animation: pagebgslideinreverse 400ms ease-out;
+  animation: pagebgslideinreverse 400ms ease-out;
+}
+.ui-page.slide.out:not(.reverse)::after {
+  -webkit-animation: pagebgslideout 400ms ease-out;
+  animation: pagebgslideout 400ms ease-out;
+}
+@-webkit-keyframes pageslideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-25%, 0, 0);
+    -ms-transform: translate3d(-25%, 0, 0);
+    transform: translate3d(-25%, 0, 0);
+  }
+}
+@keyframes pageslideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-25%, 0, 0);
+    -ms-transform: translate3d(-25%, 0, 0);
+    transform: translate3d(-25%, 0, 0);
+  }
+}
+@-webkit-keyframes pageslideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes pageslideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes pageslideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@keyframes pageslideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@-webkit-keyframes pageslideinfromleft {
+  from {
+    -webkit-transform: translate3d(-25%, 0, 0);
+    -ms-transform: translate3d(-25%, 0, 0);
+    transform: translate3d(-25%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes pageslideinfromleft {
+  from {
+    -webkit-transform: translate3d(-25%, 0, 0);
+    -ms-transform: translate3d(-25%, 0, 0);
+    transform: translate3d(-25%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes pagebgslideinreverse {
+  from {
+    opacity: .5;
+  }
+  to {
+    opacity: 0;
+  }
+}
+@keyframes pagebgslideinreverse {
+  from {
+    opacity: .5;
+  }
+  to {
+    opacity: 0;
+  }
+}
+@-webkit-keyframes pagebgslideout {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: .5;
+  }
+}
+@keyframes pagebgslideout {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: .5;
+  }
+}
+/* slide up */
+.ui-page.slideup.out {
+  -webkit-animation-name: fadeout;
+  animation-name: fadeout;
+  -webkit-animation-duration: 250ms;
+  animation-duration: 250ms;
+}
+.ui-page.slideup.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation-name: pageslideinfrombottom;
+  animation-name: pageslideinfrombottom;
+  -webkit-animation-duration: 200ms;
+  animation-duration: 200ms;
+}
+.ui-page.slideup.in.reverse {
+  -webkit-animation-name: fadein;
+  animation-name: fadein;
+  -webkit-animation-duration: 250ms;
+  animation-duration: 250ms;
+}
+.ui-page.slideup.out.reverse {
+  -webkit-transform: translate3d(0, 100%, 0);
+  -ms-transform: translate3d(0, 100%, 0);
+  transform: translate3d(0, 100%, 0);
+  -webkit-animation-name: pageslideouttobottom;
+  animation-name: pageslideouttobottom;
+  -webkit-animation-duration: 200ms;
+  animation-duration: 200ms;
+}
+@-webkit-keyframes pageslideinfrombottom {
+  from {
+    -webkit-transform: translate3d(0, 100%, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes pageslideouttobottom {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 100%, 0);
+  }
+}
+/*** less definitions ***/
+ul.ui-virtual-list-container > ul.position_absolute {
+  position: absolute;
+}
+.ui-listview.ui-virtual-list-container .ui-li {
+  position: relative;
+}
+.ui-virtual-list-edge-effect {
+  pointer-events: none;
+  width: 100%;
+  height: 0;
+  position: absolute;
+  top: 0;
+  left: 0;
+  box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
+}
+.ui-virtual-list-edge-effect.orientation-horizontal {
+  height: 100%;
+  width: 0;
+}
+.ui-grid-a,
+.ui-grid-b,
+.ui-grid-c,
+.ui-grid-d {
+  overflow: hidden;
+}
+.ui-block-a,
+.ui-block-b,
+.ui-block-c,
+.ui-block-d,
+.ui-block-e {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  float: left;
+  min-height: 1px;
+}
+.ui-grid-solo .ui-block-a {
+  width: 100%;
+  float: none;
+}
+.ui-grid-a .ui-block-a,
+.ui-grid-a .ui-block-b {
+  width: 50%;
+}
+.ui-grid-a .ui-block-a {
+  clear: left;
+}
+.ui-grid-b .ui-block-a,
+.ui-grid-b .ui-block-b,
+.ui-grid-b .ui-block-c {
+  width: 33.333%;
+}
+.ui-grid-b .ui-block-a {
+  clear: left;
+}
+.ui-grid-c .ui-block-a,
+.ui-grid-c .ui-block-b,
+.ui-grid-c .ui-block-c,
+.ui-grid-c .ui-block-d {
+  width: 25%;
+}
+.ui-grid-c .ui-block-a {
+  clear: left;
+}
+.ui-grid-d .ui-block-a,
+.ui-grid-d .ui-block-b,
+.ui-grid-d .ui-block-c,
+.ui-grid-d .ui-block-d,
+.ui-grid-d .ui-block-e {
+  width: 20%;
+}
+.ui-grid-d .ui-block-a {
+  clear: left;
+}
+.ui-navbar {
+  overflow: hidden;
+}
+.ui-navbar ul,
+.ui-navbar-expanded ul {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+  position: relative;
+  display: block;
+  border: 0;
+}
+.ui-navbar-collapsed ul {
+  float: left;
+  width: 75%;
+  margin-right: -2px;
+}
+.ui-navbar-collapsed .ui-navbar-toggle {
+  float: left;
+  width: 25%;
+}
+.ui-navbar .ui-navbar-truncate {
+  position: absolute;
+  left: -9999px;
+  top: -9999px;
+}
+.ui-navbar li .ui-btn,
+.ui-navbar .ui-navbar-toggle .ui-btn {
+  display: block;
+  text-align: center;
+  margin: 0;
+  border-right-width: 0;
+}
+.ui-navbar li .ui-btn {
+  margin-right: -1px;
+}
+.ui-navbar li .ui-btn:last-child {
+  margin-right: 0;
+}
+.ui-header .ui-navbar .ui-btn,
+.ui-footer .ui-navbar .ui-btn {
+  border-top-width: 0;
+}
+.ui-navbar .ui-btn-inner {
+  padding-left: 2px;
+  padding-right: 2px;
+}
+.ui-navbar-noicons .ui-btn-inner {
+  padding-top: .8em;
+  padding-bottom: .9em;
+}
+.ui-navbar-expanded .ui-btn {
+  margin: 0;
+  font-size: 14px;
+}
+.ui-navbar-expanded .ui-btn-inner {
+  padding-left: 5px;
+  padding-right: 5px;
+}
+.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner {
+  padding: 45px 5px 15px;
+  text-align: center;
+}
+.ui-navbar-expanded .ui-btn-icon-top .ui-icon {
+  top: 15px;
+}
+.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner {
+  padding: 15px 5px 45px;
+  text-align: center;
+}
+.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon {
+  bottom: 15px;
+}
+.ui-navbar-expanded .ui-btn-inner {
+  min-height: 2.5em;
+}
+.ui-navbar-expanded .ui-navbar-noicons .ui-btn-inner {
+  padding-top: 1.8em;
+  padding-bottom: 1.9em;
+}
+.ui-select {
+  display: block;
+  position: relative;
+}
+.ui-select select {
+  position: absolute;
+  left: -9999px;
+  top: -9999px;
+}
+.ui-select .ui-btn {
+  overflow: hidden;
+}
+.ui-select .ui-btn select {
+  cursor: pointer;
+  -webkit-appearance: button;
+  left: 0;
+  top: 0;
+  width: 100%;
+  min-height: 100%;
+  height: 3em;
+  max-height: 100%;
+  opacity: 0;
+  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
+  filter: alpha(opacity=0);
+  z-index: 2;
+}
+.ui-select .ui-btn select.ui-select-nativeonly {
+  opacity: 1;
+  text-indent: 0;
+}
+.ui-select .ui-btn-icon-right .ui-btn-inner {
+  padding-right: 45px;
+}
+.ui-select .ui-btn-icon-right .ui-icon {
+  right: 15px;
+}
+label.ui-select {
+  font-size: 16px;
+  line-height: 1.4;
+  font-weight: normal;
+  margin: 0 0 .3em;
+  display: block;
+}
+.ui-select .ui-btn-text,
+.ui-selectmenu .ui-btn-text {
+  display: block;
+  min-height: 1em;
+}
+.ui-select .ui-btn-text {
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+.ui-selectmenu .ui-listview {
+  margin: 0;
+}
+.ui-selectmenu .ui-btn.ui-li-divider {
+  cursor: default;
+}
+.ui-selectmenu-hidden {
+  top: -9999px;
+  left: -9999px;
+  visibility: hidden;
+}
+.ui-selectmenu-screen {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 99;
+}
+.ui-selectmenu-list .ui-li .ui-icon {
+  display: none;
+}
+.ui-selectmenu-list .ui-li .ui-icon {
+  display: block;
+}
+.ui-li.ui-selectmenu-placeholder {
+  display: none;
+}
+.ui-selectmenu .ui-header .ui-title {
+  margin: .6em 46px .8em;
+}
+@media all and (min-width: 450px) {
+  label.ui-select {
+    vertical-align: top;
+    display: inline-block;
+    width: 20%;
+    margin: 0 2% 0 0;
+  }
+  .ui-select {
+    width: 60%;
+    display: inline-block;
+  }
+}
+.ui-selectmenu .ui-header h1::after {
+  content: '.';
+  visibility: hidden;
+}
+.ui-selectmenu .ui-header .ui-btn-icon_only .ui-btn-text {
+  position: absolute;
+  left: -9999px;
+}
+.ui-selectmenu .ui-header .ui-btn-icon_only .ui-icon {
+  margin: auto;
+}
+.ui-page.ui-empty-state .ui-header {
+  background-color: var(--background-color);
+}
+.ui-page.ui-empty-state .ui-content {
+  position: relative;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  height: 100%;
+  background-color: var(--background-color);
+}
+.ui-page.ui-empty-state .ui-content::before {
+  content: '';
+  display: block;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  -webkit-mask-image: url('images/00_page_empty_bg.png');
+          mask-image: url('images/00_page_empty_bg.png');
+  -webkit-mask-size: 100% auto;
+          mask-size: 100% auto;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  background-color: var(--background-color);
+}
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view {
+  padding-left: 16px;
+  padding-right: 16px;
+  text-align: center;
+  font-size: 16px;
+  color: var(--text-color);
+  line-height: 21.5px;
+  min-height: 286px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h1,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h2,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h3,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h4,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h5,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h6 {
+  margin: 0;
+  margin-bottom: 27px;
+  line-height: 27px;
+  font-size: 20px;
+  font-weight: lighter;
+  color: T0222L1;
+}
+@media only screen and (orientation: landscape) {
+  .ui-page.ui-empty-state .ui-content:before {
+    -webkit-mask-image: url('images/00_page_empty_bg_h.png');
+            mask-image: url('images/00_page_empty_bg_h.png');
+    -webkit-mask-size: 100% 100px;
+            mask-size: 100% 100px;
+  }
+}
+.ui-listview.ui-listview-empty-state-show {
+  height: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-listview.ui-listview-empty-state-show .ui-li-empty-state {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-listview.ui-listview-empty-state-show .ui-li-static {
+  height: 27px;
+}
+.ui-listview .ui-li-empty-state {
+  width: 100%;
+  display: none;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  position: relative;
+  -webkit-align-content: center;
+      -ms-flex-line-pack: center;
+          align-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  box-sizing: border-box;
+  padding: 0 0 42px 0;
+}
+.ui-empty-state-content {
+  pointer-events: none;
+  padding-left: 16px;
+  padding-right: 16px;
+  text-align: center;
+  font-size: 16px;
+  color: T0222L4;
+  line-height: 21.5px;
+  height: 286px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-empty-state-content h1,
+.ui-empty-state-content h2,
+.ui-empty-state-content h3,
+.ui-empty-state-content h4,
+.ui-empty-state-content h5,
+.ui-empty-state-content h6 {
+  margin: 0;
+  margin-bottom: 27px;
+  line-height: 27px;
+  font-size: 20px;
+  font-weight: lighter;
+  color: T0222L3;
+}
+.ui-page-floatingactions .ui-listview .ui-li-empty-state {
+  padding: 0 0 94px 0;
+}
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+  appearance: none;
+}
+input[type="search"][disabled] {
+  background-color: transparent;
+}
+.ui-search-input {
+  font-size: 20px;
+  overflow: hidden;
+  background-color: transparent;
+  text-shadow: 0 0 0 var(--text-color);
+  color: var(--text-input-inactive);
+  -webkit-text-fill-color: transparent;
+}
+.ui-search-input:focus {
+  text-shadow: 0 0 0 var(--text-color);
+  border-color: var(--text-input-underline-active);
+}
+.ui-search-input.ui-state-disabled {
+  text-shadow: 0 0 0 var(--text-input-disabled);
+  border-bottom: 2px solid var(--text-input-disabled);
+}
+.ui-search-input.ui-state-disabled::-webkit-input-placeholder {
+  color: var(--text-input-label-inactive);
+  text-shadow: none;
+  -webkit-text-fill-color: initial;
+}
+.ui-header-searchbar {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  padding: 0 8.5px 0 5px;
+  box-sizing: border-box;
+  overflow: initial;
+}
+.ui-header-searchbar > .ui-search-input,
+.ui-header-searchbar > input {
+  border: 0;
+  outline: 0;
+  overflow: hidden;
+  border-bottom: 1px solid;
+  border-bottom-color: var(--text-input-underline-active);
+  font-size: 20px;
+  color: var(--primary-color);
+  background-color: transparent;
+  -webkit-text-fill-color: transparent;
+  height: 40px;
+  text-shadow: 0 0 0 var(--text-color);
+  box-sizing: border-box;
+  -webkit-flex-grow: 1;
+      -ms-flex-positive: 1;
+          flex-grow: 1;
+  padding: 2px 5px 0 5px;
+  margin-right: 7.5px;
+}
+.ui-header-searchbar > .ui-search-input.ui-text-input-clear-active:focus,
+.ui-header-searchbar > input.ui-text-input-clear-active:focus,
+.ui-header-searchbar > .ui-search-input.ui-text-input-clear-active:active,
+.ui-header-searchbar > input.ui-text-input-clear-active:active {
+  text-shadow: 0 0 0 var(--text-color);
+  padding: 2px 41px 0 5px;
+}
+.ui-header-searchbar > .ui-search-input[disabled],
+.ui-header-searchbar > input[disabled],
+.ui-header-searchbar > .ui-search-input.ui-state-disabled,
+.ui-header-searchbar > input.ui-state-disabled {
+  text-shadow: 0 0 0 var(--text-input-disabled);
+}
+.ui-header-searchbar > .ui-search-input[disabled]::-webkit-input-placeholder,
+.ui-header-searchbar > input[disabled]::-webkit-input-placeholder,
+.ui-header-searchbar > .ui-search-input.ui-state-disabled::-webkit-input-placeholder,
+.ui-header-searchbar > input.ui-state-disabled::-webkit-input-placeholder {
+  text-shadow: var(--text-input-label-inactive);
+}
+.ui-header-searchbar > .ui-search-input::-webkit-input-placeholder,
+.ui-header-searchbar > input::-webkit-input-placeholder {
+  text-shadow: 0 0 0 var(--primary-color);
+}
+.ui-header-searchbar > .ui-search-input ~ .ui-text-input-clear.ui-btn.ui-btn-icon,
+.ui-header-searchbar > input ~ .ui-text-input-clear.ui-btn.ui-btn-icon {
+  top: 7.5px;
+  position: absolute;
+  right: 8.5px;
+  margin: 0;
+}
+.ui-header-searchbar > .ui-search-input ~ .ui-text-input-clear.ui-btn.ui-btn-icon::after,
+.ui-header-searchbar > input ~ .ui-text-input-clear.ui-btn.ui-btn-icon::after {
+  background-color: var(--text-color);
+}
+.ui-header-searchbar > .ui-search-input + .ui-btn.ui-btn-icon + .ui-text-input-clear.ui-btn.ui-btn-icon,
+.ui-header-searchbar > input + .ui-btn.ui-btn-icon + .ui-text-input-clear.ui-btn.ui-btn-icon {
+  right: 49.5px;
+}
+.ui-header-searchbar > .ui-search-input ~ .ui-btn-nobg::before,
+.ui-header-searchbar > input ~ .ui-btn-nobg::before {
+  background-color: var(--ripple-color);
+}
+.ui-header-searchbar .ui-header-btn-right ~ .ui-text-input-clear.ui-btn.ui-btn-icon {
+  right: 49.5px;
+}
+.ui-header-searchbar > .ui-btn:not(.ui-btn-nobg),
+.ui-header-searchbar .ui-header-btn-left.btn-icon-back,
+.ui-header-searchbar .ui-header-btn-icon.ui-header-btn-right {
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+  position: relative;
+}
+.ui-header-searchbar > .ui-btn.ui-btn-icon:not(.ui-text-input-clear):not(.btn-icon-back)::after {
+  -webkit-mask-size: 25px 25px;
+          mask-size: 25px 25px;
+}
+.ui-header-searchbar > .ui-header-btn-right {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  position: relative;
+}
+.ui-handler {
+  position: fixed;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  overflow: hidden;
+  opacity: 0;
+  transition: opacity 400ms ease-out;
+  height: 100%;
+  top: 0;
+  right: 0;
+}
+.ui-handler .ui-handler-track {
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  position: relative;
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+.ui-handler .ui-handler-track .ui-handler-handle {
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  position: absolute;
+  display: block;
+  background-color: transparent;
+}
+.ui-handler .ui-handler-track .ui-handler-handle .ui-handler-expander {
+  width: 100%;
+  height: 100%;
+  float: right;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  background-color: var(--primary-color);
+  border-radius: 2.5px;
+  transition-property: width border-width border-radius;
+  transition-duration: 100ms;
+}
+.ui-handler .ui-handler-track .ui-handler-handle.ui-active .ui-handler-thumb:before {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 16px;
+  height: 16px;
+  -webkit-mask-size: 100%;
+  -moz-mask-size: 100%;
+  -ms-mask-size: 100%;
+  -o-mask-size: 100%;
+  mask-size: 100%;
+  background-color: var(--icon-color);
+}
+.ui-handler .ui-handler-track .ui-handler-handle.ui-active .ui-handler-thumb:after {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 16px;
+  height: 16px;
+  -webkit-mask-size: 100%;
+  -moz-mask-size: 100%;
+  -ms-mask-size: 100%;
+  -o-mask-size: 100%;
+  mask-size: 100%;
+  background-color: var(--icon-color);
+}
+.ui-handler.ui-handler-direction-x {
+  right: 5px;
+  bottom: 0px;
+  left: 5px;
+  height: 19px;
+  top: auto;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-handle {
+  min-width: 22px;
+  height: 16px;
+  margin-bottom: 3px;
+  top: auto;
+  bottom: 0;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: flex-end;
+  -moz-align-items: flex-end;
+  -ms-align-items: flex-end;
+  -o-align-items: flex-end;
+  -ms-flex-align: end;
+      align-items: flex-end;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-handle .ui-handler-expander {
+  height: 5px;
+  width: 100%;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-track .ui-handler-handle.ui-active {
+  min-width: 41px;
+  margin-bottom: 3px;
+  border-radius: 8px;
+  -webkit-flex-direction: row;
+  -moz-flex-direction: row;
+  -ms-flex-direction: row;
+  -o-flex-direction: row;
+  flex-direction: row;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-track .ui-handler-handle.ui-active .ui-handler-expander {
+  height: 16px;
+  border-radius: 8px;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-thumb:before {
+  -webkit-mask-image: url("images/core_index_scroll_handler_h_01.png");
+          mask-image: url("images/core_index_scroll_handler_h_01.png");
+}
+.ui-handler.ui-handler-direction-x .ui-handler-thumb:after {
+  -webkit-mask-image: url("images/core_index_scroll_handler_h_02.png");
+          mask-image: url("images/core_index_scroll_handler_h_02.png");
+}
+.ui-handler.ui-handler-direction-y {
+  top: 0;
+  right: 0;
+  bottom: 0;
+  width: 19px;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+}
+.ui-handler.ui-handler-direction-y:before {
+  content: "";
+  width: 100%;
+  height: 55px;
+  background-color: transparent;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-handle {
+  width: 16px;
+  margin-right: 3px;
+  min-height: 22px;
+  left: auto;
+  right: 0;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-handle .ui-handler-expander {
+  width: 5px;
+  height: 100%;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-track {
+  margin: 5px 0;
+  background-color: transparent;
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-track .ui-handler-handle.ui-active {
+  width: 16px;
+  margin-right: 3px;
+  min-height: 41px;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-track .ui-handler-handle.ui-active .ui-handler-expander {
+  border-radius: 8px;
+  width: 16px;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-thumb:before {
+  -webkit-mask-image: url("images/core_index_scroll_handler_v_01.png");
+          mask-image: url("images/core_index_scroll_handler_v_01.png");
+}
+.ui-handler.ui-handler-direction-y .ui-handler-thumb:after {
+  -webkit-mask-image: url("images/core_index_scroll_handler_v_02.png");
+          mask-image: url("images/core_index_scroll_handler_v_02.png");
+}
+.ui-handler.disabled {
+  display: none;
+}
+.ui-handler .ui-handler-thumb {
+  width: 16px;
+  height: 16px;
+  position: relative;
+}
+.ui-handler-visible {
+  opacity: 1;
+}
+.scrollbar-disabled {
+  overflow: hidden !important;
+}
+.scrollbar-disabled .ui-scrollview-clip {
+  width: 105%;
+}
+.scrollbar-disabled .ui-scrollview-clip[data-direction="x"] {
+  width: 100%;
+  height: 105%;
+}
+.ui-container {
+  white-space: nowrap;
+  padding-bottom: 10px;
+}
+.ui-container > * {
+  scroll-snap-align: center;
+}
+.ui-container .ui-container-item {
+  display: inline-block;
+  margin-left: 3px;
+  margin-right: 3px;
+  width: 188px;
+}
+.ui-container .ui-container-item:last-child {
+  padding-right: 20px;
+}
+.ui-container.ui-container-middle .ui-favorite.ui-btn {
+  width: 103px;
+}
+.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content {
+  width: 103px;
+}
+.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content img {
+  width: 100px;
+  height: 100px;
+}
+.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content .ui-title,
+.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content .ui-subtitle {
+  font-family: Roboto-Medium;
+  width: 100%;
+  text-align: left;
+  text-overflow: ellipsis;
+  color: #7b7b7b;
+}
+.ui-drawer {
+  position: absolute;
+  background-color: var(--background-color);
+  z-index: 1201;
+  box-sizing: border-box;
+  overflow-x: hidden;
+  overflow-y: scroll;
+}
+.ui-drawer-header {
+  height: 56px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-drawer-title {
+  font-size: 19px;
+  color: var(--appbar-main-text-color);
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  margin-left: 20px;
+}
+.ui-drawer .ui-listview {
+  margin: 0;
+  position: absolute;
+  z-index: 2000;
+  width: 100%;
+  height: 100%;
+}
+.ui-drawer .ui-listview .ui-drawer-sub-list > .ui-btn-inner .ui-btn-text .ui-link-inherit {
+  padding-left: 13px;
+}
+.ui-drawer-overlay {
+  position: absolute;
+  background-color: var(--overlay);
+  z-index: 1200;
+}
+.ui-header .ui-btn.ui-drawer-button.ui-btn-icon-only {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 27px;
+  height: 36px;
+}
+.ui-header .ui-btn.ui-drawer-button.ui-btn-icon-only::after {
+  width: 27px;
+  height: 36px;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  margin-top: 0;
+  top: 0;
+  left: 0;
+}
+.ui-dropdownmenu-overlay {
+  opacity: 0;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 1200;
+}
+.ui-dropdownmenu {
+  box-sizing: border-box;
+  width: 100%;
+  display: block;
+  position: relative;
+}
+.ui-dropdownmenu:focus {
+  outline: none;
+}
+.ui-dropdownmenu:active {
+  outline: none;
+}
+.ui-dropdownmenu:active .ui-dropdownmenu-placeholder {
+  background-color: W021L1P;
+}
+.ui-dropdownmenu::before {
+  content: "";
+  opacity: 0;
+  width: 90%;
+  height: 26px;
+  background-color: var(--ripple-color);
+  position: absolute;
+  top: 17px;
+  left: 5%;
+  transition-property: width, height, top, left;
+  transition-duration: 0.2s;
+  transition-timing-function: ease;
+}
+.ui-dropdownmenu:active::before {
+  content: "";
+  opacity: 1;
+  width: 94%;
+  height: 40px;
+  background-color: var(--ripple-color);
+  position: absolute;
+  top: 10px;
+  left: 3%;
+}
+.ui-dropdownmenu .ui-dropdownmenu-placeholder {
+  box-sizing: border-box;
+  text-align: left;
+  width: 100%;
+  display: inline-block;
+  vertical-align: middle;
+  position: relative;
+  height: 100%;
+  line-height: 60px;
+  white-space: nowrap;
+  padding: 0 26px 0 16px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  font-size: 17px;
+  text-indent: 5px;
+  background-color: W021L1;
+}
+.ui-dropdownmenu .ui-dropdownmenu-placeholder::after {
+  content: "";
+  position: absolute;
+  width: calc(100% -  32px);
+  height: 1px;
+  bottom: 9px;
+  right: 16px;
+  background-color: F057;
+}
+.ui-dropdownmenu select {
+  width: 100%;
+  display: none;
+}
+.ui-dropdownmenu.ui-focus {
+  background-color: var(--ripple-color);
+}
+.ui-dropdownmenu-inline {
+  width: auto;
+  display: inline-block;
+}
+.ui-dropdownmenu-disabled {
+  opacity: 1;
+}
+.ui-dropdownmenu-disabled .ui-dropdownmenu-placeholder {
+  color: var(--dropdown-menu-options-color-dim);
+}
+.ui-dropdownmenu-force-display {
+  display: block !important;
+}
+.ui-dropdownmenu-native select {
+  display: block;
+  top: 0;
+  left: 0;
+  position: absolute;
+  height: 100%;
+  outline: 0;
+  opacity: 0;
+  border: 0;
+  margin: 0;
+}
+.ui-dropdownmenu-overlay-hidden {
+  display: none;
+}
+@-webkit-keyframes open-to-bottom {
+  from {
+    opacity: .5;
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+  to {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes open-to-top {
+  from {
+    opacity: .5;
+    -webkit-transform: translate3d(0, 100%, 0);
+    -ms-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+  to {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes close-to-bottom {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 100%, 0);
+    -ms-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+}
+@-webkit-keyframes close-to-top {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+.ui-dropdownmenu-options-wrapper {
+  position: absolute;
+  visibility: hidden;
+  top: -5000px;
+  overflow: hidden;
+  z-index: 1201;
+  min-width: 168px;
+  max-width: 100vw;
+  padding: 3px;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-vertical-margins {
+  margin-top: 3px;
+  margin-bottom: 3px;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-active {
+  visibility: visible;
+  overflow-y: auto;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-opening.ui-dropdownmenu-options-top .ui-dropdownmenu-options {
+  -webkit-animation: open-to-top 300ms;
+  animation: open-to-top 300ms;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-opening.ui-dropdownmenu-options-bottom .ui-dropdownmenu-options {
+  -webkit-animation: open-to-bottom 300ms;
+  animation: open-to-bottom 300ms;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-closing.ui-dropdownmenu-options-top .ui-dropdownmenu-options {
+  -webkit-animation: close-to-bottom 300ms;
+  animation: close-to-bottom 300ms;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-closing.ui-dropdownmenu-options-bottom .ui-dropdownmenu-options {
+  -webkit-animation: close-to-top 300ms;
+  animation: close-to-top 300ms;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options {
+  box-sizing: border-box;
+  list-style: none;
+  padding: 0;
+  margin: 0;
+  max-height: calc(100vh -  6px);
+  overflow-y: auto;
+  background-color: var(--dropdown-menu-options-background);
+  border-radius: 26px;
+  box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.35);
+  border: var(--dropdown-menu-options-border);
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options:focus {
+  outline: none;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-disabled {
+  color: var(--dropdown-menu-options-color-dim);
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-selected {
+  color: var(--primary-dark-color);
+  font-family: Roboto-Medium;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-selected::after {
+  width: 20px;
+  height: 20px;
+  margin-left: 16px;
+  margin-right: 24px;
+  content: '';
+  position: absolute;
+  -webkit-mask-image: url('images/1_App_bar/tw_ic_ab_back_mtrl.svg');
+          mask-image: url('images/1_App_bar/tw_ic_ab_back_mtrl.svg');
+  -webkit-mask-size: 100%, 0;
+          mask-size: 100%, 0;
+  -webkit-mask-position: center;
+          mask-position: center;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  right: 0;
+  -webkit-transform: translateY(-50%);
+      -ms-transform: translateY(-50%);
+          transform: translateY(-50%);
+  top: 50%;
+  background-color: var(--primary-dark-color);
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li {
+  padding: 15px 60px 15px 24px;
+  font-size: 17px;
+  font-family: Roboto-Regular;
+  display: block;
+  position: relative;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  color: var(--dropdown-menu-options-color);
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li.ui-dropdown-two-lines {
+  max-height: 2em;
+  line-height: 1.4em;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:not(.ui-dropdown-two-lines) {
+  white-space: nowrap;
+  height: 20px;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:focus,
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:active {
+  outline: none;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li::before {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: var(--ripple-color);
+  opacity: 0;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:active::before {
+  opacity: 1;
+}
+.ui-dropdownmenu-active::-webkit-scrollbar {
+  display: none;
+}
+.ui-listview li.ui-li-static.ui-li-has-dropdownmenu {
+  padding: 0;
+}
+.ui-listview li.ui-li-static.ui-li-has-dropdownmenu .ui-dropdownmenu-placeholder {
+  line-height: 60px;
+}
+.ui-li-static.ui-li-has-dropdownmenu {
+  height: 60px;
+}
+.ui-appbar .ui-dropdownmenu-placeholder {
+  line-height: 56px;
+}
+.ui-appbar-expanded .ui-dropdownmenu-placeholder {
+  line-height: 59px;
+}
+.ui-panel-changer {
+  position: relative;
+  display: block;
+  width: 100%;
+  left: 0;
+}
+.ui-panel {
+  position: absolute;
+  height: 100%;
+  width: 100%;
+}
+.ui-panel.ui-panel-active {
+  display: block;
+}
+.ui-panel.slide-in,
+.ui-panel.slide-out,
+.ui-panel.slide-reverse-out,
+.ui-panel.slide-reverse-in {
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
+  -webkit-animation-duration: 400ms;
+  animation-duration: 400ms;
+}
+.ui-panel.pre-in {
+  z-index: 100;
+}
+.ui-panel.slide-out {
+  -webkit-animation-name: panelslideouttoleft;
+  animation-name: panelslideouttoleft;
+}
+.ui-panel.slide-in {
+  -webkit-animation-name: panelslideinfromright;
+  animation-name: panelslideinfromright;
+}
+.ui-panel.slide-reverse-out {
+  -webkit-animation-name: panelslideouttoright;
+  animation-name: panelslideouttoright;
+}
+.ui-panel.slide-reverse-in {
+  -webkit-animation-name: panelslideinfromleft;
+  animation-name: panelslideinfromleft;
+}
+.ui-panel .ui-content {
+  height: 100%;
+}
+@-webkit-keyframes panelslideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+@keyframes panelslideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+@-webkit-keyframes panelslideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes panelslideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes panelslideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@keyframes panelslideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@-webkit-keyframes panelslideinfromleft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes panelslideinfromleft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+.ui-navigation {
+  -webkit-order: 2;
+  -moz-order: 2;
+  -ms-order: 2;
+  -o-order: 2;
+  -ms-flex-order: 2;
+      order: 2;
+  height: 35px;
+  box-sizing: border-box;
+  background-color: var(--background-color);
+  border-top: 1px solid var(--color-white);
+  white-space: nowrap;
+  overflow-x: scroll;
+  overflow-y: hidden;
+}
+.ui-navigation::-webkit-scrollbar {
+  display: none;
+}
+.ui-navigation .ui-navigation-container {
+  margin: 0;
+  padding: 0;
+  display: inline-block;
+  list-style-type: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item {
+  position: relative;
+  height: 34px;
+  line-height: 34px;
+  vertical-align: top;
+  overflow: hidden;
+  display: inline-block;
+  color: var(--text-color);
+  font-size: 16px;
+  background-color: transparent;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item:first-child {
+  margin-left: 9px;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item:first-child::before {
+  content: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item .ui-arrow {
+  float: left;
+  height: 34px;
+  width: 30px;
+  color: var(--text-color);
+  background-color: var(--color-white);
+  -webkit-mask-image: url("images/core_navigation_bar_icon_arrow.png");
+  -webkit-mask-size: 100% 100%;
+  margin: 0 -9px 0;
+  opacity: .6;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item .ui-text {
+  display: block;
+  position: relative;
+  float: left;
+  height: 21.5px;
+  color: var(--text-color);
+  padding: 3px 7px 4.5px;
+  line-height: 21.5px;
+  margin-top: 2.5px;
+  text-decoration: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  opacity: .6;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item .ui-text.ui-focus {
+  background-color: rgba(50, 150, 166, 0.4);
+  outline: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item:last-child {
+  margin-right: 9px;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-active-animation .ui-arrow {
+  -webkit-animation: navigation_active_show_animation_arrow linear 133ms;
+  animation: navigation_active_show_animation_arrow linear 133ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-active-animation .ui-text {
+  -webkit-animation: navigation_active_show_animation_text linear 166ms;
+  animation: navigation_active_show_animation_text linear 166ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back .ui-arrow {
+  -webkit-animation: none;
+  animation: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back .ui-text {
+  -webkit-animation: navigation_active_back_animation_text linear 184ms;
+  animation: navigation_active_back_animation_text linear 184ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-hide .ui-arrow {
+  -webkit-animation: navigation_active_hide_animation_text linear 150ms;
+  animation: navigation_active_hide_animation_text linear 150ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-hide .ui-text {
+  -webkit-animation: navigation_active_hide_animation_text linear 184ms;
+  animation: navigation_active_hide_animation_text linear 184ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigation-active .ui-arrow {
+  opacity: .6;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigation-active .ui-text {
+  color: var(--ripple-color);
+  opacity: 1;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back-hide .ui-arrow {
+  -webkit-animation: none;
+  animation: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back-hide .ui-text {
+  -webkit-animation: navigation_active_back_hide_animation_text linear 184ms;
+  animation: navigation_active_back_hide_animation_text linear 184ms;
+  opacity: 1;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-btn-active .ui-text::before {
+  content: "";
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  left: 50%;
+  top: 50%;
+  background-color: var(--ripple-color);
+  opacity: 0;
+  color: var(--ripple-color);
+  -webkit-animation: navigation_press_animation linear 500ms;
+  animation: navigation_press_animation linear 500ms;
+}
+@-webkit-keyframes navigation_active_show_animation_text {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@keyframes navigation_active_show_animation_text {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes navigation_active_back_animation_text {
+  0% {
+    opacity: .6;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@keyframes navigation_active_back_animation_text {
+  0% {
+    opacity: .6;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes navigation_active_back_hide_animation_text {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: .6;
+  }
+}
+@keyframes navigation_active_back_hide_animation_text {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: .6;
+  }
+}
+@-webkit-keyframes navigation_active_show_animation_arrow {
+  0% {
+    opacity: 0;
+  }
+  20% {
+    opacity: 0;
+  }
+  100% {
+    opacity: .6;
+  }
+}
+@keyframes navigation_active_show_animation_arrow {
+  0% {
+    opacity: 0;
+  }
+  20% {
+    opacity: 0;
+  }
+  100% {
+    opacity: .6;
+  }
+}
+@-webkit-keyframes navigation_active_hide_animation_text {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@keyframes navigation_active_hide_animation_text {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@-webkit-keyframes navigation_press_animation {
+  0% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(0.7);
+    -ms-transform: translate(-50%, -50%) scale(0.7);
+    transform: translate(-50%, -50%) scale(0.7);
+  }
+  5% {
+    opacity: .3;
+  }
+  100% {
+    opacity: .3;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+}
+@keyframes navigation_press_animation {
+  0% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(0.7);
+    -ms-transform: translate(-50%, -50%) scale(0.7);
+    transform: translate(-50%, -50%) scale(0.7);
+  }
+  5% {
+    opacity: .3;
+  }
+  100% {
+    opacity: .3;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+}
+@-webkit-keyframes navigation_pressup_animation {
+  0% {
+    opacity: .3;
+  }
+  100% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+}
+@keyframes navigation_pressup_animation {
+  0% {
+    opacity: .3;
+  }
+  100% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+}
+.ui-tabs {
+  position: relative;
+  height: 100%;
+  overflow: hidden;
+  border-bottom-left-radius: 26px;
+  border-bottom-right-radius: 26px;
+}
+.ui-tabs .ui-listview {
+  overflow: hidden;
+  min-height: 100%;
+  min-width: 100%;
+}
+.ui-section-changer {
+  height: 100%;
+  position: relative;
+  overflow: hidden;
+  display: block;
+}
+.ui-section-changer section {
+  overflow: auto;
+}
+.ui-indexscrollbar {
+  display: block;
+  position: absolute;
+  right: 0;
+  top: 0;
+  width: 20px;
+  height: 100%;
+  padding-left: 1px;
+  background-color: var(--control-background);
+  z-index: 1000;
+  overflow: visible;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  cursor: pointer;
+  box-sizing: border-box;
+}
+.ui-indexscrollbar::before {
+  width: 20px;
+  display: block;
+  position: absolute;
+  right: 20px;
+  height: 100%;
+  content: " ";
+  background-color: transparent;
+}
+.ui-indexscrollbar ul {
+  list-style-type: none;
+  margin: 0;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  left: 0;
+  visibility: visible;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+  -webkit-align-items: stretch;
+  -moz-align-items: stretch;
+  -ms-align-items: stretch;
+  -o-align-items: stretch;
+  -ms-flex-align: stretch;
+      align-items: stretch;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  padding: 0;
+  box-sizing: border-box;
+}
+.ui-indexscrollbar ul li {
+  cursor: pointer;
+  color: var(--text-color);
+  display: block;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  text-align: center;
+  font-size: 12px;
+  font-weight: bold;
+  border-bottom: 1px solid var(--primary-color);
+  border-left: 1px solid var(--border-surface);
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  max-height: 20px;
+  min-height: 20px;
+}
+.ui-indexscrollbar ul li a {
+  text-decoration: none;
+  width: 18px;
+  height: 19px;
+  color: inherit;
+  border: none;
+  outline: none;
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+}
+.ui-indexscrollbar ul li a:focus {
+  background-color: var(--ripple-color);
+}
+.ui-indexscrollbar ul li.ui-state-selected {
+  border-left: 2px solid var(--primary-color);
+  position: relative;
+  width: 18px;
+}
+.ui-indexscrollbar ul li.ui-state-selected::before {
+  content: "";
+  position: absolute;
+  height: 100%;
+  width: 17px;
+  left: -1px;
+  top: -1px;
+  border: 1px solid var(--border-surface);
+  border-left: none;
+}
+.ui-indexscrollbar ul::before,
+.ui-indexscrollbar ul::after {
+  content: "";
+  width: 20px;
+  border-left: 1px solid var(--border-surface);
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+  pointer-events: none;
+  -webkit-flex-basis: auto;
+      -ms-flex-preferred-size: auto;
+          flex-basis: auto;
+}
+.ui-indexscrollbar ul.ui-indexscrollbar-supplementary {
+  position: relative;
+  height: auto;
+  top: 0;
+  right: -20px;
+  width: 100%;
+}
+.ui-indexscrollbar .ui-indexscrollbar-margin {
+  width: 20px;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  border-left: 1px solid var(--border-surface);
+}
+.ui-indexscrollbar + .ui-listview li {
+  padding-right: 20px;
+}
+.ui-indexscrollbar ul li:first-child {
+  padding-top: 21px;
+  position: relative;
+}
+.ui-indexscrollbar ul li:first-child::before {
+  content: "";
+  height: 20px;
+  width: 20px;
+  position: absolute;
+  top: 0;
+  left: 0;
+  background-color: var(--text-color);
+  -webkit-mask-image: url("../default/images/controls/core_floating_icon_search.png");
+          mask-image: url("../default/images/controls/core_floating_icon_search.png");
+  -webkit-mask-size: 80%;
+          mask-size: 80%;
+  -webkit-mask-position: center center;
+          mask-position: center center;
+}
+.ui-indexscrollbar ul li:first-child::after {
+  content: "";
+  height: 1px;
+  width: 20px;
+  position: absolute;
+  top: 20px;
+  left: 0;
+  background-color: var(--primary-color);
+}
+.ui-indexscrollbar ul li:last-child {
+  border-bottom-color: transparent;
+}
+.ui-indexscrollbar-indicator {
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 999;
+  display: none;
+}
+.ui-indexscrollbar-indicator > span {
+  width: 84px;
+  line-height: 84px;
+  position: absolute;
+  display: block;
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+  font-size: 56px;
+  border-radius: 50%;
+  text-align: center;
+  box-sizing: border-box;
+  background-color: var(--control-background);
+  color: var(--text-color);
+}
+.ui-icon-add::after {
+  -webkit-mask-image: url("images/2_Buttons/tw_ic_ab_add_mtrl.svg");
+          mask-image: url("images/2_Buttons/tw_ic_ab_add_mtrl.svg");
+}
+.ui-icon-delete::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_bb_delete_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_bb_delete_mtrl.svg");
+}
+.ui-icon-cancel::after {
+  -webkit-mask-image: url("images/controls/core_button_cancel.png");
+          mask-image: url("images/controls/core_button_cancel.png");
+}
+.ui-icon-reorder::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_list_icon_reorder.svg");
+          mask-image: url("images/3_Controllers/tw_list_icon_reorder.svg");
+}
+.ui-icon-pause::after {
+  -webkit-mask-image: url("images/controls/00_button_pause.png");
+          mask-image: url("images/controls/00_button_pause.png");
+}
+.ui-icon-share::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_bb_share_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_bb_share_mtrl.svg");
+}
+.ui-icon-check::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_back_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_back_mtrl.svg");
+}
+.ui-icon-move::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_bb_move_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_bb_move_mtrl.svg");
+}
+.ui-icon-plus::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_list_icon_add_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_list_icon_add_mtrl.svg");
+}
+.ui-icon-minus::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_list_icon_delete_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_list_icon_delete_mtrl.svg");
+}
+.ui-icon-up::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_expander_close_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_expander_close_mtrl.svg");
+}
+.ui-icon-down::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+}
+.ui-icon-left::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+  -webkit-transform: translate(-50%, -50%) rotateZ(90deg);
+      -ms-transform: translate(-50%, -50%) rotate(90deg);
+          transform: translate(-50%, -50%) rotateZ(90deg);
+}
+.ui-icon-right::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+}
+.ui-icon-next::after {
+  -webkit-mask-image: url(images/3_Controllers/tw_expander_close_mtrl.svg);
+          mask-image: url(images/3_Controllers/tw_expander_close_mtrl.svg);
+}
+.ui-btn.ui-icon-next::after,
+.ui-btn.ui-icon-right::after {
+  -webkit-transform: translate(-50%, -50%) rotateZ(90deg);
+      -ms-transform: translate(-50%, -50%) rotate(90deg);
+          transform: translate(-50%, -50%) rotateZ(90deg);
+}
+.ui-btn.ui-icon-left::after {
+  -webkit-transform: translate(-50%, -50%) rotateZ(-90deg);
+      -ms-transform: translate(-50%, -50%) rotate(-90deg);
+          transform: translate(-50%, -50%) rotateZ(-90deg);
+}
+:root {
+  --button-fab-radius: 50%;
+  --button-fab-icon-color: var(--color-white);
+  --button-fab-right: 24px;
+  --button-fab-bottom: 24px;
+  --button-fab-width: 56px;
+  --button-fab-height: 56px;
+  --button-fab-icon-width: 24px;
+  --button-fab-icon-height: 24px;
+}
+tau-button {
+  -webkit-align-items: flex-start;
+      -ms-flex-align: start;
+          align-items: flex-start;
+  background-color: #dddddd;
+  border-bottom-color: #dddddd;
+  border-bottom-style: outset;
+  border-bottom-width: 2px;
+  border-image-outset: 0;
+  border-image-repeat: stretch;
+  border-image-slice: 100%;
+  border-image-source: none;
+  border-image-width: 1;
+  border-left-color: #dddddd;
+  border-left-style: outset;
+  border-left-width: 2px;
+  border-right-color: #dddddd;
+  border-right-style: outset;
+  border-right-width: 2px;
+  border-top-color: #dddddd;
+  border-top-style: outset;
+  border-top-width: 2px;
+  box-sizing: border-box;
+  color: #000000;
+  cursor: default;
+  display: inline-block;
+  font-family: 'Arial', 'MS Trebuchet', sans-serif;
+  font-size: 13.3333330154419px;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: normal;
+  letter-spacing: normal;
+  line-height: normal;
+  margin-bottom: 0;
+  margin-left: 0;
+  margin-right: 0;
+  margin-top: 0;
+  padding-bottom: 1px;
+  padding-left: 6px;
+  padding-right: 6px;
+  padding-top: 1px;
+  text-align: center;
+  text-indent: 0;
+  text-rendering: auto;
+  text-shadow: none;
+  text-transform: none;
+  word-spacing: 0;
+  -webkit-writing-mode: horizontal-tb;
+      -ms-writing-mode: lr-tb;
+          writing-mode: horizontal-tb;
+}
+@-webkit-keyframes btn_pressup_animation {
+  0% {
+    opacity: 1;
+  }
+  33% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@keyframes btn_pressup_animation {
+  0% {
+    opacity: 1;
+  }
+  33% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@-webkit-keyframes btn_press_animation_nobg {
+  0% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+  100% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1.425);
+    -ms-transform: translate(-50%, -50%) scale(1.425);
+    transform: translate(-50%, -50%) scale(1.425);
+  }
+}
+@keyframes btn_press_animation_nobg {
+  0% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+  100% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1.425);
+    -ms-transform: translate(-50%, -50%) scale(1.425);
+    transform: translate(-50%, -50%) scale(1.425);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_opacity_in {
+  0% {
+    background-color: transparent;
+  }
+  100% {
+    background-color: var(--ripple-button-flat-color);
+  }
+}
+@keyframes btn_press_animation_flat_opacity_in {
+  0% {
+    background-color: transparent;
+  }
+  100% {
+    background-color: var(--ripple-button-flat-color);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_opacity_out {
+  0% {
+    background-color: var(--ripple-button-flat-color);
+  }
+  100% {
+    background-color: transparent;
+  }
+}
+@keyframes btn_press_animation_flat_opacity_out {
+  0% {
+    background-color: var(--ripple-button-flat-color);
+  }
+  100% {
+    background-color: transparent;
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_opacity_in {
+  0% {
+    background-color: var(--button-background-flat);
+  }
+  100% {
+    background-color: var(--ripple-button-flat-color);
+  }
+}
+@keyframes btn_press_animation_flat_icon_opacity_in {
+  0% {
+    background-color: var(--button-background-flat);
+  }
+  100% {
+    background-color: var(--ripple-button-flat-color);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_opacity_out {
+  0% {
+    background-color: var(--ripple-button-flat-color);
+  }
+  100% {
+    background-color: var(--button-background-flat);
+  }
+}
+@keyframes btn_press_animation_flat_icon_opacity_out {
+  0% {
+    background-color: var(--ripple-button-flat-color);
+  }
+  100% {
+    background-color: var(--button-background-flat);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_scale {
+  0% {
+    -webkit-transform: translate(-50%, -50%) scale(0.95);
+            transform: translate(-50%, -50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translate(-50%, -50%) scale(1);
+            transform: translate(-50%, -50%) scale(1);
+  }
+}
+@keyframes btn_press_animation_flat_scale {
+  0% {
+    -webkit-transform: translate(-50%, -50%) scale(0.95);
+            transform: translate(-50%, -50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translate(-50%, -50%) scale(1);
+            transform: translate(-50%, -50%) scale(1);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_scale {
+  0% {
+    -webkit-transform: translate(-50%, -50%) scale(0.95);
+            transform: translate(-50%, -50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translate(-50%, -50%) scale(1);
+            transform: translate(-50%, -50%) scale(1);
+  }
+}
+@keyframes btn_press_animation_flat_icon_scale {
+  0% {
+    -webkit-transform: translate(-50%, -50%) scale(0.95);
+            transform: translate(-50%, -50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translate(-50%, -50%) scale(1);
+            transform: translate(-50%, -50%) scale(1);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_scale_left {
+  0% {
+    -webkit-transform: translateY(-50%) scale(0.95);
+            transform: translateY(-50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translateY(-50%) scale(1);
+            transform: translateY(-50%) scale(1);
+  }
+}
+@keyframes btn_press_animation_flat_icon_scale_left {
+  0% {
+    -webkit-transform: translateY(-50%) scale(0.95);
+            transform: translateY(-50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translateY(-50%) scale(1);
+            transform: translateY(-50%) scale(1);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_scale_top {
+  0% {
+    -webkit-transform: translateX(-50%) scale(0.95);
+            transform: translateX(-50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translateX(-50%) scale(1);
+            transform: translateX(-50%) scale(1);
+  }
+}
+@keyframes btn_press_animation_flat_icon_scale_top {
+  0% {
+    -webkit-transform: translateX(-50%) scale(0.95);
+            transform: translateX(-50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translateX(-50%) scale(1);
+            transform: translateX(-50%) scale(1);
+  }
+}
+@-webkit-keyframes animation_opacity_in {
+  0% {
+    opacity: 0;
+  }
+  10% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@keyframes animation_opacity_in {
+  0% {
+    opacity: 0;
+  }
+  10% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes animation_opacity_out {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@keyframes animation_opacity_out {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+button.ui-btn,
+input[type="button"].ui-btn {
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  width: 100%;
+  border: none;
+  outline: none;
+}
+a.ui-btn {
+  text-decoration: none;
+  width: 100%;
+}
+.ui-btn {
+  position: relative;
+  padding: 0 16px;
+  min-height: 36px;
+  vertical-align: middle;
+  text-overflow: ellipsis;
+  text-align: center;
+  color: var(--primary-color);
+  font-size: var(--button-text-font-size);
+  white-space: nowrap;
+  cursor: pointer;
+  background-color: var(--button-background);
+  box-sizing: border-box;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  z-index: 0;
+  border-radius: 18px;
+  font-family: Roboto-Medium;
+}
+.ui-btn::before {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  width: 100%;
+  height: 100%;
+  opacity: 0;
+  content: "";
+  border-width: 0;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+.ui-btn::after {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  -webkit-mask-size: 100% 100%;
+  -moz-mask-size: 100% 100%;
+  -ms-mask-size: 100% 100%;
+  -o-mask-size: 100% 100%;
+  mask-size: 100% 100%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+  -webkit-mask-repeat: no-repeat;
+  -moz-mask-repeat: no-repeat;
+  -ms-mask-repeat: no-repeat;
+  -o-mask-repeat: no-repeat;
+  mask-repeat: no-repeat;
+  -webkit-mask-position: center;
+  -moz-mask-position: center;
+  -ms-mask-position: center;
+  -o-mask-position: center;
+  mask-position: center;
+  -webkit-mask-size: 100%;
+  -moz-mask-size: 100%;
+  -ms-mask-size: 100%;
+  -o-mask-size: 100%;
+  mask-size: 100%;
+  content: "";
+}
+.ui-btn:focus {
+  outline: none;
+}
+.ui-btn:not(.ui-btn-nobg)::before {
+  z-index: -1;
+  border-radius: 26px;
+  background-color: var(--ripple-color);
+  box-sizing: border-box;
+}
+.ui-btn:not(.ui-btn-nobg).ui-btn-active::before {
+  opacity: 1;
+  -webkit-animation: btn_press_animation_flat_opacity_in linear 100ms, btn_press_animation_flat_opacity_out linear 400ms 100ms, btn_press_animation_flat_scale cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+          animation: btn_press_animation_flat_opacity_in linear 100ms, btn_press_animation_flat_opacity_out linear 400ms 100ms, btn_press_animation_flat_scale cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+}
+.ui-btn.ui-btn-focus {
+  outline: 2px solid var(--primary-color);
+}
+.ui-btn.ui-btn-nobg {
+  background-color: transparent;
+  color: var(--primary-color);
+}
+.ui-btn.ui-btn-nobg::before {
+  background-color: var(--ripple-color);
+  opacity: 0;
+  border-radius: 50%;
+  width: 40px;
+  height: 40px;
+  -webkit-transform: translate(-50%, -50%) scale(1);
+  -ms-transform: translate(-50%, -50%) scale(1);
+  transform: translate(-50%, -50%) scale(1);
+}
+.ui-btn.ui-btn-nobg.ui-btn-active::before {
+  -webkit-animation: btn_press_animation_nobg linear 315ms;
+          animation: btn_press_animation_nobg linear 315ms;
+  opacity: 1;
+  -webkit-transform: translate(-50%, -50%) scale(1.425);
+  -ms-transform: translate(-50%, -50%) scale(1.425);
+  transform: translate(-50%, -50%) scale(1.425);
+}
+.ui-btn.ui-btn-nobg.ui-btn-active.ui-btn-inactive::before {
+  opacity: 0;
+  -webkit-transform: translate(-50%, -50%) scale(1.425);
+  -ms-transform: translate(-50%, -50%) scale(1.425);
+  transform: translate(-50%, -50%) scale(1.425);
+}
+.ui-btn.ui-btn-nobg.ui-btn-active.ui-btn-inactive::after {
+  -webkit-animation: btn_pressup_animation 300ms linear;
+  animation: btn_pressup_animation 300ms linear;
+  opacity: 0;
+}
+.ui-btn.ui-btn-nobg.ui-btn-icon::after {
+  background-color: var(--text-color);
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-position: center;
+          mask-position: center;
+}
+.ui-btn.ui-btn-nobg.ui-btn-icon.ui-btn-active::after {
+  background-color: var(--text-color);
+}
+.ui-btn.ui-btn-nobg.ui-btn-icon.ui-icon-delete::after {
+  background-color: F060L3;
+  transition: background-color 15ms;
+}
+.ui-btn.ui-btn-nobg.ui-btn-icon.ui-icon-delete.ui-btn-active::after {
+  background-color: F060L3P;
+  transition: background-color 300ms;
+}
+.ui-btn.ui-btn-icon.ui-state-disabled::after {
+  opacity: 0.4;
+}
+.ui-btn.ui-btn-icon.ui-btn-circle {
+  width: 49px;
+  height: 49px;
+}
+.ui-btn.ui-btn-icon.ui-btn-circle::after {
+  background-color: var(--text-color);
+}
+.ui-btn.ui-btn-icon.ui-btn-nobg {
+  width: 40px;
+  height: 40px;
+  text-indent: -4999.5px;
+  padding: 10px 0;
+  border-radius: 0;
+}
+.ui-btn.ui-btn-icon.ui-btn-nobg.ui-inline {
+  width: 40px;
+}
+.ui-btn.ui-btn-icon.ui-btn-nobg::after {
+  width: 25px;
+  height: 25px;
+}
+.ui-btn.ui-btn-icon.ui-color-add::after {
+  background-color: var(--btn-add-color);
+}
+.ui-btn.ui-btn-icon.ui-color-delete::after {
+  background-color: var(--btn-delete-color);
+}
+.ui-btn.ui-inline {
+  display: inline-block;
+  width: auto;
+}
+.ui-btn.ui-hidden {
+  display: none;
+}
+.ui-btn.ui-state-disabled {
+  pointer-events: none;
+  background-color: var(--button-background);
+  color: var(--button-text-color-disabled);
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-only {
+  text-indent: -4999.5px;
+  width: 104px;
+}
+.ui-btn.ui-btn-icon::after {
+  background-color: var(--button-icon-color);
+}
+.ui-btn.ui-btn-icon.ui-btn-active::after {
+  background-color: var(--text-color);
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-left {
+  padding-left: 65px;
+  padding-right: 30px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-left::after {
+  left: 29px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-right {
+  padding-left: 30px;
+  padding-right: 65px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-right::after {
+  right: 29px;
+  left: auto;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-left::after,
+.ui-btn.ui-btn-icon.ui-btn-icon-right::after {
+  top: 50%;
+  -webkit-transform: translate(0, -50%);
+  -ms-transform: translate(0, -50%);
+  transform: translate(0, -50%);
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-top {
+  padding-top: 65px;
+  padding-bottom: 40px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-top::after {
+  top: 28px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-bottom {
+  padding-top: 40px;
+  padding-bottom: 65px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-bottom::after {
+  bottom: 28px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-top::after,
+.ui-btn.ui-btn-icon.ui-btn-icon-bottom::after {
+  left: 50%;
+  -webkit-transform: translate(-50%, 0);
+  -ms-transform: translate(-50%, 0);
+  transform: translate(-50%, 0);
+}
+.ui-btn.ui-btn-text-light,
+.ui-btn.ui-btn-text-dark {
+  min-height: 24px;
+  height: 24px;
+  line-height: 17px;
+  min-width: 48px;
+  font-size: 16px;
+  padding: 4px 12px;
+}
+.ui-btn.ui-btn-text-light.ui-btn-active,
+.ui-btn.ui-btn-text-dark.ui-btn-active {
+  font-size: 16px;
+}
+.ui-btn.ui-btn-text-light {
+  background-color: W019;
+}
+.ui-btn.ui-btn-text-light.ui-btn-active {
+  background-color: W019P;
+}
+.ui-btn.ui-btn-text-dark {
+  background-color: W020;
+}
+.ui-btn.ui-btn-text-dark.ui-btn-active::before {
+  background-color: W020P;
+}
+.ui-btn.ui-btn-flat {
+  color: var(--primary-dark-color);
+}
+.ui-btn.ui-btn-flat::before {
+  border-radius: 22px;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon {
+  color: var(--text-color);
+  min-height: 32px;
+  max-width: 32px;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon::after {
+  width: 32px;
+  height: 32px;
+  border-radius: 28px;
+  -webkit-mask-size: 32px;
+          mask-size: 32px;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon::before {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+      -ms-transform: translate(-50%, -50%);
+          transform: translate(-50%, -50%);
+  height: 32px;
+  width: 32px;
+  border-radius: 28px;
+  background-color: var(--button-background-flat);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top {
+  line-height: normal;
+  height: 60px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-flex-direction: column-reverse;
+      -ms-flex-direction: column-reverse;
+          flex-direction: column-reverse;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  padding: 0;
+  color: var(--appbar-subtitle-color);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top::after {
+  top: auto;
+  left: auto;
+  border-radius: 0;
+  width: 24px;
+  height: 24px;
+  -webkit-mask-size: 24px;
+          mask-size: 24px;
+  position: relative;
+  padding-bottom: 1px;
+  -webkit-transform: none;
+      -ms-transform: none;
+          transform: none;
+  background-color: var(--bottom-button-icon-color);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top::before {
+  top: auto;
+  left: auto;
+  border-radius: 12px;
+  -webkit-transform: none;
+      -ms-transform: none;
+          transform: none;
+  width: 100%;
+  height: 56px;
+  opacity: 0;
+  background-color: var(--ripple-color);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top.ui-btn-icon.ui-btn-active::before {
+  -webkit-animation: animation_opacity_in 200ms linear;
+          animation: animation_opacity_in 200ms linear;
+  -webkit-animation-fill-mode: both;
+          animation-fill-mode: both;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top.ui-btn-icon.ui-btn-inactive::before {
+  -webkit-animation: animation_opacity_out 50ms linear;
+          animation: animation_opacity_out 50ms linear;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-left {
+  padding-top: 13px;
+  padding-right: 8px;
+  padding-bottom: 13px;
+  max-height: 56px;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-left::after {
+  left: 0;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-left::before {
+  left: 0;
+  -webkit-transform: translateY(-50%);
+      -ms-transform: translateY(-50%);
+          transform: translateY(-50%);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-left.ui-btn-icon.ui-btn-active::before {
+  -webkit-animation: btn_press_animation_flat_icon_opacity_in linear 100ms, btn_press_animation_flat_icon_opacity_out linear 400ms 100ms, btn_press_animation_flat_icon_scale_left cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+          animation: btn_press_animation_flat_icon_opacity_in linear 100ms, btn_press_animation_flat_icon_opacity_out linear 400ms 100ms, btn_press_animation_flat_icon_scale_left cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon.ui-btn-active::before {
+  -webkit-animation: btn_press_animation_flat_icon_opacity_in linear 100ms, btn_press_animation_flat_icon_opacity_out linear 400ms 100ms, btn_press_animation_flat_icon_scale cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+          animation: btn_press_animation_flat_icon_opacity_in linear 100ms, btn_press_animation_flat_icon_opacity_out linear 400ms 100ms, btn_press_animation_flat_icon_scale cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+}
+.ui-btn.ui-btn-flat.ui-btn-disabled {
+  opacity: 0.4;
+}
+.ui-btn.ui-btn-contained {
+  background-color: var(--button-background-contained);
+  color: var(--text-color);
+  font-size: var(--button-contained-text-font-size);
+  border-radius: 22px;
+  width: auto;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  padding-top: 12px;
+  padding-bottom: 12px;
+}
+.ui-btn.ui-btn-contained::before {
+  border-radius: 22px;
+}
+.ui-btn.ui-btn-contained:not(.ui-btn-inline) {
+  max-width: 75%;
+  width: 60%;
+  display: block;
+  margin: 0 auto;
+}
+.ui-btn.ui-btn-contained.ui-state-disabled {
+  opacity: 0.4;
+  color: var(--button-text-contained-dim-color);
+}
+.ui-btn.ui-btn-contained-colored {
+  background-color: var(--primary-dark-color);
+  font-size: 17px;
+  color: var(--color-white);
+}
+.ui-btn.ui-btn-contained-colored.ui-state-disabled {
+  color: var(--color-white);
+}
+.ui-btn.ui-btn-fab {
+  position: fixed;
+  right: var(--button-fab-right);
+  bottom: var(--button-fab-bottom);
+  width: var(--button-fab-width);
+  height: var(--button-fab-height);
+  background-color: var(--primary-color);
+  z-index: 1000;
+  border-radius: var(--button-fab-radius);
+}
+.ui-btn.ui-btn-fab::after {
+  background-color: var(--button-fab-icon-color);
+  width: var(--button-fab-icon-width);
+  height: var(--button-fab-icon-height);
+}
+.ui-btn.ui-btn-fab.ui-btn-active.ui-btn-icon::after {
+  background-color: var(--button-fab-icon-color);
+}
+.ui-btn .ui-btn-content {
+  width: 90px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  margin: 0 auto;
+}
+.ui-btn .ui-btn-content :first-child {
+  font-size: 13px;
+  font-family: Roboto-Regular;
+  color: #949494;
+}
+.ui-btn .ui-btn-content :nth-child(2) {
+  font-size: 13px;
+  font-family: Roboto-Medium;
+  color: #404040;
+}
+@media all and (min-width: 673px) and (min-height: 411px) {
+  .ui-btn.ui-btn-contained:not(.ui-btn-inline):not(.ui-btn.ui-popup-toast-has-button) {
+    max-width: 60%;
+    min-width: 240px;
+  }
+}
+.ui-listview li.ui-li-has-btn {
+  box-sizing: border-box;
+}
+.ui-listview li .ui-btn.ui-btn-contained {
+  border-radius: 18px;
+  font-size: var(--button-contained-list-text-font-size);
+  padding-top: 8px;
+  padding-bottom: 8px;
+}
+.ui-listview .ui-btn-flat,
+.ui-listview .ui-btn-contained {
+  margin-right: 24px;
+  margin-left: 8px;
+}
+.ui-li-has-btn {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  height: 60px;
+}
+.ui-li-has-btn .ui-btn {
+  margin: -7px auto;
+  max-width: 248px;
+}
+.ui-li-has-btn .ui-btn ~ .ui-btn {
+  margin-left: 8px;
+}
+.ui-listview .ui-expandable,
+.ui-content-area .ui-expandable {
+  padding: 0 24px;
+  -webkit-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-listview .ui-expandable .ui-expandable-heading,
+.ui-content-area .ui-expandable .ui-expandable-heading {
+  color: var(--text-color);
+  font-size: 18px;
+  font-weight: normal;
+  padding-top: 15px;
+  padding-bottom: 16px;
+  line-height: 21px;
+  margin: 0;
+  position: relative;
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle {
+  position: relative;
+  display: block;
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle:focus,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle:focus {
+  outline: 0;
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle::after,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle::after {
+  content: "";
+  position: absolute;
+  right: -8px;
+  top: calc(50% -  16px);
+  -webkit-mask-image: url("images/6_Lists/tw_expander_close_mtrl.svg");
+          mask-image: url("images/6_Lists/tw_expander_close_mtrl.svg");
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  -webkit-mask-position: center;
+          mask-position: center;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  background-color: var(--expander-color);
+  width: 32px;
+  height: 32px;
+  transition: all 330ms ease;
+  -webkit-transform: rotate(0);
+      -ms-transform: rotate(0);
+          transform: rotate(0);
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-btn,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn {
+  width: 32px;
+  height: 32px;
+  min-height: auto;
+  position: absolute;
+  right: -8px;
+  top: calc(50% -  16px);
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-btn::before,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn::before {
+  width: 32px;
+  height: 32px;
+  display: none;
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-btn::after,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn::after {
+  width: 32px;
+  height: 32px;
+  -webkit-mask-size: 32px;
+          mask-size: 32px;
+  background-color: var(--expander-color);
+  transition: all 330ms ease;
+  -webkit-transform: translate(-50%, -50%) rotate(0);
+      -ms-transform: translate(-50%, -50%) rotate(0);
+          transform: translate(-50%, -50%) rotate(0);
+}
+.ui-listview .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-expandable-heading-toggle::after,
+.ui-content-area .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-expandable-heading-toggle::after {
+  -webkit-transform: rotate(180deg);
+      -ms-transform: rotate(180deg);
+          transform: rotate(180deg);
+}
+.ui-listview .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-btn::after,
+.ui-content-area .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-btn::after {
+  -webkit-transform: translate(-50%, -50%) rotate(180deg);
+      -ms-transform: translate(-50%, -50%) rotate(180deg);
+          transform: translate(-50%, -50%) rotate(180deg);
+}
+.ui-listview .ui-expandable .ui-expandable-content,
+.ui-content-area .ui-expandable .ui-expandable-content {
+  transition: all 330ms ease;
+  overflow: auto;
+}
+.ui-listview .ui-expandable .ui-expandable-content .ui-listview,
+.ui-content-area .ui-expandable .ui-expandable-content .ui-listview {
+  padding: 0;
+  margin-left: 18px;
+}
+.ui-listview .ui-expandable .ui-expandable-content .ui-listview li,
+.ui-content-area .ui-expandable .ui-expandable-content .ui-listview li {
+  color: var(--expandable-text-color);
+  padding-top: 15px;
+  padding-bottom: 16px;
+  line-height: 21px;
+  margin: 0;
+}
+.ui-listview .ui-expandable .ui-expandable-content-collapsed,
+.ui-content-area .ui-expandable .ui-expandable-content-collapsed {
+  overflow: hidden;
+  max-height: 0 !important;
+  display: none;
+  transition: all 330ms ease;
+}
+.ui-listview .ui-expandable.ui-state-disabled,
+.ui-content-area .ui-expandable.ui-state-disabled {
+  cursor: default !important;
+  pointer-events: none;
+  zoom: 1;
+}
+.ui-listview .ui-expandable.ui-state-disabled .ui-expandable-heading .ui-expandable-heading-toggle::after,
+.ui-content-area .ui-expandable.ui-state-disabled .ui-expandable-heading .ui-expandable-heading-toggle::after {
+  background-color: var(--control-background);
+}
+.ui-expandable-from ~ *:not(.ui-expandable-to) {
+  display: none;
+}
+.ui-listview .ui-expandable-from ~ *:not(.ui-expandable-to) {
+  display: none;
+}
+.ui-expandable-from.ui-expandable-expanded ~ *:not(.ui-expandable-to) {
+  display: inherit;
+}
+.ui-listview .ui-expandable-to ~ *:not(.ui-expandable-from) {
+  display: inherit;
+}
+.ui-expandable-to .ui-btn.ui-btn-flat,
+.ui-expandable-from .ui-btn.ui-btn-flat {
+  width: 32px;
+  height: 32px;
+  min-height: auto;
+  margin: auto;
+}
+.ui-expandable-to .ui-btn.ui-btn-flat::before,
+.ui-expandable-from .ui-btn.ui-btn-flat::before {
+  width: 32px;
+  height: 32px;
+}
+.ui-expandable-to .ui-btn.ui-btn-flat::after,
+.ui-expandable-from .ui-btn.ui-btn-flat::after {
+  width: 32px;
+  height: 32px;
+  -webkit-mask-size: 32px;
+          mask-size: 32px;
+  background-color: var(--expander-color);
+  transition: all 330ms ease;
+  -webkit-transform: translate(-50%, -50%) rotate(0);
+      -ms-transform: translate(-50%, -50%) rotate(0);
+          transform: translate(-50%, -50%) rotate(0);
+}
+.ui-expandable-from .ui-btn.ui-btn-flat {
+  position: absolute;
+  right: -6px;
+}
+.ui-expandable-from.ui-expandable-expanded ~ .ui-expandable-to .ui-btn.ui-btn-flat::after,
+.ui-expandable-from.ui-expandable-expanded .ui-btn.ui-btn-flat::after {
+  -webkit-transform: translate(-50%, -50%) rotate(180deg);
+      -ms-transform: translate(-50%, -50%) rotate(180deg);
+          transform: translate(-50%, -50%) rotate(180deg);
+}
+.ui-floatingactions {
+  position: fixed;
+  right: 0;
+  bottom: 21.5px;
+  height: 60px;
+  padding-left: 15px;
+  padding-right: 15px;
+  -webkit-transform: translate3d(12px, 0, 0);
+          transform: translate3d(12px, 0, 0);
+  -webkit-mask-box-image-repeat: repeat;
+  -moz-mask-box-image-repeat: repeat;
+  -ms-mask-box-image-repeat: repeat;
+  -o-mask-box-image-repeat: repeat;
+  mask-box-image-repeat: repeat;
+  -webkit-mask-box-image-width: auto;
+  -moz-mask-box-image-width: auto;
+  -ms-mask-box-image-width: auto;
+  -o-mask-box-image-width: auto;
+  mask-box-image-width: auto;
+  -webkit-mask-box-image-source: url('images/nine-patch/core_floating_button_bg.png');
+  -webkit-mask-box-image-slice: 60 64 60 64 fill;
+  -moz-mask-box-image-slice: 60 64 60 64 fill;
+  -ms-mask-box-image-slice: 60 64 60 64 fill;
+  -o-mask-box-image-slice: 60 64 60 64 fill;
+  mask-box-image-slice: 60 64 60 64 fill;
+  background-color: var(--primary-dark-color);
+  z-index: 1000;
+}
+.ui-floatingactions.ui-floatingactions-transitions {
+  transition-property: all;
+  transition-duration: 500ms;
+}
+.ui-floatingactions .ui-btn {
+  display: inline-block;
+  width: 60px;
+  height: 60px;
+  margin: 0;
+  background-color: transparent;
+  color: var(--primary-color);
+}
+.ui-floatingactions .ui-btn.ui-btn-icon {
+  width: 60px;
+}
+.ui-floatingactions .ui-btn::before {
+  background-color: var(--ripple-color);
+  opacity: 0;
+  border-radius: 50%;
+  width: 40px;
+  height: 40px;
+  -webkit-transform: translate(-50%, -50%) scale(1);
+  -ms-transform: translate(-50%, -50%) scale(1);
+  transform: translate(-50%, -50%) scale(1);
+}
+.ui-floatingactions .ui-btn.ui-btn-active::before {
+  -webkit-animation: btn_press_animation_nobg linear 315ms;
+          animation: btn_press_animation_nobg linear 315ms;
+  opacity: 1;
+  -webkit-transform: translate(-50%, -50%) scale(1.425);
+  -ms-transform: translate(-50%, -50%) scale(1.425);
+  transform: translate(-50%, -50%) scale(1.425);
+}
+.ui-floatingactions .ui-btn.ui-btn-active.ui-btn-inactive::before {
+  opacity: 0;
+  -webkit-transform: translate(-50%, -50%) scale(1.425);
+  -ms-transform: translate(-50%, -50%) scale(1.425);
+  transform: translate(-50%, -50%) scale(1.425);
+}
+.ui-floatingactions .ui-btn.ui-btn-active.ui-btn-inactive::after {
+  -webkit-animation: btn_pressup_animation 300ms linear;
+  animation: btn_pressup_animation 300ms linear;
+  opacity: 0;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon::after {
+  background-color: var(--text-color);
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-position: center;
+          mask-position: center;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-active::after {
+  background-color: var(--text-color);
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-icon-delete::after {
+  background-color: F060L3;
+  transition: background-color 15ms;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-icon-delete.ui-btn-active::after {
+  background-color: F060L3P;
+  transition: background-color 300ms;
+}
+.ui-floatingactions .ui-btn::before {
+  background-color: var(--ripple-color);
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left {
+  padding: 0;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after {
+  left: 50%;
+  top: 50%;
+  -webkit-transform: translate(-50%, -50%);
+      -ms-transform: translate(-50%, -50%);
+          transform: translate(-50%, -50%);
+  width: 40px;
+  height: 40px;
+  background-color: var(--color-white);
+  z-index: -100;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active ::after {
+  background-color: var(--ripple-color);
+}
+.ui-floatingactions .ui-btn.ui-icon-floating-add::after {
+  -webkit-mask-image: url("images/controls/core_floating_icon_add.png");
+          mask-image: url("images/controls/core_floating_icon_add.png");
+}
+.ui-floatingactions .ui-btn.ui-icon-floating-search::after {
+  -webkit-mask-image: url("images/controls/core_floating_icon_search.png");
+          mask-image: url("images/controls/core_floating_icon_search.png");
+}
+.ui-floatingactions .ui-btn-focus {
+  outline: none;
+  background-color: rgba(50, 150, 166, 0.4);
+}
+.ui-floatingactions .ui-btn ~ .ui-btn {
+  margin-left: -10px;
+}
+.ui-floatingactions.ui-floatingactions-expand-to-right {
+  padding-right: 30px;
+  right: -15px;
+}
+.ui-floatingactions.ui-floatingactions-expand-to-left {
+  padding-left: 30px;
+}
+.ui-floatingactions:focus {
+  outline: none;
+  background-color: rgba(78, 97, 173, 0.8);
+}
+.ui-floatingactions-reposition:focus {
+  background-color: var(--ripple-color);
+}
+.ui-content .ui-floatingactions,
+.ui-tabs .ui-floatingactions {
+  background-color: var(--primary-dark-color);
+}
+.ui-content .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after,
+.ui-tabs .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after {
+  background-color: var(--color-white);
+}
+.ui-content .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after,
+.ui-tabs .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after {
+  background-color: var(--ripple-color);
+}
+.ui-content .ui-floatingactions .ui-btn::before,
+.ui-tabs .ui-floatingactions .ui-btn::before {
+  background-color: var(--ripple-color);
+}
+.ui-content .ui-floatingactions:focus,
+.ui-tabs .ui-floatingactions:focus {
+  outline: none;
+  background-color: rgba(78, 97, 173, 0.8);
+}
+.ui-content .ui-floatingactions-reposition:focus,
+.ui-tabs .ui-floatingactions-reposition:focus {
+  background-color: var(--ripple-color);
+}
+.ui-indexscrollbar ~ .ui-floatingactions {
+  background-color: var(--primary-dark-color);
+}
+.ui-indexscrollbar ~ .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after {
+  background-color: var(--color-white);
+}
+.ui-indexscrollbar ~ .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after {
+  background-color: var(--ripple-color);
+}
+.ui-indexscrollbar ~ .ui-floatingactions .ui-btn::before {
+  background-color: var(--ripple-color);
+}
+.ui-listview ~ .ui-floatingactions .ui-btn.ui-btn-icon::after {
+  background-color: var(--color-white);
+}
+.ui-listview ~ .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-active::after {
+  background-color: var(--ripple-color);
+}
+.ui-page-floatingactions.ui-empty-state .ui-content {
+  box-sizing: border-box;
+  border-bottom: 127px solid transparent;
+}
+/*
+* Listview Style - divide single / multiline style for specific
+* If you want to see any style, search them using class name.
+*/
+/******************** custom elements styles *********************/
+tau-listview {
+  display: block;
+  list-style-type: disc;
+  -webkit-margin-before: 1em;
+  -webkit-margin-after: 1em;
+  -webkit-margin-start: 0;
+  -webkit-margin-end: 0;
+  -webkit-padding-start: 40px;
+}
+tau-expandable {
+  display: list-item;
+  text-align: -webkit-match-parent;
+}
+/******************** listview common style *********************/
+.ui-listview {
+  /**
+        * Listview cannot have style "overflow: hidden"
+        * because this widget has canvas which has to be visible outside the listview
+        */
+  margin: auto;
+  padding: 0;
+  list-style: none;
+  counter-reset: listnumbering;
+  position: relative;
+  -webkit-transform: translate3d(0, 0, 0);
+          transform: translate3d(0, 0, 0);
+  /*when set the list in drag mode before dragging*/
+  /*When dragging element*/
+}
+@media (min-width: 673px) and (min-height: 411px) {
+  .ui-listview {
+    width: 90%;
+  }
+}
+@media (min-width: 960px) {
+  .ui-listview {
+    width: 75%;
+  }
+}
+.ui-listview.ui-content-area {
+  margin-bottom: 16px;
+}
+.ui-listview.ui-content-area + button[data-style=fab] {
+  display: block;
+  min-height: 0;
+  margin-bottom: 108px;
+}
+.ui-listview li {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  position: relative;
+  box-sizing: content-box;
+  overflow: visible;
+  text-align: left;
+  font-size: 18px;
+}
+.ui-listview li[disabled] {
+  opacity: 0.4;
+}
+.ui-listview li.ui-li-subheader {
+  margin-left: 20px;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-listview li.ui-li-subheader:empty {
+  margin-top: 16px;
+}
+.ui-listview li.ui-li-subheader .ui-li-text-subheader {
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  color: var(--text-secondary-color);
+  font-family: Roboto-Medium;
+  font-size: 14px;
+  margin-left: 4px;
+  margin-right: 16px;
+  min-height: 36px;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-subheader::after {
+  content: "";
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  width: calc(100% - 20px);
+  border-bottom: 3px dotted var(--subheader-divider-color);
+  height: 0;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  margin-right: 20px;
+}
+.ui-listview li.ui-li-anchor {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  padding: 14px 0;
+  margin: 0 24px;
+}
+.ui-listview li.ui-li-has-text-input {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  padding: 18px 0 8px 0;
+  margin: 0 24px;
+}
+.ui-listview li .ui-li-checkbox-icon {
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li .ui-li-checkbox-icon img {
+  width: 40px;
+  height: 40px;
+  margin-right: 18px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-listview li .ui-li-icon {
+  width: 40px;
+  height: 40px;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  position: relative;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+          align-self: center;
+  margin: 0 12px;
+}
+.ui-listview li .ui-li-icon.ui-li-icon-small,
+.ui-listview li .ui-li-icon.ui-li-icon-small:after {
+  width: 25px !important;
+  height: 25px !important;
+}
+.ui-listview li .ui-li-icon::after,
+.ui-listview li .ui-li-icon * {
+  content: "";
+  position: absolute;
+  width: 40px;
+  height: 40px;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-position: center center;
+          mask-position: center center;
+}
+.ui-listview li .ui-li-text {
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  padding: 15px 0;
+  margin-right: 24px;
+}
+.ui-listview li .ui-li-text .ui-li-text-title {
+  font-size: 18px;
+  color: var(--text-color);
+  line-height: 21px;
+  vertical-align: middle;
+}
+.ui-listview li .ui-li-text .ui-li-text-title:only-child {
+  padding-bottom: 1px;
+}
+.ui-listview li .ui-li-text .ui-li-text-title + .ui-li-text-sub::before {
+  content: "";
+  display: block;
+  height: 4px;
+}
+.ui-listview li .ui-li-text .ui-li-text-sub {
+  font-size: 13px;
+  color: var(--text-secondary-color);
+  line-height: 15px;
+}
+.ui-listview li .ui-li-text .ui-li-text-sub + .ui-li-text-title::before {
+  content: "";
+  display: block;
+  height: 4px;
+}
+.ui-listview li .ui-li-text .ui-li-text-sub img {
+  width: 15px;
+  height: 15px;
+}
+.ui-listview li .ui-li-text .ui-li-text-value {
+  color: var(--primary-color);
+}
+.ui-listview li > .ui-li-text:first-child {
+  margin-left: 24px;
+}
+.ui-listview li.ui-li-divider::after {
+  content: "";
+  position: absolute;
+  width: calc(100% - 40px);
+  left: 20px;
+  bottom: -0.75px;
+  height: 0.75px;
+  background-color: var(--divider-color);
+  opacity: var(--divider-opacity);
+}
+.ui-listview li.ui-li-divider.ui-li-has-icon::after {
+  width: calc(100% - 84px);
+  left: 64px;
+}
+.ui-listview li.ui-li-divider.ui-li-has-checkbox::after,
+.ui-listview li.ui-li-divider.ui-li-has-radio::after {
+  width: calc(100% - 92px);
+  left: 68px;
+}
+.ui-listview li.ui-li-divider.ui-li-has-checkbox-icon::after {
+  left: 126px;
+}
+.ui-listview li + li.ui-li-divider {
+  margin-top: 0.75px;
+}
+.ui-listview li .ui-li-divider {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  margin-left: 12px;
+  margin-right: 9px;
+}
+.ui-listview li .ui-li-divider::after {
+  content: "";
+  position: absolute;
+  width: 0.5px;
+  height: 22px;
+  background-color: var(--on-off-switch-divider-color);
+}
+.ui-listview li .ui-li-action {
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+          align-self: center;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  margin-left: auto;
+  white-space: nowrap;
+}
+.ui-listview li .ui-li-action .ui-on-off-switch-container {
+  margin-right: 24px;
+}
+.ui-listview li .ui-li-right {
+  margin-left: auto !important;
+}
+.ui-listview li .ui-li-text-ellipse {
+  min-width: 0;
+  white-space: nowrap;
+}
+.ui-listview li .ui-li-text-ellipse * {
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+.ui-listview li input[type="checkbox"].ui-checkbox,
+.ui-listview li input[type="radio"].ui-radio {
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li.ui-li-selected {
+  background-color: var(--list-item-selected-color);
+}
+.ui-listview li,
+.ui-listview tau-expandable {
+  box-shadow: none;
+}
+.ui-listview li .ui-link-inherit,
+.ui-listview tau-expandable .ui-link-inherit {
+  color: var(--text-color);
+}
+.ui-listview li:not(.ui-expandable).ui-li-active,
+.ui-listview tau-expandable:not(.ui-expandable).ui-li-active {
+  background-color: var(--active);
+}
+.ui-listview li.ui-li-active.ui-expandable .ui-expandable-heading,
+.ui-listview tau-expandable.ui-li-active.ui-expandable .ui-expandable-heading {
+  background-color: var(--active);
+}
+.ui-listview li > a:not(.ui-btn),
+.ui-listview tau-expandable > a:not(.ui-btn) {
+  display: block;
+  width: 100%;
+  height: 100%;
+  margin: -16.5px -16px;
+  padding: 16.5px 16px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  color: var(--text-color);
+  text-decoration: none;
+  box-sizing: border-box;
+}
+.ui-listview.ui-listview-focus {
+  box-sizing: border-box;
+  border: 2px solid blue;
+}
+.ui-listview .ui-listview-item-focus {
+  background-color: var(--ripple-color);
+}
+.ui-listview .ui-listview-item-focus a {
+  outline: none;
+}
+.ui-listview .ui-listview-background {
+  display: block;
+  box-sizing: border-box;
+  position: absolute;
+  top: 0;
+  left: 0;
+  pointer-events: none;
+  z-index: -1;
+}
+.ui-listview .ui-listview-background::before {
+  content: "250,250,250,1::0,0,0,-0.04";
+  display: none;
+}
+.ui-listview.ui-listview-background-disabled .ui-listview-background {
+  display: none;
+}
+.ui-listview .ui-li-static {
+  /**************** with progress bar ************/
+}
+.ui-listview .ui-li-static.ui-li-select-all {
+  color: var(--background-color);
+}
+.ui-listview .ui-li-static.ui-li-select-all label {
+  display: block;
+}
+.ui-listview .ui-li-static.ui-li-select-all label input[type=checkbox] {
+  float: right;
+}
+.ui-listview .ui-li-static.li-has-thumb .li-thumb {
+  position: absolute;
+  left: 16px;
+  top: 50%;
+  margin-top: -13px;
+  width: 25px;
+  height: 25px;
+}
+.ui-listview .ui-li-static.li-has-thumb .li-thumb.li-thumb-circle {
+  border-radius: 100%;
+}
+.ui-listview .ui-li-static.li-has-thumb.li-thumbnail-right .li-thumb {
+  float: right;
+  left: auto;
+  right: 16px;
+}
+.ui-listview .ui-li-static.li-has-progress {
+  padding: 12px 16px 11px;
+}
+.ui-listview .ui-li-static.li-has-progress .ui-progress {
+  margin: 16px 0 10px 0;
+}
+.ui-listview .ui-li-static .ui-btn.ui-btn-icon.ui-btn-nobg::after {
+  width: 40px;
+  height: 40px;
+}
+.ui-listview li.ui-li-flex {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  padding: 0;
+  overflow-x: visible;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex.ui-li-select-all {
+  color: var(--background-color);
+}
+.ui-listview li.ui-li-flex.ui-li-select-all label {
+  display: block;
+}
+.ui-listview li.ui-li-flex.ui-li-select-all label input[type=checkbox] {
+  float: right;
+}
+.ui-listview li.ui-li-flex .ui-li-text {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  font-size: 18px;
+  color: var(--text-color);
+  max-height: 24.25px;
+  width: 100%;
+}
+.ui-listview li.ui-li-flex .ui-li-text > *:not(.ui-li-text-sub-2) {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text .ui-li-text-sub-2 {
+  -webkit-align-self: flex-end;
+  -ms-align-self: flex-end;
+  -o-align-self: flex-end;
+  -ms-flex-item-align: end;
+      align-self: flex-end;
+}
+.ui-listview li.ui-li-flex .ui-li-text-2 {
+  color: var(--text-secondary-color);
+  line-height: 21.5px;
+  font-size: 13px;
+  max-height: 17.5px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text-2 > *:not(.ui-li-text-sub-3) {
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text-2 .ui-li-text-sub-3 {
+  -webkit-align-self: flex-end;
+  -ms-align-self: flex-end;
+  -o-align-self: flex-end;
+  -ms-flex-item-align: end;
+      align-self: flex-end;
+  margin: auto 0 auto auto;
+}
+.ui-listview li.ui-li-flex .ui-li-text-2 span + .ui-li-text-sub-3 {
+  margin-left: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub {
+  line-height: 21.5px;
+  font-size: 16px;
+  color: var(--text-secondary-color);
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub > *:not(.ui-li-text-sub-3) {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub .ui-li-text-sub-3 {
+  -webkit-align-self: flex-end;
+  -ms-align-self: flex-end;
+  -o-align-self: flex-end;
+  -ms-flex-item-align: end;
+      align-self: flex-end;
+  margin: auto 0 auto auto;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub span + .ui-li-text-sub-3 {
+  margin-left: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub-2 {
+  line-height: 27px;
+  max-width: 109px;
+  margin-left: 16px;
+  font-size: 15px;
+  color: var(--text-secondary-color);
+  float: right;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub-3 {
+  line-height: 22px;
+  max-width: 109px;
+  margin-left: 16px;
+  font-size: 16px;
+  color: var(--text-secondary-color);
+  float: right;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub + .ui-li-text-sub-3 {
+  margin-top: -1rem;
+}
+.ui-listview li.ui-li-flex .ui-li-area-a {
+  position: relative;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  min-width: 1%;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-justify-content: flex-start;
+      -ms-flex-pack: start;
+          justify-content: flex-start;
+  margin-top: 16.5px;
+  margin-bottom: 16.5px;
+  padding: 0 24px 0 18px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-b {
+  -webkit-order: 0;
+      -ms-flex-order: 0;
+          order: 0;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-image,
+.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-circle-image,
+.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-icon {
+  margin-left: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-c {
+  -webkit-order: 3;
+      -ms-flex-order: 3;
+          order: 3;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-image,
+.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-circle-image {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-icon {
+  margin-right: 8.5px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-c .ui-toggle-container {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-d {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-image,
+.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-circle-image {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-icon {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex input.ui-li-area-b[type="checkbox"],
+.ui-listview li.ui-li-flex input.ui-li-area-b[type="radio"] {
+  margin-left: 18px;
+  margin-right: 0;
+}
+.ui-listview li.ui-li-flex input.ui-li-area-c[type="checkbox"],
+.ui-listview li.ui-li-flex input.ui-li-area-c[type="radio"] {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex input.ui-li-area-d[type="checkbox"],
+.ui-listview li.ui-li-flex input.ui-li-area-d[type="radio"],
+.ui-listview li.ui-li-flex input.ui-li-area-d .ui-li-image,
+.ui-listview li.ui-li-flex input.ui-li-area-d .ui-li-circle-image {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-icon::after {
+  content: "";
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-position: center center;
+          mask-position: center center;
+  left: 50%;
+  top: 50%;
+  -webkit-transform: translate(-50%, -50%);
+      -ms-transform: translate(-50%, -50%);
+          transform: translate(-50%, -50%);
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-image {
+  width: 60px;
+  height: 60px;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-circle-image {
+  width: 49px;
+  height: 49px;
+  border-radius: 100%;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-icon {
+  width: 32px;
+  height: 32px;
+  position: relative;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon {
+  width: 25px;
+  min-width: 25px;
+  max-width: 25px;
+  height: 25px;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  position: relative;
+  margin-left: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon.ui-li-icon-left {
+  -webkit-order: -1;
+      -ms-flex-order: -1;
+          order: -1;
+  margin-right: 6px;
+  margin-left: 0;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon.ui-li-icon-middle {
+  top: 50%;
+  -webkit-transform: translateY(-50%);
+      -ms-transform: translateY(-50%);
+          transform: translateY(-50%);
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-c.ui-li-icon {
+  width: 40px;
+  height: 40px;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-c.ui-li-icon:after {
+  width: 25px;
+  height: 25px;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-d.ui-li-icon {
+  width: 25px;
+  height: 25px;
+}
+.ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a {
+  margin-top: 12px;
+  margin-bottom: 12px;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a > .ui-li-icon {
+  position: absolute;
+  right: 16px;
+}
+.ui-listview li.ui-li-flex.ui-li-flex-reverse .ui-li-area {
+  -webkit-flex-direction: column-reverse;
+      -ms-flex-direction: column-reverse;
+          flex-direction: column-reverse;
+}
+.ui-listview.ui-details .ui-li-static {
+  color: var(--text-color);
+  padding: 12px 16px 11.5px 16px;
+  height: 48.5px;
+  line-height: 27px;
+}
+.ui-listview.ui-details .ui-li-static.li-has_icon {
+  padding: 64px 16px 11.5px 16px;
+}
+.ui-listview.ui-details .ui-li-static.li-has_icon img {
+  position: absolute;
+  top: 20px;
+  left: 16px;
+}
+.ui-listview.ui-details .ui-li-static .li-text-sub {
+  color: var(--text-secondary-color);
+  height: 21.5px;
+  position: initial;
+  float: none;
+  text-align: left;
+  display: block;
+  line-height: 21.5px;
+}
+.ui-listview.ui-details .ui-listview-background {
+  display: none;
+}
+.ui-listview .li-has-right-btn .ui-btn,
+.ui-listview .li-has-right-circle-btn .ui-btn {
+  position: absolute;
+  top: 50%;
+  right: 16px;
+  -webkit-transform: translate(0, -50%);
+      -ms-transform: translate(0, -50%);
+          transform: translate(0, -50%);
+}
+.ui-listview .li-has-right-btn .ui-toggle-container,
+.ui-listview .li-has-right-circle-btn .ui-toggle-container {
+  position: absolute;
+  top: 50%;
+  right: 16px;
+  -webkit-transform: translate(0, -50%);
+      -ms-transform: translate(0, -50%);
+          transform: translate(0, -50%);
+}
+.ui-listview .li-has-right-btn .ui-toggle-container:first-child:not(:only-child),
+.ui-listview .li-has-right-circle-btn .ui-toggle-container:first-child:not(:only-child) {
+  right: 60px;
+}
+.ui-listview .li-has-right-btn .ui-btn-icon.ui-btn-nobg,
+.ui-listview .li-has-right-circle-btn .ui-btn-icon.ui-btn-nobg {
+  right: 8.5px;
+}
+.ui-listview .li-has-right-btn .ui-btn-icon.ui-btn-circle,
+.ui-listview .li-has-right-circle-btn .ui-btn-icon.ui-btn-circle {
+  right: 16px;
+}
+.ui-listview .li-has-radio.li-has-right-radio .ui-radio {
+  margin-top: 0;
+  position: absolute;
+  right: 13px;
+  left: auto;
+  top: 18px;
+}
+.ui-listview .li-has-radio.li-has-right-radio .ui-radio:first-child {
+  right: 60px;
+}
+.ui-listview.ui-drag-mode li {
+  /*align-items: center;*/
+}
+.ui-listview.ui-drag-mode li .ui-listview-handler {
+  display: block;
+  position: relative;
+  width: 32px;
+  height: 32px;
+  -webkit-flex: 0 1 auto;
+      -ms-flex: 0 1 auto;
+          flex: 0 1 auto;
+  -webkit-order: 10;
+      -ms-flex-order: 10;
+          order: 10;
+  margin: auto 16px auto auto;
+}
+.ui-listview.ui-drag-mode li .ui-listview-handler::after {
+  content: "";
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  background-color: var(--reorder-color);
+}
+.ui-listview.ui-snapshot {
+  height: 100%;
+}
+.ui-listview.ui-snapshot li {
+  position: absolute;
+  width: 100%;
+  box-sizing: border-box;
+  transition: top 0.1s linear;
+}
+.ui-listview.ui-snapshot li.ui-listview-helper {
+  transition: none;
+  background-color: var(--holder-reoder-background);
+  box-sizing: border-box;
+  border: 0.25px solid var(--holder-reoder-border);
+}
+.ui-listview.ui-snapshot li.ui-listview-helper::after {
+  display: none;
+}
+.ui-listview.ui-snapshot li.ui-listview-item.ui-listview-holder {
+  background: none;
+}
+.ui-listview.ui-snapshot li.ui-listview-item-moved {
+  opacity: 0.75;
+  transition: opacity 0.1s;
+}
+.ui-listview.ui-snapshot li:nth-last-child(2) {
+  transition: none;
+}
+.ui-listview.ui-activate-handlers li .ui-listview-handler {
+  -webkit-animation: button-handler-activate 200ms linear alternate;
+  animation: button-handler-activate 200ms linear alternate;
+}
+.ui-listview.ui-deactivate-handlers li .ui-listview-handler {
+  -webkit-animation: button-handler-deactivate 200ms linear alternate;
+  animation: button-handler-deactivate 200ms linear alternate;
+}
+.ui-listview.ui-cancel-animation li .ui-listview-handler {
+  -webkit-animation: none;
+  animation: none;
+}
+.ui-listview[data-colored-background='false'] {
+  background-color: var(--background-area-color);
+}
+.ui-listview[data-colored-background='false'] li:not(.ui-group-index) {
+  border-bottom: 1px solid #e6e6e6;
+  box-sizing: border-box;
+}
+@-webkit-keyframes button-handler-activate {
+  0% {
+    margin-right: -40px;
+  }
+  100% {
+    margin-right: 0;
+  }
+}
+@keyframes button-handler-activate {
+  0% {
+    margin-right: -40px;
+  }
+  100% {
+    margin-right: 0;
+  }
+}
+@-webkit-keyframes button-handler-deactivate {
+  0% {
+    margin-right: 0;
+  }
+  100% {
+    margin-right: -40px;
+  }
+}
+@keyframes button-handler-deactivate {
+  0% {
+    margin-right: 0;
+  }
+  100% {
+    margin-right: -40px;
+  }
+}
+.ui-page-indicator {
+  display: block;
+  position: absolute;
+  left: 50%;
+  bottom: 10px;
+  -webkit-transform: translate3d(-50%, 0, 0);
+  -ms-transform: translate3d(-50%, 0, 0);
+  transform: translate3d(-50%, 0, 0);
+}
+.ui-page-indicator-item {
+  position: relative;
+  display: inline-block;
+  width: 16px;
+  height: 16px;
+  -webkit-mask-image: -webkit-radial-gradient(black 4px, transparent 5.5px);
+  -webkit-transform: scale3d(0.7, 0.7, 1);
+  -ms-transform: scale3d(0.7, 0.7, 1);
+  transform: scale3d(0.7, 0.7, 1);
+  background-color: var(--primary-dark-color);
+  margin-right: 10px;
+  transition-duration: 150ms;
+}
+.ui-page-indicator-item:last-child {
+  margin-right: 0;
+}
+.ui-page-indicator-item.ui-page-indicator-active {
+  background-color: var(--primary-dark-color);
+  -webkit-transform: scale3d(1, 1, 1);
+  -ms-transform: scale3d(1, 1, 1);
+  transform: scale3d(1, 1, 1);
+  transition-duration: 150ms;
+}
+.ui-page-indicator-dashed .ui-page-indicator-item {
+  position: relative;
+  display: inline-block;
+  width: 20px;
+  height: 20px;
+  -webkit-mask-image: url("images/core_page_indicator_off.png");
+          mask-image: url("images/core_page_indicator_off.png");
+  -webkit-transform: rotate(0deg);
+  -ms-transform: rotate(0deg);
+  transform: rotate(0deg);
+  background-color: var(--primary-dark-color);
+  margin-right: 1px;
+  transition-duration: 150ms;
+  -webkit-mask-size: 20px;
+  -moz-mask-size: 20px;
+  -ms-mask-size: 20px;
+  -o-mask-size: 20px;
+  mask-size: 20px;
+}
+.ui-page-indicator-dashed .ui-page-indicator-item::before {
+  content: "";
+  position: absolute;
+  width: 20px;
+  height: 20px;
+  -webkit-mask-image: url("images/core_page_indicator_off_ef.png");
+          mask-image: url("images/core_page_indicator_off_ef.png");
+  -webkit-mask-size: 20px;
+  -moz-mask-size: 20px;
+  -ms-mask-size: 20px;
+  -o-mask-size: 20px;
+  mask-size: 20px;
+}
+.ui-page-indicator-dashed .ui-page-indicator-item:last-child {
+  margin-right: 0;
+}
+.ui-page-indicator-dashed .ui-page-indicator-item.ui-page-indicator-active {
+  background-color: var(--primary-dark-color);
+  -webkit-transform: rotate(90deg);
+  -ms-transform: rotate(90deg);
+  transform: rotate(90deg);
+  transition-duration: 150ms;
+}
+tau-progress {
+  display: block;
+}
+.ui-progress-container {
+  width: 360px;
+  height: inherit;
+  position: absolute;
+  top: 50%;
+  -webkit-transform: translateY(-50%);
+      -ms-transform: translateY(-50%);
+          transform: translateY(-50%);
+  box-sizing: border-box;
+}
+.ui-progress-bar {
+  position: relative;
+  min-width: 12px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  height: 32px;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -ms-grid-column-align: center;
+      justify-items: center;
+}
+.ui-progress-bar .ui-progress-current-value {
+  font-size: 36px;
+}
+.ui-progress-text {
+  padding-top: 17px;
+  display: block;
+  font-size: 15px;
+  text-align: center;
+  color: var(--text-color);
+}
+.ui-progress-bar-labels-top {
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-progress-bar-labels-bottom {
+  -webkit-order: 3;
+      -ms-flex-order: 3;
+          order: 3;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-progress-bar-value-bg {
+  height: 3px;
+  max-height: 3px;
+  width: 100%;
+  position: relative;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  background-color: var(--progress-bar-bg-color);
+  border-radius: 1.5px;
+}
+.ui-progress-bar-label span ~ span {
+  margin-left: 2px;
+}
+.ui-progress-bar-label-left-bottom {
+  padding: 4px 0 0;
+  color: var(--text-secondary-color);
+  font-size: 16px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: left;
+  line-height: normal;
+}
+.ui-progress-bar-label-right-bottom {
+  padding: 4px 0 0;
+  color: var(--text-secondary-color);
+  font-size: 16px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: right;
+  line-height: normal;
+}
+.ui-progress-bar-label-right-top {
+  padding: 0 0 4px;
+  color: var(--progress-bar-color);
+  font-size: 16px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: right;
+  line-height: normal;
+}
+.ui-progress-bar-value {
+  height: 3px;
+  position: absolute;
+  left: 0;
+  top: 0;
+  background-color: var(--progress-bar-color);
+  border-radius: 1.5px;
+}
+.ui-progress-circle.ui-progress-circle-full {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+.ui-progress-circle.ui-progress-circle-large {
+  width: 124px;
+  height: 124px;
+}
+.ui-progress-circle.ui-progress-circle-medium {
+  width: 56px;
+  height: 56px;
+}
+.ui-progress-circle.ui-progress-circle-small {
+  width: 44px;
+  height: 44px;
+}
+.ui-progress-circle {
+  position: relative;
+  display: inline-block;
+  box-sizing: border-box;
+}
+.ui-progress-circle * {
+  pointer-events: none;
+}
+.ui-progress-circle .ui-progress-circle-value.ui-progress-circle-half {
+  box-sizing: border-box;
+  clip: rect(auto, auto, auto, auto);
+}
+.ui-progress-circle .ui-progress-circle-value.ui-progress-circle-half .ui-progress-circle-value-right {
+  -webkit-transform: rotate(180deg);
+      -ms-transform: rotate(180deg);
+          transform: rotate(180deg);
+}
+.ui-progress-circle .ui-progress-circle-value {
+  clip: rect(0, 1em, 1em, 0.5em);
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  box-sizing: border-box;
+}
+.ui-progress-circle .ui-progress-circle-value .ui-progress-circle-value-left {
+  border: 2px solid var(--primary-color);
+  border-radius: 50%;
+  clip: rect(0, 0.5em, 1em, 0);
+  height: 100%;
+  width: 100%;
+  position: absolute;
+  box-sizing: border-box;
+}
+.ui-progress-circle .ui-progress-circle-value .ui-progress-circle-value-right {
+  border: 2px solid var(--primary-color);
+  border-radius: 50%;
+  clip: rect(0, 0.5em, 1em, 0);
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  box-sizing: border-box;
+}
+.ui-progress-circle .ui-progress-circle-bg {
+  border: 2px solid var(--progress-background-color);
+  border-radius: 50%;
+  width: 100%;
+  height: 100%;
+  box-sizing: border-box;
+}
+.ui-indeterminate-bar {
+  overflow: hidden;
+  position: relative;
+  height: 3px;
+  border-radius: 1.5px;
+  background-color: var(--progress-bar-bg-color);
+}
+.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate {
+  position: relative;
+  top: 0;
+  height: 100%;
+  padding: 0;
+  background-color: transparent;
+  border-radius: 1.5px;
+}
+.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate::before {
+  content: "";
+  position: absolute;
+  width: 46%;
+  left: 0;
+  top: 0;
+  height: 100%;
+  background-color: var(--progress-bar-color);
+  -webkit-animation: indeterminate-bar1 1200ms infinite linear;
+          animation: indeterminate-bar1 1200ms infinite linear;
+}
+.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate::after {
+  content: "";
+  position: absolute;
+  width: 46%;
+  left: 93%;
+  top: 0;
+  height: 100%;
+  background-color: var(--progress-bar-color);
+  -webkit-animation: indeterminate-bar2 1200ms infinite linear;
+          animation: indeterminate-bar2 1200ms infinite linear;
+}
+@-webkit-keyframes indeterminate-bar1 {
+  0% {
+    left: -30%;
+  }
+  74.9% {
+    left: 100%;
+    opacity: 1;
+  }
+  75% {
+    left: -70%;
+    opacity: 0;
+  }
+  75.1% {
+    left: -70%;
+    opacity: 1;
+  }
+  100% {
+    left: -30%;
+  }
+}
+@keyframes indeterminate-bar1 {
+  0% {
+    left: -30%;
+  }
+  74.9% {
+    left: 100%;
+    opacity: 1;
+  }
+  75% {
+    left: -70%;
+    opacity: 0;
+  }
+  75.1% {
+    left: -70%;
+    opacity: 1;
+  }
+  100% {
+    left: -30%;
+  }
+}
+@-webkit-keyframes indeterminate-bar2 {
+  0% {
+    left: 93%;
+  }
+  59.9% {
+    left: 232%;
+    opacity: 1;
+  }
+  60% {
+    left: -46%;
+    opacity: 0;
+  }
+  60.1% {
+    left: -46%;
+    opacity: 1;
+  }
+  100% {
+    left: 93%;
+  }
+}
+@keyframes indeterminate-bar2 {
+  0% {
+    left: 93%;
+  }
+  59.9% {
+    left: 232%;
+    opacity: 1;
+  }
+  60% {
+    left: -46%;
+    opacity: 0;
+  }
+  60.1% {
+    left: -46%;
+    opacity: 1;
+  }
+  100% {
+    left: 93%;
+  }
+}
+@-webkit-keyframes rotating {
+  from {
+    -webkit-transform: rotate(0);
+            transform: rotate(0);
+  }
+  to {
+    -webkit-transform: rotate(360deg);
+            transform: rotate(360deg);
+  }
+}
+@keyframes rotating {
+  from {
+    -webkit-transform: rotate(0);
+            transform: rotate(0);
+  }
+  to {
+    -webkit-transform: rotate(360deg);
+            transform: rotate(360deg);
+  }
+}
+.ui-indeterminate-circle {
+  box-sizing: border-box;
+  margin: auto;
+  -webkit-animation: rotating 2s linear infinite;
+          animation: rotating 2s linear infinite;
+}
+.ui-indeterminate-circle::before {
+  content: "";
+  border-top-style: solid;
+  border-left-style: solid;
+  border-color: var(--progress-circle-second-color);
+  border-radius: 100% 0 0 0;
+  display: block;
+}
+.ui-indeterminate-circle::after {
+  content: "";
+  position: relative;
+  left: 50%;
+  border-right-style: solid;
+  border-bottom-style: solid;
+  border-color: var(--primary-color);
+  display: block;
+  border-radius: 100% 0;
+}
+.ui-indeterminate-circle-small-title {
+  width: 16px;
+  height: 16px;
+}
+.ui-indeterminate-circle-small-title::before,
+.ui-indeterminate-circle-small-title::after {
+  width: 6.5px;
+  height: 6.5px;
+}
+.ui-indeterminate-circle-small-title::before {
+  border-top-width: 1.5px;
+  border-left-width: 1.5px;
+}
+.ui-indeterminate-circle-small-title::after {
+  border-right-width: 1.5px;
+  border-bottom-width: 1.5px;
+}
+.ui-indeterminate-circle-small {
+  width: 24px;
+  height: 24px;
+}
+.ui-indeterminate-circle-small::before,
+.ui-indeterminate-circle-small::after {
+  width: 10px;
+  height: 10px;
+}
+.ui-indeterminate-circle-small::before {
+  border-top-width: 2px;
+  border-left-width: 2px;
+}
+.ui-indeterminate-circle-small::after {
+  border-right-width: 2px;
+  border-bottom-width: 2px;
+}
+.ui-indeterminate-circle-medium {
+  width: 48px;
+  height: 48px;
+}
+.ui-indeterminate-circle-medium::before,
+.ui-indeterminate-circle-medium::after {
+  width: 21px;
+  height: 21px;
+}
+.ui-indeterminate-circle-medium::before {
+  border-top-width: 3px;
+  border-left-width: 3px;
+}
+.ui-indeterminate-circle-medium::after {
+  border-right-width: 3px;
+  border-bottom-width: 3px;
+}
+.ui-indeterminate-circle-large {
+  width: 60px;
+  height: 60px;
+}
+.ui-indeterminate-circle-large::before,
+.ui-indeterminate-circle-large::after {
+  width: 27px;
+  height: 27px;
+}
+.ui-indeterminate-circle-large::before {
+  border-top-width: 3px;
+  border-left-width: 3px;
+}
+.ui-indeterminate-circle-large::after {
+  border-right-width: 3px;
+  border-bottom-width: 3px;
+}
+.ui-listview .ui-li-has-progress {
+  height: 4px;
+  padding: 28px 0;
+}
+.ui-listview .ui-li-has-progress-with-labels {
+  height: 4px;
+  padding: 34px 0;
+}
+.ui-scrollview-view > .ui-progress-container {
+  padding-left: 56px;
+  padding-right: 56px;
+}
+.ui-listview .ui-group-index + .ui-li-static {
+  padding-top: 16.5px;
+  padding-bottom: 16.5px;
+}
+.ui-listview .ui-group-index ~ .ui-li-static > input[type=checkbox] {
+  position: absolute;
+  right: 16px;
+  top: 17.5px;
+}
+tau-textenveloper {
+  display: block;
+}
+.ui-text-enveloper {
+  z-index: 1;
+  position: relative;
+  background-color: transparent;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  outline: none;
+  -webkit-flex-wrap: wrap;
+      -ms-flex-wrap: wrap;
+          flex-wrap: wrap;
+  overflow-x: visible;
+}
+.ui-text-enveloper.ui-text-enveloper-with-container {
+  -webkit-flex-wrap: nowrap;
+      -ms-flex-wrap: nowrap;
+          flex-wrap: nowrap;
+  -webkit-align-content: stretch;
+      -ms-flex-line-pack: stretch;
+          align-content: stretch;
+}
+.ui-text-enveloper.ui-text-enveloper-with-container .ui-text-enveloper-container {
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+  -webkit-flex-shrink: 1;
+      -ms-flex-negative: 1;
+          flex-shrink: 1;
+  -webkit-flex-basis: 100%;
+      -ms-flex-preferred-size: 100%;
+          flex-basis: 100%;
+  -webkit-flex-wrap: wrap;
+      -ms-flex-wrap: wrap;
+          flex-wrap: wrap;
+  white-space: pre-wrap;
+  overflow: visible;
+}
+.ui-text-enveloper .ui-text-enveloper-start {
+  line-height: 27px;
+  height: 27px;
+  font-size: 20px;
+  margin-top: 6.5px;
+  color: var(--primary-color);
+  margin-right: 10px;
+  display: inline-block;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn {
+  position: relative;
+  line-height: 27px;
+  height: 40px;
+  border-radius: 7.5px;
+  font-size: 20px;
+  margin-top: -1px;
+  padding: 7px 6px 6px;
+  margin-left: -6px;
+  min-height: 40px;
+  vertical-align: top;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  background-color: transparent;
+  color: var(--primary-color);
+  overflow: auto;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded::before,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn::before {
+  top: 50%;
+  left: 50%;
+  width: 100%;
+  height: 100%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+  border-radius: 0;
+  opacity: 0;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded::after,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn::after {
+  position: absolute;
+  content: "";
+  top: 50%;
+  left: 50%;
+  width: 100%;
+  height: 100%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+  opacity: 0;
+  transition: opacity linear 200ms;
+  -webkit-mask-box-image-source: url('images/nine-patch/core_focus_round.png');
+  -webkit-mask-box-image-slice: 20 20 fill;
+  -moz-mask-box-image-slice: 20 20 fill;
+  -ms-mask-box-image-slice: 20 20 fill;
+  -o-mask-box-image-slice: 20 20 fill;
+  mask-box-image-slice: 20 20 fill;
+  background-color: var(--text-input-underline-active);
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-blur,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-blur {
+  display: none;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-blur + span,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-blur + span {
+  display: none;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-selected::after,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-selected::after {
+  opacity: 1;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-btn-active::before,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-btn-active::before {
+  opacity: 1;
+  background-color: var(--ripple-color);
+  -webkit-animation: navigation_press_animation linear 315ms;
+  animation: navigation_press_animation linear 315ms;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-btn-active.ui-btn-inactive::before,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-btn-active.ui-btn-inactive::before {
+  -webkit-animation: navigation_pressup_animation linear 200ms;
+  animation: navigation_pressup_animation linear 200ms;
+}
+.ui-text-enveloper .ui-text-enveloper-btn.ui-btn:not(.ui-inline) {
+  margin-left: 3px;
+  padding-left: 5px;
+  border-bottom: 1px solid var(--primary-color);
+  overflow: visible;
+  border-radius: 0;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: left;
+  margin-bottom: 1px;
+}
+.ui-text-enveloper .ui-text-enveloper-btn.ui-btn:not(.ui-inline) + .ui-text-enveloper-input {
+  display: block;
+  position: absolute;
+  width: 100%;
+  text-indent: 100%;
+  height: 27px;
+}
+.ui-text-enveloper .ui-text-enveloper-btn-separator {
+  display: inline-block;
+  margin: 0 6px;
+  width: 7.5px;
+}
+.ui-text-enveloper .ui-text-enveloper-btn-separator::after {
+  content: "";
+  display: block;
+  position: absolute;
+  width: 7.5px;
+  height: 16.5px;
+  margin-top: -15px;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-image: url(images/core_contact_div.png);
+          mask-image: url(images/core_contact_div.png);
+  background-color: var(--control-active-color);
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+}
+.ui-text-enveloper .ui-text-enveloper-btn-expanded {
+  color: var(--control-inactive-color);
+}
+.ui-text-enveloper .ui-text-enveloper-slash {
+  margin-top: -1px;
+  width: 13.5px;
+  height: 40px;
+  opacity: 1;
+  transition: opacity linear 200ms;
+  display: inline-block;
+  overflow: auto;
+}
+.ui-text-enveloper .ui-text-enveloper-slash::after {
+  content: "";
+  width: 7.5px;
+  margin-top: 12px;
+  height: 16.5px;
+  position: absolute;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-image: url(images/core_contact_div.png);
+          mask-image: url(images/core_contact_div.png);
+  background-color: var(--control-active-color);
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+}
+.ui-text-enveloper .ui-text-enveloper-slash.ui-text-enveloper-slash-hidden {
+  opacity: 0;
+}
+.ui-text-enveloper .ui-text-enveloper-input {
+  display: inline-block;
+  width: auto;
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+  min-width: 60px;
+  line-height: 27px;
+  height: 27px;
+  margin-top: 6px;
+  font-size: 20px;
+  background-color: transparent;
+  margin-left: -5px;
+  margin-bottom: 0;
+}
+.ui-text-enveloper .ui-text-enveloper-input-new-line {
+  clear: left;
+  width: 100%;
+}
+.ui-text-enveloper .ui-text-enveloper-input-new-line .ui-text-enveloper-input {
+  margin-left: 0;
+}
+.ui-text-enveloper .ui-text-enveloper-input-new-line.ui-text-enveloper-input-blur {
+  display: none;
+}
+.ui-text-enveloper input.ui-text-input ~ .ui-text-input-clear {
+  top: auto;
+}
+.ui-listview .ui-li-static .ui-text-enveloper,
+.ui-listview .ui-li-flex .ui-text-enveloper {
+  margin-top: -7px;
+  margin-bottom: -6px;
+  margin-right: 8.5px;
+  width: 100%;
+}
+.ui-listview .ui-li-static .ui-text-enveloper input.ui-text-input + .ui-text-input-textline,
+.ui-listview .ui-li-flex .ui-text-enveloper input.ui-text-input + .ui-text-input-textline {
+  margin-bottom: 0;
+}
+tau-gridview {
+  display: block;
+  list-style-type: disc;
+}
+.ui-gridview {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  padding: 0;
+  margin: 0;
+  list-style: none;
+}
+.ui-gridview .ui-gridview-item {
+  position: absolute;
+  border: 0.25px solid var(--grid-border-color);
+  box-sizing: border-box;
+  opacity: 0;
+  border-radius: 26px;
+  overflow: hidden;
+}
+.ui-gridview .ui-gridview-item.ui-gridview-item-active {
+  transition: -webkit-transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 1);
+  transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 1);
+  transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 1), -webkit-transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 1);
+  opacity: 1;
+}
+.ui-gridview .ui-gridview-item.ui-gridview-helper {
+  transition: none;
+  -webkit-transform: translate3d(0, 0, 0);
+          transform: translate3d(0, 0, 0);
+}
+.ui-gridview .ui-gridview-item .ui-gridview-handler {
+  display: block;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  left: 0;
+  top: 0;
+  opacity: 0;
+}
+.ui-gridview .ui-gridview-item > label {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+.ui-gridview .ui-gridview-item > label.ui-gridview-image-checked {
+  background-color: var(--checkbox-image-checked);
+}
+.ui-gridview .ui-gridview-item > label > input[type="checkbox"] {
+  position: absolute;
+  margin: 8px 0 0 8px;
+  background-image: url(images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg);
+  background-size: 100%;
+  background-repeat: no-repeat;
+  opacity: 1;
+}
+.ui-gridview .ui-gridview-item > label > input[type="checkbox"]:checked {
+  background-image: url(images/3_Controllers/gallery_btn_check_bg_mtrl.svg);
+}
+.ui-gridview .ui-gridview-item > label > input[type="checkbox"]::after {
+  background-color: var(--color-white);
+}
+.ui-gridview .ui-gridview-item > label > input[type="checkbox"]:disabled {
+  opacity: 0.4;
+}
+.ui-gridview .ui-gridview-item .ui-gridview-image {
+  display: block;
+  width: 100%;
+  height: auto;
+  pointer-events: none;
+}
+.ui-gridview .ui-gridview-item.ui-gridview-item-has-label .ui-gridview-image {
+  -webkit-transform: translateY(-28.5px);
+      -ms-transform: translateY(-28.5px);
+          transform: translateY(-28.5px);
+}
+.ui-gridview .ui-gridview-item .ui-gridview-label {
+  position: absolute;
+  width: calc(100% -  30px);
+  margin: auto;
+  padding: 0 15px;
+  font-family: Roboto-Regular;
+  font-size: 16px;
+  color: var(--grid-label-color);
+  text-align: left;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  bottom: 0;
+  background-color: var(--background-area-color);
+  height: 57px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-gridview .ui-gridview-item .ui-gridview-label p {
+  margin: 0;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+.ui-gridview .ui-gridview-item .ui-gridview-label p:nth-child(1) {
+  font-size: 16px;
+  color: var(--grid-label-color);
+}
+.ui-gridview .ui-gridview-item .ui-gridview-label p:nth-child(2) {
+  margin-top: 3px;
+  font-size: 13px;
+  color: var(--grid-label-secondary-color);
+}
+.ui-gridview .ui-gridview-item .ui-gridview-badge {
+  position: absolute;
+  border-radius: 25px;
+  min-width: 11px;
+  background-color: var(--accent-badge);
+  color: var(--color-white);
+  top: 4.5px;
+  right: 4.5px;
+  padding: 3px 7px;
+  font-size: 11px;
+  text-align: center;
+}
+.ui-gridview .ui-gridview-item.ui-focus {
+  -webkit-filter: invert(0.2);
+          filter: invert(0.2);
+}
+.ui-gridview.ui-gridview-label-in .ui-gridview-label {
+  position: absolute;
+  bottom: 6px;
+  display: block;
+  color: var(--grid-label-color);
+}
+.ui-gridview.ui-gridview-label-out .ui-gridview-label {
+  display: block;
+  margin: 0;
+  color: var(--grid-label-color);
+  margin-bottom: 11.5px;
+}
+.ui-gridview.ui-gridview-reorder .ui-gridview-item .ui-gridview-handler {
+  opacity: 1;
+}
+.ui-gridview-cols::after {
+  content: "2";
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  opacity: 0;
+}
+.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) {
+  box-sizing: content-box;
+}
+.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+@-webkit-keyframes grid_show_item {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@keyframes grid_show_item {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@media (orientation: portrait) {
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview {
+    min-height: 509px;
+  }
+}
+@media (orientation: portrait) and (min-width: 480px) and (max-width: 959px) {
+  .ui-gridview-cols::after {
+    content: "3";
+  }
+}
+@media (orientation: landscape) {
+  .ui-gridview-cols::after {
+    content: "4";
+  }
+}
+@media (min-width: 960px) {
+  .ui-gridview-cols::after {
+    content: "5";
+  }
+}
+.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper {
+  width: 100%;
+  height: auto;
+  overflow: auto;
+  border-radius: 26px;
+}
+.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper .ui-popup-content.ui-popup-content-gridview {
+  padding: 0;
+  margin: 0;
+  height: 135px;
+}
+.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper .ui-popup-content.ui-popup-content-gridview-multiple {
+  padding: 0;
+  margin: 0;
+  height: 252px;
+}
+@media (orientation: landscape) {
+  .ui-popup.ui-popup-gridview {
+    width: 360px;
+    left: 70px;
+  }
+  .ui-gridview-image {
+    display: block;
+    width: 90.5px;
+    height: 90.5px;
+    pointer-events: none;
+  }
+}
+@media (min-width: 1920px) {
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out {
+    min-width: 1920px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out .ui-gridview-item .ui-gridview-image {
+    width: 240px;
+    height: 238px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out .ui-gridview-item .ui-gridview-label {
+    height: 39px;
+    line-height: 39px;
+    padding: 0 10px;
+    margin: 0;
+    margin-bottom: 23px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) {
+    min-width: 1920px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item {
+    width: 240px;
+    height: 238px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item .ui-gridview-image {
+    width: 240px;
+    height: 238px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item .ui-gridview-label {
+    height: 39px;
+    line-height: 39px;
+    padding: 0 10px;
+  }
+}
+.ui-welcome-page .ui-content .ui-scrollview-view {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  text-align: center;
+  padding-bottom: 41.5px;
+}
+.ui-welcome-page .ui-content .ui-welcome-icon {
+  height: 80px;
+  width: auto;
+  -webkit-flex: 0 0 auto;
+  -moz-flex: 0 0 auto;
+  -ms-flex: 0 0 auto;
+  -o-flex: 0 0 auto;
+  flex: 0 0 auto;
+  -webkit-align-self: center;
+  -ms-align-self: center;
+  -o-align-self: center;
+  -ms-flex-item-align: center;
+      -ms-grid-row-align: center;
+      align-self: center;
+}
+.ui-welcome-page .ui-content .ui-welcome-primary-text,
+.ui-welcome-page .ui-content .ui-welcome-secondary-text {
+  margin: 0 20px;
+  font-weight: normal;
+}
+.ui-welcome-page .ui-content .ui-welcome-primary-text {
+  color: var(--text-color);
+  line-height: 33.5px;
+  font-size: 24.5px;
+}
+.ui-welcome-page .ui-content .ui-welcome-secondary-text {
+  color: var(--text-secondary-color);
+  line-height: 21.5px;
+  font-size: 17.5px;
+}
+.ui-welcome-page .ui-content .ui-welcome-primary-text + .ui-welcome-secondary-text {
+  margin-top: 29px;
+}
+.ui-welcome-page .ui-footer {
+  height: 86px;
+  text-align: center;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+}
+.ui-welcome-page .ui-footer button,
+.ui-welcome-page .ui-footer .ui-btn-welcome {
+  min-width: 248px;
+  height: 52px;
+  background-color: var(--primary-color);
+  display: inline-block;
+  width: auto;
+  -webkit-flex: 0 0 auto;
+  -moz-flex: 0 0 auto;
+  -ms-flex: 0 0 auto;
+  -o-flex: 0 0 auto;
+  flex: 0 0 auto;
+}
+.ui-welcome-page .ui-footer button:active,
+.ui-welcome-page .ui-footer .ui-btn-welcome:active,
+.ui-welcome-page .ui-footer button:focus,
+.ui-welcome-page .ui-footer .ui-btn-welcome:focus {
+  background-color: var(--ripple-color);
+}
+.ui-welcome-page .ui-footer button[disabled],
+.ui-welcome-page .ui-footer .ui-btn-welcome[disabled],
+.ui-welcome-page .ui-footer button.ui-disabled,
+.ui-welcome-page .ui-footer .ui-btn-welcome.ui-disabled {
+  background-color: var(--control-inactive-color);
+}
+.ui-dimmer {
+  position: relative;
+  border: 60px solid rgba(0, 151, 216, 0.5);
+  border-radius: 100%;
+  max-width: 720px;
+  /* @TODO: temp fix for mobile on tv usage */
+}
+.ui-dimmer::after {
+  display: block;
+  content: " ";
+  padding-bottom: 100%;
+}
+.ui-dimmer .ui-dimmer-hidden {
+  display: none;
+}
+.ui-dimmer .ui-dimmer-text {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+      -ms-transform: translate(-50%, -50%);
+          transform: translate(-50%, -50%);
+}
+.ui-dimmer.ui-dimmer-lightbulb {
+  width: 50%;
+  left: 50%;
+  -webkit-transform: translateX(-50%);
+      -ms-transform: translateX(-50%);
+          transform: translateX(-50%);
+  padding-bottom: 50%;
+  border-radius: 0;
+  border: none;
+  background-image: url("images/dimmer/lightbulb.png");
+  background-size: contain;
+  display: block;
+}
+.ui-dimmer.ui-dimmer-lightbulb::after {
+  display: none;
+}
+.ui-dimmer.ui-dimmer-lightbulb .ui-dimmer-lightbulb-light {
+  display: block;
+  position: absolute;
+  width: 60%;
+  height: 60%;
+  left: 50%;
+  top: 5%;
+  opacity: 0.7;
+  -webkit-transform: translateX(-50%);
+      -ms-transform: translateX(-50%);
+          transform: translateX(-50%);
+  background-color: yellow;
+  -webkit-filter: blur(1.3rem);
+          filter: blur(1.3rem);
+  border-radius: 50%;
+  border: none;
+  transition: background-color 0.3s;
+}
+.wrapper {
+  -webkit-perspective: 600px;
+          perspective: 600px;
+  margin: 32px auto;
+  margin-top: 15%;
+  margin-right: 5%;
+  width: 100%;
+  height: 150px;
+}
+.wrapper_test {
+  -webkit-perspective: 600px;
+          perspective: 600px;
+  white-space: nowrap;
+}
+.outer {
+  transition: .8s;
+  -webkit-transform: rotateY(40deg);
+          transform: rotateY(40deg);
+  width: auto;
+  height: auto;
+  overflow-x: scroll;
+  margin-top: 10%;
+  margin-left: 30%;
+}
+.inner {
+  transition: .8s;
+  -webkit-transform: rotateY(40deg);
+          transform: rotateY(40deg);
+  margin-left: -15%;
+  width: auto;
+  height: auto;
+}
+.inner figure {
+  box-shadow: -3.5px 3.5px 1px -1.5px rgba(100, 100, 100, 0.5);
+  display: inline-block;
+}
+.inner img {
+  display: block;
+  width: 50px;
+  height: 50px;
+  max-width: 100%;
+  box-reflect: below 0 -webkit-gradient(linear, left bottom, left top, color-stop(0.05, rgba(255, 255, 255, 0.12)), color-stop(0.35, transparent));
+  -webkit-box-reflect: below 0 -webkit-gradient(linear, left bottom, left top, color-stop(0.05, rgba(255, 255, 255, 0.12)), color-stop(0.35, transparent));
+}
+.flipster {
+  display: block;
+  overflow-x: hidden;
+  overflow-y: visible;
+  position: relative;
+}
+.flipster:focus {
+  outline: none;
+}
+.flipster__container {
+  margin: 0;
+  padding: 0;
+  list-style-type: none;
+  position: relative;
+  display: block;
+  white-space: nowrap;
+  word-spacing: -0.25em;
+  -webkit-transform-origin: 50% 50%;
+      -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
+}
+.flipster__item {
+  margin: 0;
+  padding: 0;
+  list-style-type: none;
+  position: relative;
+  display: inline-block;
+  white-space: normal;
+  word-spacing: normal;
+  vertical-align: bottom;
+}
+.flipster__item img {
+  max-width: 100%;
+}
+.flipster--click .flipster__item--past {
+  cursor: pointer;
+}
+.flipster--click .flipster__item--future {
+  cursor: pointer;
+}
+.flipster__button {
+  position: absolute;
+  top: 50%;
+  display: block;
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  background: none;
+  border: none;
+  padding: 0;
+  z-index: 999;
+  cursor: pointer;
+  font-size: 7.5px;
+  opacity: 0.5;
+  transition: opacity 500ms ease;
+  margin: -1em 2em;
+}
+.flipster__button svg {
+  width: 2em;
+  stroke: currentColor;
+  fill: transparent;
+  stroke-width: 3;
+  stroke-linecap: round;
+}
+.flipster__button:hover {
+  opacity: 1;
+}
+.flipster__button:focus {
+  opacity: 1;
+}
+.flipster__button--prev {
+  left: 0;
+}
+.flipster__button--next {
+  right: 0;
+}
+.flipster__nav {
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
+  display: block;
+  margin: 0 0 4em;
+  text-align: center;
+  position: relative;
+}
+.flipster__nav__item {
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
+  display: inline-block;
+  margin: 0 0.25em;
+}
+.flipster__nav__link {
+  display: block;
+  color: inherit;
+  padding: 0.5em 1em;
+  position: relative;
+  overflow: hidden;
+  transition: all 250ms ease-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+}
+.flipster__nav__link::after {
+  content: '';
+  display: block;
+  background: #232221;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: -1;
+  -webkit-transform: translateY(100%) translateY(-0.25em);
+      -ms-transform: translateY(100%) translateY(-0.25em);
+          transform: translateY(100%) translateY(-0.25em);
+  transition: inherit;
+}
+.flipster__nav__link:hover {
+  color: #FFF;
+}
+.flipster__nav__link:hover::after {
+  -webkit-transform: translateY(0);
+      -ms-transform: translateY(0);
+          transform: translateY(0);
+}
+.flipster__nav__link:focus {
+  color: #FFF;
+}
+.flipster__nav__link:focus::after {
+  -webkit-transform: translateY(0);
+      -ms-transform: translateY(0);
+          transform: translateY(0);
+}
+.flipster__nav__item--current > .flipster__nav__link {
+  color: #FFF;
+}
+.flipster__nav__item--current > .flipster__nav__link::after {
+  -webkit-transform: translateY(0);
+      -ms-transform: translateY(0);
+          transform: translateY(0);
+}
+.flipster__nav__item--current .flipster__nav__child {
+  display: block;
+}
+.flipster__nav__child {
+  display: none;
+  position: absolute;
+  top: 100%;
+  left: 0;
+  right: 0;
+  margin-top: -0.5px;
+  padding: 0.5em;
+  background: #4e4441;
+  z-index: 1;
+}
+.flipster__nav__child .flipster__nav__link {
+  color: #FFF;
+}
+.flipster__nav__child .flipster__nav__link::after {
+  background: #FFF;
+}
+.flipster__nav__child .flipster__nav__link:hover {
+  color: #232221;
+}
+.flipster__nav__child .flipster__nav__link:focus {
+  color: #232221;
+}
+.flipster__nav__child .flipster__nav__item--current > .flipster__nav__link {
+  color: #232221;
+}
+.flipster--carousel .flipster__container {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+}
+.flipster--carousel .flipster__item {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  -webkit-perspective: 400px;
+          perspective: 400px;
+}
+.flipster--carousel .flipster__item__content {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+}
+.flipster--carousel .flipster__item--past {
+  opacity: 0;
+  transition-delay: 115ms;
+}
+.flipster--carousel .flipster__item--past .flipster__item__content {
+  -webkit-transform: translateX(100%) rotateY(-20deg) scale(0.5);
+          transform: translateX(100%) rotateY(-20deg) scale(0.5);
+}
+.flipster--carousel .flipster__item--future {
+  opacity: 0;
+  transition-delay: 115ms;
+}
+.flipster--carousel .flipster__item--future .flipster__item__content {
+  -webkit-transform: translateX(-100%) rotateY(20deg) scale(0.5);
+          transform: translateX(-100%) rotateY(20deg) scale(0.5);
+}
+.flipster--carousel .flipster__item--past-2 {
+  opacity: 0.6;
+  transition-delay: 20ms;
+}
+.flipster--carousel .flipster__item--past-2 .flipster__item__content {
+  -webkit-transform: translateX(25%) rotateY(40deg) scale(0.65);
+          transform: translateX(25%) rotateY(40deg) scale(0.65);
+}
+.flipster--carousel .flipster__item--future-2 {
+  opacity: 0.6;
+  transition-delay: 20ms;
+}
+.flipster--carousel .flipster__item--future-2 .flipster__item__content {
+  -webkit-transform: translateX(-25%) rotateY(-40deg) scale(0.65);
+          transform: translateX(-25%) rotateY(-40deg) scale(0.65);
+}
+.flipster--carousel .flipster__item--past-1 {
+  opacity: 0.6;
+  transition-delay: 20ms;
+}
+.flipster--carousel .flipster__item--past-1 .flipster__item__content {
+  -webkit-transform: rotateY(45deg) scale(0.8);
+          transform: rotateY(45deg) scale(0.8);
+}
+.flipster--carousel .flipster__item--future-1 {
+  opacity: 0.6;
+  transition-delay: 20ms;
+}
+.flipster--carousel .flipster__item--future-1 .flipster__item__content {
+  -webkit-transform: rotateY(-45deg) scale(0.8);
+          transform: rotateY(-45deg) scale(0.8);
+}
+.flipster--carousel .flipster__item--current .flipster__item__content {
+  -webkit-transform: translateX(0) rotateY(0deg) scale(1);
+          transform: translateX(0) rotateY(0deg) scale(1);
+  transition-delay: 60ms;
+}
+.flipster--carousel.no-rotate .flipster__item--past .flipster__item__content {
+  -webkit-transform: translateX(175%) scale(0.5);
+      -ms-transform: translateX(175%) scale(0.5);
+          transform: translateX(175%) scale(0.5);
+}
+.flipster--carousel.no-rotate .flipster__item--past-2 .flipster__item__content {
+  -webkit-transform: translateX(25%) scale(0.65);
+      -ms-transform: translateX(25%) scale(0.65);
+          transform: translateX(25%) scale(0.65);
+}
+.flipster--carousel.no-rotate .flipster__item--past-1 .flipster__item__content {
+  -webkit-transform: translateX(0%) scale(0.8);
+      -ms-transform: translateX(0%) scale(0.8);
+          transform: translateX(0%) scale(0.8);
+}
+.flipster--carousel.no-rotate .flipster__item--future .flipster__item__content {
+  -webkit-transform: translateX(-175%) scale(0.5);
+      -ms-transform: translateX(-175%) scale(0.5);
+          transform: translateX(-175%) scale(0.5);
+}
+.flipster--carousel.no-rotate .flipster__item--future-2 .flipster__item__content {
+  -webkit-transform: translateX(-25%) scale(0.65);
+      -ms-transform: translateX(-25%) scale(0.65);
+          transform: translateX(-25%) scale(0.65);
+}
+.flipster--carousel.no-rotate .flipster__item--future-1 .flipster__item__content {
+  -webkit-transform: translateX(0%) scale(0.8);
+      -ms-transform: translateX(0%) scale(0.8);
+          transform: translateX(0%) scale(0.8);
+}
+.flipster--coverflow .flipster__container {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  padding-bottom: 10%;
+}
+.flipster--coverflow .flipster__item {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  -webkit-perspective: 400px;
+          perspective: 400px;
+}
+.flipster--coverflow .flipster__item__content {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  -webkit-transform-origin: 50% 100%;
+      -ms-transform-origin: 50% 100%;
+          transform-origin: 50% 100%;
+  box-reflect: below 0 -webkit-gradient(linear, left bottom, left top, color-stop(0.05, rgba(255, 255, 255, 0.12)), color-stop(0.35, transparent));
+  -webkit-box-reflect: below 0 -webkit-gradient(linear, left bottom, left top, color-stop(0.05, rgba(255, 255, 255, 0.12)), color-stop(0.35, transparent));
+}
+.flipster--coverflow .flipster__item__content img:only-child {
+  display: block;
+}
+.flipster--coverflow .flipster__item--past .flipster__item__content {
+  -webkit-transform-origin: 0% 50%;
+      -ms-transform-origin: 0% 50%;
+          transform-origin: 0% 50%;
+  -webkit-transform: scale(0.75) rotateY(55deg);
+          transform: scale(0.75) rotateY(55deg);
+}
+.flipster--coverflow .flipster__item--future .flipster__item__content {
+  -webkit-transform-origin: 100% 50%;
+      -ms-transform-origin: 100% 50%;
+          transform-origin: 100% 50%;
+  -webkit-transform: scale(0.75) rotateY(-55deg);
+          transform: scale(0.75) rotateY(-55deg);
+}
+.flipster--coverflow .flip-current .flipster__item__content {
+  -webkit-transform: rotateY(0deg);
+          transform: rotateY(0deg);
+}
+.flipster--flat .flipster__container {
+  transition: all 400ms ease-in-out;
+}
+.flipster--flat .flipster__item {
+  transition: all 400ms ease-in-out;
+}
+.flipster--flat .flipster__item__content {
+  transition: all 400ms ease-in-out;
+}
+.flipster--flat .flipster__item--past {
+  opacity: 0.5;
+}
+.flipster--flat .flipster__item--past .flipster__item__content {
+  -webkit-transform: scale(0.75);
+      -ms-transform: scale(0.75);
+          transform: scale(0.75);
+}
+.flipster--flat .flipster__item--future {
+  opacity: 0.5;
+}
+.flipster--flat .flipster__item--future .flipster__item__content {
+  -webkit-transform: scale(0.75);
+      -ms-transform: scale(0.75);
+          transform: scale(0.75);
+}
+.flipster--wheel {
+  overflow: hidden;
+}
+.flipster--wheel .flipster__container {
+  transition: all 400ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  padding-bottom: 20%;
+}
+.flipster--wheel .flipster__item__content {
+  transition: all 400ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  -webkit-transform-origin: 50% 100%;
+      -ms-transform-origin: 50% 100%;
+          transform-origin: 50% 100%;
+}
+.flipster--wheel .flipster__item__content img:only-child {
+  display: block;
+}
+.flipster--wheel .flipster__item--past .flipster__item__content {
+  -webkit-transform-origin: 100% 100%;
+      -ms-transform-origin: 100% 100%;
+          transform-origin: 100% 100%;
+  opacity: 0;
+  -webkit-transform: rotateZ(-80deg) translate(-170%, 110%);
+      -ms-transform: rotate(-80deg) translate(-170%, 110%);
+          transform: rotateZ(-80deg) translate(-170%, 110%);
+}
+.flipster--wheel .flipster__item--future .flipster__item__content {
+  -webkit-transform-origin: 0% 100%;
+      -ms-transform-origin: 0% 100%;
+          transform-origin: 0% 100%;
+  opacity: 0;
+  -webkit-transform: rotateZ(80deg) translate(170%, 110%);
+      -ms-transform: rotate(80deg) translate(170%, 110%);
+          transform: rotateZ(80deg) translate(170%, 110%);
+}
+.flipster--wheel .flipster__item--past-3 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(-60deg) translate(-70%, 75%);
+      -ms-transform: rotate(-60deg) translate(-70%, 75%);
+          transform: rotateZ(-60deg) translate(-70%, 75%);
+}
+.flipster--wheel .flipster__item--future-3 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(60deg) translate(70%, 75%);
+      -ms-transform: rotate(60deg) translate(70%, 75%);
+          transform: rotateZ(60deg) translate(70%, 75%);
+}
+.flipster--wheel .flipster__item--past-2 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(-40deg) translate(-17%, 30%);
+      -ms-transform: rotate(-40deg) translate(-17%, 30%);
+          transform: rotateZ(-40deg) translate(-17%, 30%);
+}
+.flipster--wheel .flipster__item--future-2 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(40deg) translate(17%, 30%);
+      -ms-transform: rotate(40deg) translate(17%, 30%);
+          transform: rotateZ(40deg) translate(17%, 30%);
+}
+.flipster--wheel .flipster__item--past-1 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(-20deg);
+      -ms-transform: rotate(-20deg);
+          transform: rotateZ(-20deg);
+}
+.flipster--wheel .flipster__item--future-1 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(20deg);
+      -ms-transform: rotate(20deg);
+          transform: rotateZ(20deg);
+}
+.flipster--wheel .flip-current .flipster__item__content {
+  -webkit-transform: rotateX(0deg);
+          transform: rotateX(0deg);
+}
+.ui-graph {
+  width: 100%;
+  height: 250px;
+}
+.ui-toggle-slider-container {
+  position: relative;
+  display: inline-block;
+  width: 50px;
+  height: 26px;
+}
+.ui-toggle-slider-container input {
+  background-color: #CCCCCC;
+  transition: 0.5s;
+  border-radius: 26px;
+  width: 50px;
+  height: 26px;
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  outline: 0;
+  margin: 0;
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
+}
+.ui-toggle-slider-container input:checked {
+  background-color: #3695DD;
+}
+.ui-toggle-slider-container input:disabled {
+  background-color: W015L1D;
+}
+.ui-toggle-slider-container .ui-toggle-slider:before {
+  position: absolute;
+  content: '';
+  height: 22px;
+  width: 22px;
+  left: 1px;
+  bottom: 2px;
+  background-color: #FFFFFF;
+  transition: 0.5s;
+  border-radius: 50%;
+  pointer-events: none;
+}
+.ui-toggle-slider-container input:checked + .ui-toggle-slider:before {
+  -webkit-transform: translateX(25.5px);
+      -ms-transform: translateX(25.5px);
+          transform: translateX(25.5px);
+}
+.ui-coverflow:focus {
+  background-color: var(--ripple-color);
+}
+.ui-spin {
+  position: relative;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  height: 164px;
+  background-color: transparent;
+  overflow: hidden;
+  font-size: 32px;
+  padding: 0;
+  box-sizing: content-box;
+  width: 50px;
+}
+.ui-spin-item {
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  background-color: transparent;
+  width: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  color: var(--primary-dark-color);
+  opacity: var(--spin-item-opacity) !important;
+  -webkit-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  font-family: Roboto-Medium;
+}
+.ui-spin-item-selected {
+  opacity: 1 !important;
+}
+.ui-spin-carousel-item {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-spin-enabling .ui-spin-item {
+  transition: 300ms opacity linear;
+}
+.ui-spin-placeholder {
+  opacity: 0;
+  pointer-events: none;
+  position: absolute;
+  display: none;
+}
+.ui-time-picker {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  height: 164px;
+  -webkit-justify-content: space-evenly;
+      -ms-flex-pack: space-evenly;
+          justify-content: space-evenly;
+}
+.ui-time-picker[data-format="12"] .ui-time-picker-container {
+  width: 28%;
+}
+.ui-time-picker[data-format="12"] .ui-time-picker-container-hour::after {
+  content: ":";
+  height: 164px;
+  width: 4%;
+  font-size: 32px;
+  color: var(--primary-dark-color);
+  position: absolute;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-time-picker[data-format="12"] .ui-time-picker-container-format .ui-spin-item {
+  font-size: 24px;
+  line-height: 54px;
+}
+.ui-time-picker[data-format="24"] .ui-time-picker-container {
+  width: 30%;
+}
+.ui-time-picker[data-format="24"] .ui-time-picker-container-hour::after {
+  content: ":";
+  height: 164px;
+  width: 13.33333333%;
+  font-size: 32px;
+  color: var(--primary-dark-color);
+  position: absolute;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-time-picker[data-format="24"] .ui-time-picker-container-format {
+  display: none;
+}
+.ui-time-picker .ui-spin {
+  width: 100%;
+  height: 164px;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-time-picker .ui-spin .ui-time-picker-input {
+  width: 50px;
+  height: 50px;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  text-align: center;
+  font-size: 32px;
+  color: transparent;
+  font-family: Roboto-Regular;
+  border-width: 0;
+  outline: unset;
+  outline-offset: unset;
+  text-shadow: 0 0 0 var(--primary-dark-color);
+  opacity: 0;
+  background-color: transparent;
+}
+.ui-time-picker .ui-spin .ui-time-picker-input:focus {
+  background-color: var(--primary-color-20p);
+}
+.ui-time-picker .ui-spin-item {
+  font-family: Roboto-Regular;
+  line-height: 56px;
+}
+.ui-time-picker-input-active .ui-time-picker-container-hour .ui-spin-item,
+.ui-time-picker-input-active .ui-time-picker-container-minute .ui-spin-item {
+  opacity: 0 !important;
+}
+.ui-time-picker-input-active .ui-time-picker-container-hour .ui-time-picker-input,
+.ui-time-picker-input-active .ui-time-picker-container-minute .ui-time-picker-input {
+  opacity: 1;
+}
+.ui-calendar-view {
+  width: 100%;
+  border-spacing: 0;
+}
+.ui-calendar-view tr td {
+  height: 32px;
+  text-align: center;
+  vertical-align: middle;
+  font-size: 15px;
+  font-family: Roboto-Regular;
+  color: var(--calendar-text-color);
+  padding: 0;
+}
+.ui-calendar-view tr td div {
+  border-radius: 100%;
+  width: 28px;
+  height: 28px;
+  line-height: 28px;
+  margin: 0 auto;
+}
+.ui-calendar-view tr td div.ui-calendar-selection {
+  background-color: var(--primary-color);
+  color: var(--calendar-select-text-color);
+}
+.ui-calendar-view tr td:only-child {
+  width: 100%;
+}
+.ui-calendar-view tr td:nth-last-child(2) {
+  width: 50%;
+}
+.ui-calendar-view tr td:nth-last-child(2) + td {
+  width: 50%;
+}
+.ui-calendar-view tr td:nth-last-child(3) {
+  width: 33.3%;
+}
+.ui-calendar-view tr td:nth-last-child(3) ~ td {
+  width: 33.3%;
+}
+.ui-calendar-view tr td:nth-last-child(4) {
+  width: 25%;
+}
+.ui-calendar-view tr td:nth-last-child(4) ~ td {
+  width: 25%;
+}
+.ui-calendar-view tr td:nth-last-child(5) {
+  width: 20%;
+}
+.ui-calendar-view tr td:nth-last-child(5) ~ td {
+  width: 20%;
+}
+.ui-calendar-view tr td:nth-last-child(6) {
+  width: 16.6%;
+}
+.ui-calendar-view tr td:nth-last-child(6) ~ td {
+  width: 16.6%;
+}
+.ui-calendar-view tr td:nth-last-child(7) {
+  width: 14.2%;
+}
+.ui-calendar-view tr td:nth-last-child(7) ~ td {
+  width: 14.2%;
+}
+.ui-calendar-view tr td:nth-child(7) {
+  color: var(--calendar-weekend-day-color);
+}
+.ui-calendar-view .ui-calendar-one-week {
+  height: 32px;
+}
+.ui-calendar-view .ui-calendar-one-week td {
+  font-family: Roboto-Regular;
+  font-size: 11px;
+  color: var(--text-secondary-color);
+}
+.ui-calendar-view .ui-calendar-one-week .ui-sunday {
+  color: var(--calendar-weekend-color);
+}
+.ui-calendar-top-space {
+  height: 10px;
+}
+.ui-calendar-prev-month-day {
+  opacity: 0.1;
+}
+.ui-calendar-next-month-day {
+  opacity: 0.4;
+}
+.ui-calendar-controller {
+  width: 100%;
+  height: 36px;
+  line-height: 36px;
+  margin: 0 auto;
+  text-align: center;
+}
+.ui-calendar-controller div.ui-calendar-switch {
+  text-align: center;
+  font-family: Roboto-Regular;
+  font-size: 17px;
+  color: var(--calendar-text-color);
+  line-height: 36px;
+  display: inline;
+}
+.ui-calendar-arrow {
+  width: 36px;
+  height: 36px;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  -webkit-mask-position: center;
+          mask-position: center;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  background-color: var(--calendar-arrow-color);
+}
+.ui-calendar-left-arrow {
+  float: left;
+  -webkit-mask-image: url("images/4_Dialogs/tw_numberpicker_prev_mtrl.svg");
+          mask-image: url("images/4_Dialogs/tw_numberpicker_prev_mtrl.svg");
+}
+.ui-calendar-right-arrow {
+  float: right;
+  -webkit-mask-image: url("images/4_Dialogs/tw_numberpicker_next_mtrl.svg");
+          mask-image: url("images/4_Dialogs/tw_numberpicker_next_mtrl.svg");
+}
+.ui-calendar-disabled {
+  opacity: 0.1;
+}
+.ui-calendar-disabled-arrow {
+  opacity: 0.4;
+}
+@media (min-width: 361px) {
+  .ui-calendar-controller {
+    width: 328px;
+    margin: 0 auto;
+  }
+}
+.ui-content-area .ui-calendar,
+.ui-popup-content .ui-calendar {
+  padding: 14px 16px;
+}
+.ui-date-picker {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-date-picker-header {
+  font-family: Roboto-Regular;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  height: 36px;
+  font-size: 17px;
+  color: var(--date-picker-header-text-color);
+  line-height: 36px;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  margin-top: 14px;
+  margin-bottom: 10px;
+}
+.ui-date-picker-content {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-justify-content: space-evenly;
+      -ms-flex-pack: space-evenly;
+          justify-content: space-evenly;
+}
+.ui-date-picker-content .ui-date-picker-container {
+  width: 28%;
+  height: 164px;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-date-picker-content .ui-date-picker-container .ui-spin {
+  width: 100%;
+}
+.ui-date-picker-content .ui-date-picker-container .ui-spin-item {
+  font-size: 32px;
+  line-height: 54px;
+  font-family: Roboto-Regular;
+}
+.ui-date-picker-content .ui-date-picker-container .ui-spin-item-selected {
+  line-height: 56px;
+}
+.ui-date-picker-content .ui-date-picker-container-month .ui-spin-item {
+  font-size: 30px;
+}
+.ui-datetime-picker-wheel {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  height: 164px;
+  margin-left: 4%;
+  margin-right: 6%;
+  padding-top: 60px;
+  padding-bottom: 81px;
+}
+.ui-datetime-picker-wheel-container {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  font-size: 22px;
+}
+.ui-datetime-picker-wheel-container-separator {
+  position: relative;
+}
+.ui-datetime-picker-wheel-container-separator::after {
+  content: ":";
+  height: 100%;
+  width: auto;
+  color: var(--primary-dark-color);
+  position: absolute;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  right: 0;
+}
+.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-date {
+  min-width: 47%;
+}
+.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-hour {
+  min-width: 14%;
+}
+.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-minute {
+  min-width: 14%;
+}
+.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-format {
+  min-width: 13%;
+}
+.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-date {
+  min-width: 47%;
+}
+.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-hour {
+  min-width: 14%;
+}
+.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-minute {
+  min-width: 14%;
+}
+.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-format {
+  display: none;
+}
+.ui-datetime-picker-wheel .ui-spin {
+  width: 100%;
+  height: 164px;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  white-space: nowrap;
+  font-size: 22px;
+}
+.ui-datetime-picker-wheel .ui-spin .ui-datetime-picker-wheel-input {
+  width: 50px;
+  height: 50px;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  text-align: center;
+  font-size: 22px;
+  color: transparent;
+  font-family: Roboto-Regular;
+  border-width: 0;
+  outline: unset;
+  outline-offset: unset;
+  text-shadow: 0 0 0 var(--primary-dark-color);
+  opacity: 0;
+  background-color: transparent;
+}
+.ui-datetime-picker-wheel .ui-spin .ui-datetime-picker-wheel-input:focus {
+  background-color: var(--primary-color-20p);
+}
+.ui-datetime-picker-wheel .ui-spin-item {
+  font-family: Roboto-Regular;
+  line-height: 54px;
+}
+.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-hour .ui-spin-item,
+.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-minute .ui-spin-item {
+  opacity: 0 !important;
+}
+.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-hour .ui-datetime-picker-wheel-input,
+.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-minute .ui-datetime-picker-wheel-input {
+  opacity: 1;
+}
+.ui-datetime-picker-hidden {
+  display: none;
+}
+.ui-chip {
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  font-family: Roboto-Regular;
+  font-size: 14px;
+  height: 30px;
+  border-radius: 15px;
+  padding: 0 0 0 16px;
+  background-color: var(--chip-background-color);
+  border: 0.25px solid var(--chip-border-color);
+  box-sizing: border-box;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-chip .ui-chip-text {
+  text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap;
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+}
+.ui-chip .ui-chip-button {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+}
+.ui-chip .ui-btn.ui-btn-flat {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  width: 20px;
+  height: 20px;
+  max-width: 20px;
+  max-height: 20px;
+  min-width: 20px;
+  min-height: 20px;
+  max-width: 100%;
+  margin: auto 5px auto 10px;
+  padding: 0;
+  border-radius: 100%;
+  background-color: var(--chip-btn-background-color);
+  border: 0.5px solid var(--chip-btn-border-color);
+  box-sizing: border-box;
+}
+.ui-chip .ui-btn.ui-btn-flat::after {
+  width: 20px;
+  height: 20px;
+  -webkit-mask-size: 20px;
+          mask-size: 20px;
+}
+.ui-chip .ui-btn.ui-btn-flat::before {
+  width: 30px;
+  height: 30px;
+}
+.ui-chip .ui-btn.ui-btn-flat.ui-btn-icon {
+  background-color: var(--chip-btn-background-color);
+}
+.ui-chip .ui-btn.ui-btn-flat.ui-icon-add::after {
+  -webkit-mask-image: url(images/3_Controllers/tw_chips_icon_add_mtrl.svg);
+          mask-image: url(images/3_Controllers/tw_chips_icon_add_mtrl.svg);
+}
+.ui-chip .ui-btn.ui-btn-flat.ui-icon-delete::after {
+  -webkit-mask-image: url(images/3_Controllers/tw_chips_icon_delete_mtrl.svg);
+          mask-image: url(images/3_Controllers/tw_chips_icon_delete_mtrl.svg);
+}
+.ui-chips {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  margin: 0 20px;
+  row-gap: 4px;
+  -webkit-column-gap: 7px;
+          column-gap: 7px;
+  -webkit-flex-wrap: wrap;
+      -ms-flex-wrap: wrap;
+          flex-wrap: wrap;
+  max-height: 114px;
+  overflow-y: auto;
+}
+.ui-chips .ui-chip {
+  margin-top: 4px;
+  max-width: 100%;
+}
+.ui-chips.ui-chips-inline {
+  -webkit-flex-wrap: nowrap;
+      -ms-flex-wrap: nowrap;
+          flex-wrap: nowrap;
+  overflow-x: scroll;
+  height: 44px;
+}
+.tau-info-theme:after {
+  content: "default";
+}
diff --git a/d2d_app/client/lib/tau/mobile/theme/changeable/tau.min.css b/d2d_app/client/lib/tau/mobile/theme/changeable/tau.min.css
new file mode 100644 (file)
index 0000000..c18db94
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+:root{--text-secondary-color:#909090;--primary-color:#0381fe;--control-background:#e6e6e6;--textual-background:#FCFCFC;--color-white:#fafafa;--surface:#FCFCFC;--accent-badge:#F56A0D;--on-background:#858585;--border-surface:#e6e6e6;--button-background:rgba(0,0,0,0);--button-background-flat:transparent;--button-text-font-size:17px;--button-contained-text-font-size:17px;--button-contained-list-text-font-size:15px;--btn-add-color:#00b149;--btn-delete-color:#ff3d00;--checkbox-image-checked:rgba(0,0,0,.3);--slider-bg-color:rgba(3,129,254,.3);--slider-bg-disabled-color:rgba(102,102,102,.15);--slider-value-color:#0381fe;--slider-handler-color:#0381fe;--btn-toast-background:rgba(71,71,71,.9);--btn-toast-text-color:#0381fe;--toast-background:rgba(102,102,102,.95);--toast-text-color:#FFF;--progress-circle-second-color:#06b485;--on-off-switch-off-button-border:#8f8f8f;--on-off-switch-on-disabled-track-background:rgba(143,143,143,.4);--on-off-switch-off-track-background:transparent;--on-off-switch-off-disabled-track-border:rgba(143,143,143,.4)}body,body.ui-theme-light,body.ui-theme-default{--primary-color:#0381fe;--primary-dark-color:#0072de;--primary-color-20p:rgba(3,129,254,.2);--primary-color-30p:rgba(3,129,254,.3);--control-active-color:#3e91ff;--control-active-disabled-color:rgba(62,145,255,.4);--control-inactive-color:#8f8f8f;--text-color:#252525;--text-secondary-color:#909090;--color-white:#fafafa;--color-black:#000;--ripple-color:rgba(0,0,0,.1);--overlay:rgba(0,0,0,.45);--background-color:#F2F2F2;--background-area-color:#fcfcfc;--expandable-text-color:#666;--popup-background:#fcfcfc;--popup-text:#505050;--popup-text-secondary-color:#8f8f8f;--popup-footer-divider-color:#e6e6e6;--popup-scroll-divider-color:#d4d4d4;--icon-color:#3b3b3b;--appbar-main-text-color:#252525;--appbar-subtitle-color:#636363;--appbar-miltiline-title-color:#252525;--tab-text-color:#858585;--tab-text-color-dim:rgba(133,133,133,.4);--bottom-bar-color:#F2F2F2;--button-icon-color:#252525;--bottom-button-icon-color:#454545;--sub-tab-bg-color:#F2F2F2;--sub-tab-text-color:#858585;--sub-tab-active-text-color:#252525;--sub-tab-border-color:rgba(113,113,113,.8);--progress-bar-color:#0381fe;--progress-bar-bg-color:rgba(3,129,254,.3);--button-text-color-disabled:rgba(3,129,254,.4);--checkbox-favorite-color:#f5ab00;--ripple-button-flat-color:rgba(0,0,0,.1);--slider-handler-disabled-color:#d2d2d2;--slider-scale-dot:#9c9c9c;--slider-level-bar-bg-color:rgba(151,151,151,.3);--button-background-contained:rgba(0,0,0,.06);--on-off-switch-off-disabled-button-border:#d0d0d0;--on-off-switch-on-disabled-button-border:#d0d0d0;--on-off-switch-on-disabled-button-background:#fafafa;--on-off-switch-divider-color:#c4c4c4;--master-on-off-off-color:#fafafa;--master-on-off-on-color:rgba(62,145,255,.8);--chip-background-color:#e5e5e5;--chip-border-color:rgba(37,37,37,.2);--chip-btn-background-color:#f2f2f2;--chip-btn-border-color:rgba(37,37,37,.3);--text-input-invalid-color:#b00020;--dropdown-menu-options-border:.25px solid #ccc;--dropdown-menu-options-background:#fcfcfc;--dropdown-menu-options-color:#000;--dropdown-menu-options-color-dim:rgba(0,0,0,.4);--content-area-line-color:#d6d6d6;--list-item-selected-color:rgba(3,129,254,.08);--divider-color:#e6e6e6;--divider-opacity:100%;--subheader-divider-color:#979797;--grid-border-color:rgba(0,0,0,.12);--grid-label-color:#252525;--grid-label-secondary-color:#666;--expander-color:#747474;--reorder-color:#747474;--holder-reoder-background:#fcfcfc;--holder-reoder-border:#0072de;--spin-item-opacity:.1;--grid-selection-color:rgba(0,0,0,.3);--calendar-weekend-day-color:#c95151;--calendar-weekend-color:#d77e7e;--calendar-text-color:#454545;--calendar-arrow-color:#8e8e8e;--calendar-select-text-color:#fafafa;--date-picker-header-text-color:#454545;--text-input-disabled:#bebebe;--text-input-label-inactive:#8c8c8c;--text-input-underline-inactive:#8c8c8c;--text-input-underline-active:var(--primary-color);--icon-control-color:var(--color-white);--progress-background-color:#ccc;--on-off-switch-track-off:#8f8f8f;--more-options-background-color:var(--popup-background);--more-options-background-stroke:#ccc;--more-options-pressed-color:rgba(0,0,0,.1);--button-text-contained-dim-color:rgba(37,37,37,.4)}body.ui-theme-dark{--primary-color:#0381fe;--primary-dark-color:#3e91ff;--primary-color-20p:rgba(3,129,254,.2);--primary-color-30p:rgba(3,129,254,.3);--control-active-color:#3e91ff;--control-active-disabled-color:rgba(62,145,255,.4);--control-inactive-color:#8f8f8f;--text-color:#fafafa;--text-secondary-color:#999;--color-white:#fafafa;--color-black:#080808;--ripple-color:rgba(255,255,255,.2);--overlay:rgba(0,0,0,.65);--background-color:#080808;--background-area-color:#252525;--expandable-text-color:#9c9c9c;--popup-background:#252525;--popup-text:#e5e5e5;--popup-text-secondary-color:#999;--popup-footer-divider-color:rgba(230,230,230,.2);--popup-scroll-divider-color:rgba(212,212,212,.18);--icon-color:#d9d9d9;--appbar-main-text-color:#fafafa;--appbar-subtitle-color:#9c9c9c;--appbar-miltiline-title-color:#e5e5e5;--tab-text-color:#a8a9a9;--tab-text-color-dim:rgba(168,169,169,.4);--bottom-bar-color:#010101;--button-icon-color:#fafafa;--bottom-button-icon-color:#ccc;--sub-tab-bg-color:#010101;--sub-tab-text-color:#999;--sub-tab-active-text-color:#FFF;--sub-tab-border-color:rgba(255,255,255,.6);--progress-bar-color:#0381fe;--progress-bar-bg-color:rgba(3,129,254,.3);--button-text-color-disabled:rgba(3,129,254,.4);--checkbox-favorite-color:#f5ab00;--ripple-button-flat-color:rgba(255,255,255,.2);--slider-handler-disabled-color:#545454;--slider-scale-dot:gray;--slider-level-bar-bg-color:rgba(151,151,151,.3);--button-background-contained:rgba(250,250,250,.17);--on-off-switch-off-disabled-button-border:#3b3b3b;--on-off-switch-on-disabled-button-border:#3b3b3b;--on-off-switch-on-disabled-button-background:#858585;--on-off-switch-divider-color:rgba(212,212,212,.15);--master-on-off-off-color:rgba(250,250,250,.17);--master-on-off-on-color:rgba(62,145,255,.4);--chip-background-color:#252525;--chip-border-color:rgba(250,250,250,.2);--chip-btn-background-color:#f2f2f2;--chip-btn-border-color:rgba(37,37,37,.3);--text-input-invalid-color:#f66;--dropdown-menu-options-border:.75px solid #525252;--dropdown-menu-options-background:#3d3d3d;--dropdown-menu-options-color:#fafafa;--dropdown-menu-options-color-dim:rgba(250,250,250,.4);--content-area-line-color:#d6d6d6;--list-item-selected-color:rgba(250,250,250,.1);--divider-color:#d4d4d4;--divider-opacity:15%;--subheader-divider-color:#fafafa;--grid-border-color:rgba(250,250,250,.25);--grid-label-color:#fafafa;--grid-label-secondary-color:#999;--expander-color:gray;--reorder-color:gray;--holder-reoder-background:#252525;--holder-reoder-border:#3e91ff;--spin-item-opacity:.2;--grid-selection-color:rgba(0,0,0,.3);--calendar-weekend-day-color:#c95151;--calendar-weekend-color:#993d3d;--calendar-text-color:#ccc;--calendar-arrow-color:#737373;--calendar-select-text-color:#000;--date-picker-header-text-color:#ccc;--surface:#3d3d3d;--text-input-disabled:#454545;--text-input-label-inactive:#737373;--text-input-underline-inactive:#737373;--text-input-underline-active:var(--primary-color);--icon-control-color:var(--surface);--progress-background-color:#252525;--more-options-background-color:#3d3d3d;--more-options-background-stroke:#525252;--more-options-pressed-color:rgba(255,255,255,.2);--button-text-contained-dim-color:rgba(250,250,250,.4)}@font-face{font-family:Roboto-Light;src:url(fonts/Roboto-Light.ttf)}@font-face{font-family:Roboto-Regular;src:url(fonts/Roboto-Regular.ttf)}@font-face{font-family:Roboto-Medium;src:url(fonts/Roboto-Medium.ttf)}.tau-info-theme{position:absolute;top:-999px;left:-999px}.ui-appbar,header{position:relative;width:100%;box-sizing:border-box;background:var(--background-color);overflow:hidden;border:0;height:56px;margin-bottom:12px;font-family:Roboto-Regular;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-appbar:not(.ui-appbar-dragging),header:not(.ui-appbar-dragging){transition:height 100ms cubic-bezier(0.25,.46,.45,.94)}.ui-appbar:not(.ui-appbar-dragging) .ui-appbar-controls-container,header:not(.ui-appbar-dragging) .ui-appbar-controls-container,.ui-appbar:not(.ui-appbar-dragging) .ui-appbar-expanded-title-container,header:not(.ui-appbar-dragging) .ui-appbar-expanded-title-container{padding-top:0;transition:opacity 100ms cubic-bezier(0.25,.46,.45,.94)}.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast,header:not(.ui-appbar-dragging).ui-appbar-animation-fast{transition-duration:10ms}.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-controls-container,header:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-controls-container,.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-expanded-title-container,header:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-expanded-title-container{transition-duration:10ms}.ui-appbar .ui-btn,header .ui-btn{padding:0}.ui-appbar .ui-btn.ui-btn-flat,header .ui-btn.ui-btn-flat{font-size:18px;font-family:Roboto-Medium;color:var(--appbar-main-text-color)}.ui-appbar .ui-btn.ui-btn-flat::before,header .ui-btn.ui-btn-flat::before{height:48px;border-radius:24px}.ui-appbar .ui-btn.ui-btn-icon,header .ui-btn.ui-btn-icon{background-color:transparent;position:relative;width:24px;height:24px;min-height:24px;margin-right:8px}.ui-appbar .ui-btn.ui-btn-icon::before,header .ui-btn.ui-btn-icon::before{width:48px;height:48px}.ui-appbar .ui-btn.ui-btn-icon::after,header .ui-btn.ui-btn-icon::after{width:24px;height:24px}.ui-appbar .ui-btn.ui-btn-icon-back::after,header .ui-btn.ui-btn-icon-back::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg)}.ui-appbar .ui-btn.ui-btn-icon-more::after,header .ui-btn.ui-btn-icon-more::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_more_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_more_mtrl.svg)}.ui-appbar .ui-btn.ui-btn-icon-search::after,header .ui-btn.ui-btn-icon-search::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_search_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_search_mtrl.svg)}.ui-appbar .ui-btn.ui-btn-icon-add::after,header .ui-btn.ui-btn-icon-add::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_add_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_add_mtrl.svg)}.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat,header .ui-btn.ui-btn-icon.ui-btn-flat{min-height:24px;display:block;margin-top:auto;margin-bottom:auto}.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat::after,header .ui-btn.ui-btn-icon.ui-btn-flat::after{-webkit-mask-size:100%;mask-size:100%;width:24px;height:24px}.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat::before,header .ui-btn.ui-btn-icon.ui-btn-flat::before{background-color:transparent;width:48px;height:48px}.ui-appbar .ui-btn.ui-btn-icon.ui-btn-icon-back,header .ui-btn.ui-btn-icon.ui-btn-icon-back{margin-left:20px;margin-right:12px}.ui-appbar .ui-appbar-controls-container,header .ui-appbar-controls-container{-webkit-flex:0 0 56px;-ms-flex:0 0 56px;flex:0 0 56px;width:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;position:absolute;bottom:0}.ui-appbar .ui-appbar-controls-container .ui-appbar-left-icons-container,header .ui-appbar-controls-container .ui-appbar-left-icons-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;min-width:24px;margin-top:auto;margin-bottom:auto}.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container,header .ui-appbar-controls-container .ui-appbar-title-container{height:56px;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:auto 0;overflow:hidden;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start}.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container .ui-appbar-title,header .ui-appbar-controls-container .ui-appbar-title-container .ui-appbar-title{max-width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:19px;color:var(--appbar-main-text-color)}.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-subtitle .ui-appbar-subtitle,header .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-subtitle .ui-appbar-subtitle{font-size:13px;color:var(--appbar-subtitle-color)}.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-multiline .ui-appbar-title,header .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-multiline .ui-appbar-title{font-size:17px;color:var(--appbar-miltiline-title-color)}.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container,header .ui-appbar-controls-container .ui-appbar-action-buttons-container{height:100%;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;margin-left:auto;min-width:24px;margin-top:auto;margin-bottom:auto;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end}.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn,header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn{margin-right:12px;margin-left:12px}.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn:last-child,header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn:last-child{margin-right:20px;margin-left:15px}.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn+.ui-btn-icon,header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn+.ui-btn-icon{margin-left:3px}.ui-appbar .ui-appbar-expanded-title-container,header .ui-appbar-expanded-title-container{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;opacity:0;height:0}.ui-appbar .ui-appbar-expanded-title-container .ui-appbar-title,header .ui-appbar-expanded-title-container .ui-appbar-title{line-height:54px;font-size:38px;font-family:Roboto-Light;margin-left:24px;margin-right:24px;text-align:center}.ui-appbar .ui-appbar-expanded-title-container .ui-appbar-subtitle,header .ui-appbar-expanded-title-container .ui-appbar-subtitle{line-height:20px;font-size:15px;text-align:center}.ui-appbar h1,header h1,.ui-appbar h2,header h2,.ui-appbar h3,header h3,.ui-appbar h4,header h4,.ui-appbar h5,header h5,.ui-appbar h6,header h6{margin:0;padding:0;border:0;outline:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline}.ui-appbar.ui-appbar-expanded,header.ui-appbar-expanded{height:calc(39.67% - 12px)}.ui-appbar.ui-appbar-expanded .ui-appbar-expanded-title-container,header.ui-appbar-expanded .ui-appbar-expanded-title-container{opacity:1}.ui-appbar.ui-appbar-dragging .ui-appbar-expanded-title-container,header.ui-appbar-dragging .ui-appbar-expanded-title-container{overflow:hidden}.ui-appbar .ui-label-select-all,header .ui-label-select-all{font-family:Roboto-Regular;font-size:12px;width:32px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding-top:10px;line-height:14px;margin-left:18px;margin-right:18px}.ui-appbar .ui-label-select-all input[type=checkbox].ui-checkbox,header .ui-label-select-all input[type=checkbox].ui-checkbox{margin:0 0 -3px 0}.ui-appbar .ui-appbar-container,header .ui-appbar-container{height:70px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-order:10;-ms-flex-order:10;order:10;background-color:var(--background-area-color);border-radius:26px;overflow:hidden;box-sizing:border-box;box-shadow:0 0 0 .25px var(--content-area-line-color) inset}.ui-appbar .ui-appbar-container>:first-child,header .ui-appbar-container>:first-child{margin-left:24px}.ui-appbar .ui-appbar-container .ui-title,header .ui-appbar-container .ui-title{font-size:18px;-webkit-flex:1;-ms-flex:1;flex:1}.ui-appbar .ui-appbar-container .ui-icon,header .ui-appbar-container .ui-icon{width:21px;height:21px;overflow:hidden;margin-right:22px}.ui-appbar .ui-appbar-container .ui-icon img,header .ui-appbar-container .ui-icon img{width:100%}.ui-appbar .ui-appbar-container .ui-btn.ui-btn-icon.ui-btn-icon-only,header .ui-appbar-container .ui-btn.ui-btn-icon.ui-btn-icon-only{height:48px;max-width:48px}@media all and (min-height:580px) and (orientation:landscape){.ui-appbar.ui-appbar-expanded{height:calc(30% - 12px)}}@media all and (min-height:960px){.ui-appbar.ui-appbar-expanded{height:calc(25% - 12px)}}.ui-card{border-radius:26px;overflow:hidden;box-sizing:border-box;margin-bottom:10px}.ui-card.ui-card-service{background-color:var(--background-area-color);border-radius:26px;overflow:hidden;box-sizing:border-box;box-shadow:0 0 0 .25px var(--content-area-line-color) inset}.ui-card.ui-card-service ::-webkit-scrollbar{display:none}.ui-card.ui-card-service .ui-subheader-text{color:#7b7b7b}.ui-card.ui-card-service .ui-content-subheader{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-card.ui-card-service .ui-content-subheader::after{content:"";display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;width:calc(100% - 20px);border-bottom:1px solid var(--subheader-divider-color);height:0;-webkit-align-items:center;-ms-flex-align:center;align-items:center;margin-right:20px;margin-left:10px}.ui-card.ui-card-service .ui-content-thumbnail{width:100%}.ui-card.ui-card-service .ui-content .ui-title.ui-title-medium{font-size:18px;font-family:Roboto-Medium}.ui-card.ui-card-service .ui-content.ui-scrollview-clip{border-radius:0}.ui-card.ui-card-service .ui-listview li .ui-li-icon{width:58px;height:58px}.ui-card.ui-card-service .ui-listview li .ui-li-icon img{width:58px;height:58px}.ui-card.ui-card-service .ui-listview li .ui-li-text{padding:25px 0 23px}.ui-card.ui-card-service .ui-listview li .ui-li-text-title{font-size:16px}.ui-card.ui-card-service .ui-listview li .ui-li-text-sub{font-size:12px}.ui-card .ui-header{display:-webkit-flex;display:-ms-flexbox;display:flex;height:46px;padding:0 20px}.ui-card .ui-header .ui-title{margin-top:24px;margin-bottom:3px;font-size:15px;color:var(--text-color);-webkit-order:1;-ms-flex-order:1;order:1;display:inline-block;-webkit-flex:1;-ms-flex:1;flex:1}.ui-card .ui-header .ui-icon{margin-right:10px;margin-top:20px;width:26px;height:26px;-webkit-order:0;-ms-flex-order:0;order:0;display:inline-block}.ui-card .ui-header .ui-icon img{width:100%;height:100%}.ui-card .ui-header .ui-controls{-webkit-order:2;-ms-flex-order:2;order:2;display:-webkit-flex;display:-ms-flexbox;display:flex;margin-top:20px;height:26px}.ui-card .ui-header .ui-controls .ui-btn{width:26px;height:26px;background-color:transparent;min-height:26px;padding:0;display:inline-block}.ui-card .ui-header .ui-controls .ui-btn~.ui-btn{margin-left:14px}.ui-card .ui-header .ui-controls .ui-btn::before{height:26px}.ui-card .ui-header .ui-controls .ui-btn::after{background-color:var(--background-area-color);height:26px;width:26px}.ui-card .ui-content,.ui-card .ui-content.ui-scrollview-clip{padding:10px 20px}.ui-card .ui-content.ui-tabs,.ui-card .ui-content.ui-scrollview-clip.ui-tabs{padding:0}.ui-card .ui-content .ui-section-changer .ui-content,.ui-card .ui-content.ui-scrollview-clip .ui-section-changer .ui-content{padding:0}.ui-card .ui-content .ui-title,.ui-card .ui-content.ui-scrollview-clip .ui-title{font-size:16px}.ui-card .ui-content .ui-description,.ui-card .ui-content.ui-scrollview-clip .ui-description{font-size:14px}.ui-card .ui-content video,.ui-card .ui-content.ui-scrollview-clip video{border-radius:26px}.ui-card .ui-content .ui-btn,.ui-card .ui-content.ui-scrollview-clip .ui-btn{width:86px;padding:0}.ui-card .ui-content .ui-btn .ui-btn-content,.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content{width:86px;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-card .ui-content .ui-btn .ui-btn-content img,.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content img{border-radius:15px;width:80px;height:80px;margin-bottom:8px}.ui-card .ui-content .ui-btn .ui-btn-content .ui-title,.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content .ui-title{font-size:14px;color:var(--text-color);line-height:16px}.ui-card .ui-content .ui-btn .ui-btn-content .ui-subtitle,.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content .ui-subtitle{font-size:12px;color:var(--text-secondary-color);line-height:14px}.ui-card .ui-container-item img{border-radius:16px;width:188px;height:126px;margin-bottom:17px}.ui-card .ui-container-item .ui-title{font-family:Roboto-Medium;color:var(--text-color);font-size:16px;line-height:19px;text-align:left;white-space:normal;margin-bottom:6px}.ui-card .ui-container-item .ui-subtitle{font-family:Roboto-Regular;color:var(--text-secondary-color);font-size:14px;line-height:16px;text-align:left;white-space:normal}.ui-card .ui-footer{height:63px;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end;padding:0 20px}.ui-card .ui-footer .ui-btn{display:inline-block;width:auto;height:43px;color:var(--color-white);font-size:14px;background-color:var(--primary-dark-color)}.ui-card .ui-sub-tab{background-color:transparent}.ui-card.ui-card-ads{background-color:var(--background-area-color);min-height:200px}.ui-card.ui-card-ads .ui-content{padding:0;border-radius:0}.ui-card.ui-card-ads .ui-content .ui-scrollview-view{overflow:hidden}.ui-card.ui-card-ads .ui-content video,.ui-card.ui-card-ads .ui-content img{border-radius:0;width:100%}.ui-card.ui-card-ads .ui-content .ui-title{font-family:Roboto-Medium;color:var(--text-color);font-size:16px;white-space:normal;margin:0 20px}.ui-card.ui-card-ads .ui-content .ui-title:last-child{margin-top:15px}.ui-card.ui-card-ads .ui-content .ui-subtitle{font-family:Roboto-Regular;color:var(--text-secondary-color);font-size:14px;white-space:normal;margin:0 20px}.ui-card.ui-card-ads .ui-content .ui-banner{position:relative;width:100%;height:150px;overflow:hidden}.ui-card.ui-card-ads .ui-content .ui-banner img{width:100%;position:absolute}.ui-card.ui-card-ads .ui-footer .ui-title{font-family:Roboto-Medium;color:var(--text-color);font-size:16px;white-space:normal;margin:0 20px 0 0;-webkit-flex:1;-ms-flex:1;flex:1;text-align:left}.LESSui-footer{box-sizing:border-box;padding:12px 24px;text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0}.LESSui-footer .ui-btn:not(.ui-btn-contained){height:52px;line-height:52px;margin:0 auto;max-width:248px}.LESSui-footer .ui-btn.ui-btn-contained:not(.ui-btn-inline){-webkit-flex:1;-ms-flex:1;flex:1}.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained){background-color:var(--button-background)}.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-btn-active::before{background-color:var(--ripple-color)}.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-state-disabled{background-color:var(--button-background)}.LESSui-footer .ui-btn~.ui-btn{margin-left:16px}.LESSui-footer .ui-btn.ui-btn-contained~.ui-btn.ui-btn-contained{margin-left:8px}.LESSui-footer.ui-grid-col-1 .ui-btn.ui-inline,.LESSui-footer.ui-grid-col-2 .ui-btn.ui-inline,.LESSui-footer.ui-grid-col-3 .ui-btn.ui-inline{display:block;width:100%}.LESSui-footer.ui-bottom-button{height:56px;padding-left:24px;padding-right:24px}.ui-footer{width:100%;box-sizing:border-box;padding:12px 24px;text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0}.ui-footer .ui-btn:not(.ui-btn-contained){height:52px;line-height:52px;margin:0 auto;max-width:248px}.ui-footer .ui-btn.ui-btn-contained:not(.ui-btn-inline){-webkit-flex:1;-ms-flex:1;flex:1}.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained){background-color:var(--button-background)}.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-btn-active::before{background-color:var(--ripple-color)}.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-state-disabled{background-color:var(--button-background)}.ui-footer .ui-btn~.ui-btn{margin-left:16px}.ui-footer .ui-btn.ui-btn-contained~.ui-btn.ui-btn-contained{margin-left:8px}.ui-footer.ui-grid-col-1 .ui-btn.ui-inline,.ui-footer.ui-grid-col-2 .ui-btn.ui-inline,.ui-footer.ui-grid-col-3 .ui-btn.ui-inline{display:block;width:100%}.ui-footer.ui-bottom-button{height:56px;padding-left:24px;padding-right:24px}.ui-page:not(.ui-page-flex) .ui-footer{position:fixed;bottom:0}.ui-page.ui-page-flex .ui-footer{overflow:visible}.ui-page-container,.ui-page-container body{height:100%;font-size:22px}@media all and (max-width:359px){.ui-page-container,.ui-page-container body{font-size:19px}}.ui-page-container fieldset,.ui-page{padding:0;margin:0}.ui-page-container a img,.ui-page-container fieldset{border:0}.ui-page-container{margin:0;overflow-x:hidden;-webkit-tap-highlight-color:rgba(0,0,0,0)}[data-role=page],[data-role=dialog],.ui-page{top:0;left:0;width:100%;position:absolute;display:none;border:0}[data-role=page].ui-page-build,[data-role=dialog].ui-page-build,.ui-page.ui-page-build{display:block;visibility:hidden}[data-role=page].ui-pre-in,[data-role=dialog].ui-pre-in,.ui-page.ui-pre-in{z-index:100}[data-role=page].ui-pre-in,[data-role=dialog].ui-pre-in,.ui-page.ui-pre-in,[data-role=page].ui-page-active,[data-role=dialog].ui-page-active,.ui-page.ui-page-active{display:block;overflow:hidden}[data-role=page].ui-pre-in.ui-page-flex,[data-role=dialog].ui-pre-in.ui-page-flex,.ui-page.ui-pre-in.ui-page-flex,[data-role=page].ui-page-active.ui-page-flex,[data-role=dialog].ui-page-active.ui-page-flex,.ui-page.ui-page-active.ui-page-flex{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-content:stretch;-ms-flex-line-pack:stretch;align-content:stretch}[data-role=page].ui-pre-in.ui-page-flex .ui-header,[data-role=dialog].ui-pre-in.ui-page-flex .ui-header,.ui-page.ui-pre-in.ui-page-flex .ui-header,[data-role=page].ui-page-active.ui-page-flex .ui-header,[data-role=dialog].ui-page-active.ui-page-flex .ui-header,.ui-page.ui-page-active.ui-page-flex .ui-header{position:relative}[data-role=page].ui-pre-in.ui-page-flex .ui-content,[data-role=dialog].ui-pre-in.ui-page-flex .ui-content,.ui-page.ui-pre-in.ui-page-flex .ui-content,[data-role=page].ui-page-active.ui-page-flex .ui-content,[data-role=dialog].ui-page-active.ui-page-flex .ui-content,.ui-page.ui-page-active.ui-page-flex .ui-content{-webkit-flex:1;-ms-flex:1;flex:1}.ui-page-container,.ui-page-container .ui-page{color:var(--text-color);background-image:none;background-color:var(--background-color)}.ui-page-container.ui-page-light,.ui-page-container .ui-page.ui-page-light{background-image:none}.ui-page.ui-mobile-touch-overflow,.ui-mobile-touch-overflow.ui-native-fixed .ui-content{overflow:auto;height:100%;-webkit-overflow-scrolling:touch}.ui-page.ui-mobile-touch-overflow,.ui-page.ui-mobile-touch-overflow *{transform:rotateY(0);-ms-transform:rotateY(0);-moz-transform:rotateY(0);-webkit-transform:rotateY(0);-o-transform:rotateY(0)}.ui-page.ui-mobile-pre-transition{display:block}.ui-blocker{width:100%;height:100%;z-index:2147483647}.ui-mobile-rendering>*{visibility:hidden}.ui-bar,.ui-body{position:relative;padding:.4em 15px;overflow:hidden;display:block;clear:both}.ui-bar{font-size:16px;margin:0}.ui-bar h1,.ui-bar h2,.ui-bar h3,.ui-bar h4,.ui-bar h5,.ui-bar h6{margin:0;padding:0;font-size:16px;display:inline-block}.ui-content{border-width:0;overflow-y:visible;overflow-x:hidden;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;border-radius:26px}.ui-content.ui-content-padding,.ui-content.ui-content-padding.ui-scrollview-clip{padding-left:12px;padding-right:12px}.ui-content.ui-content-under-popup{pointer-events:none}.ui-content .ui-content-area{background-color:var(--background-area-color);border-radius:26px;overflow:hidden;box-sizing:border-box;box-shadow:0 0 0 .25px var(--content-area-line-color) inset;margin:auto auto 16px}@media (min-width:673px) and (min-height:411px){.ui-content .ui-content-area{width:90%}}@media (min-width:960px){.ui-content .ui-content-area{width:75%}}.ui-content .ui-content-area-disabled-top-rounding{border-top-left-radius:0;border-top-right-radius:0;-webkit-mask-box-image-width:0 26px 26px;mask-border-width:0 26px 26px}.ui-content .ui-content-area~.ui-content-subheader{margin-top:-16px}.ui-content .ui-content-subheader{color:var(--text-secondary-color);font-family:Roboto-Medium;font-size:14px;padding-bottom:7px;padding-top:13px;margin-left:24px;line-height:16px}body.ui-theme-dark .ui-content-area{box-shadow:unset}.ui-page-fullscreen .ui-content{padding:0}.ui-mobile-touch-overflow.ui-native-fixed .ui-content{padding-top:2.5em;padding-bottom:3em;top:0;bottom:0;height:auto;position:absolute}.ui-mobile-touch-overflow.ui-native-fullscreen .ui-content{padding-top:0;padding-bottom:0}.ui-native-bars-hidden{display:none}.ui-screen-hidden{display:none}.ui-icon{width:18px;height:18px}.ui-fullscreen img{max-width:100%}.ui-nojs{position:absolute;left:-9999px}.scrolling-scrollbar{position:absolute;pointer-events:none}.scrolling-scrollbar .scrolling-scrollthumb{background-color:#71cbd9;position:absolute}.scrolling-scrollbar.scrolling-direction-y{right:11px;width:10px}.scrolling-scrollbar.scrolling-direction-y .scrolling-scrollthumb{width:10px;min-height:44px;top:0;left:50%;margin-left:-5px}.scrolling-scrollbar.scrolling-direction-x{bottom:11px;height:10px}.scrolling-scrollbar.scrolling-direction-x .scrolling-scrollthumb{height:10px;min-width:37px;left:0;top:50%;margin-top:-5px}input[type=checkbox].ui-checkbox:not(.ui-toggle-switch){position:relative;height:32px;width:32px;box-sizing:border-box;outline:0;-webkit-appearance:none;margin:0 18px}@-webkit-keyframes checkbox-in{from{-webkit-mask-position:0 0;mask-position:0 0}to{-webkit-mask-position:100% 0;mask-position:100% 0}}@keyframes checkbox-in{from{-webkit-mask-position:0 0;mask-position:0 0}to{-webkit-mask-position:100% 0;mask-position:100% 0}}@-webkit-keyframes checkbox-out{from{-webkit-mask-position:100% 0;mask-position:100% 0}to{-webkit-mask-position:0 0;mask-position:0 0}}@keyframes checkbox-out{from{-webkit-mask-position:100% 0;mask-position:100% 0}to{-webkit-mask-position:0 0;mask-position:0 0}}input[type=checkbox].ui-checkbox::before{content:"";position:absolute;left:0;top:0;width:32px;height:32px;background-color:var(--ripple-color);border-radius:100%;opacity:0}input[type=checkbox].ui-checkbox::after{content:"";position:absolute;bottom:0;opacity:.8;background-color:var(--control-inactive-color);-webkit-animation-duration:250ms;animation-duration:250ms;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:steps(26);animation-timing-function:steps(26);width:100%;height:100%;-webkit-mask-image:url(images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg);mask-image:url(images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg);-webkit-mask-size:auto 100%;mask-size:auto 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:0 0;mask-position:0 0}input[type=checkbox].ui-checkbox.ui-checkbox-backward-animation::after{-webkit-animation-name:checkbox-out;animation-name:checkbox-out}input[type=checkbox].ui-checkbox:checked::after{background-color:var(--control-active-color);-webkit-animation-name:checkbox-in;animation-name:checkbox-in}input[type=checkbox].ui-checkbox:active::before{opacity:1}input[type=checkbox].ui-checkbox:disabled{opacity:.4}input[type=checkbox].ui-checkbox.ui-checkbox-focus{outline:2px solid var(--primary-color)}@-webkit-keyframes radio-in{from{-webkit-mask-position:0 0;mask-position:0 0}to{-webkit-mask-position:100% 0;mask-position:100% 0}}@keyframes radio-in{from{-webkit-mask-position:0 0;mask-position:0 0}to{-webkit-mask-position:100% 0;mask-position:100% 0}}@-webkit-keyframes radio-out{from{-webkit-mask-position:100% 0;mask-position:100% 0}to{-webkit-mask-position:0 0;mask-position:0 0}}@keyframes radio-out{from{-webkit-mask-position:100% 0;mask-position:100% 0}to{-webkit-mask-position:0 0;mask-position:0 0}}input[type=radio].ui-radio{position:relative;height:32px;width:32px;box-sizing:border-box;outline:0;-webkit-appearance:none;margin:0 18px}input[type=radio].ui-radio::before{content:"";position:absolute;left:0;top:0;width:32px;height:32px;background-color:var(--ripple-color);border-radius:100%;opacity:0}input[type=radio].ui-radio::after{content:"";position:absolute;bottom:0;opacity:.8;background-color:var(--control-inactive-color);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:250ms;animation-duration:250ms;-webkit-animation-timing-function:steps(26);animation-timing-function:steps(26);width:100%;height:100%;-webkit-mask-image:url(images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg);mask-image:url(images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg);-webkit-mask-size:auto 100%;mask-size:auto 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:0 0;mask-position:0 0}input[type=radio].ui-radio.ui-radio-backward-animation::after{-webkit-animation-name:radio-out;animation-name:radio-out}input[type=radio].ui-radio:checked::after{background-color:var(--control-active-color);-webkit-animation-name:radio-in;animation-name:radio-in}input[type=radio].ui-radio:active::before{opacity:1}input[type=radio].ui-radio:disabled{opacity:.4}@-webkit-keyframes EXPAND{0%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}50%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.3);-ms-transform:translate(-50%,-50%) scale(1.3);transform:translate(-50%,-50%) scale(1.3)}100%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1.3);-ms-transform:translate(-50%,-50%) scale(1.3);transform:translate(-50%,-50%) scale(1.3)}}@keyframes EXPAND{0%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}50%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.3);-ms-transform:translate(-50%,-50%) scale(1.3);transform:translate(-50%,-50%) scale(1.3)}100%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1.3);-ms-transform:translate(-50%,-50%) scale(1.3);transform:translate(-50%,-50%) scale(1.3)}}.ui-text-input-container{width:100%}textarea.ui-text-input{resize:none;overflow:hidden;white-space:normal;transition:height 200ms linear}.ui-group-index+.ui-li-static input.ui-text-input,.ui-group-index+.ui-li-static textarea.ui-text-input{padding:0 13px 0 5px}.ui-group-index+.ui-li-static input.ui-text-input+.ui-text-input-textline,.ui-group-index+.ui-li-static textarea.ui-text-input+.ui-text-input-textline{margin:5.5px 8px 10px 0}.ui-group-index+.ui-li-static input.ui-text-input~.ui-text-input-clear,.ui-group-index+.ui-li-static textarea.ui-text-input~.ui-text-input-clear{right:0}.ui-group-index+.ui-li-static input.ui-text-input:focus.ui-text-input-clear-active,.ui-group-index+.ui-li-static textarea.ui-text-input:focus.ui-text-input-clear-active{padding-right:40px}.ui-li-static input.ui-text-input+.ui-text-input-textline,.ui-li-static textarea.ui-text-input+.ui-text-input-textline{position:absolute;width:calc(100% - 32px)}.ui-li-static input.ui-text-input+.ui-text-input-textline+.ui-text-input-error-message,.ui-li-static textarea.ui-text-input+.ui-text-input-textline+.ui-text-input-error-message{margin:8px 0 0}.ui-li-flex input.ui-text-input,.ui-li-flex textarea.ui-text-input{padding:0 5px}.ui-li-flex input.ui-text-input+.ui-text-input-textline,.ui-li-flex textarea.ui-text-input+.ui-text-input-textline{margin:5.5px 0 -6px 0}.ui-li-flex input.ui-text-input~.ui-text-input-clear,.ui-li-flex textarea.ui-text-input~.ui-text-input-clear{top:0;margin-top:-35px;margin-bottom:-6px;right:0}.ui-popup textarea.ui-text-input{min-height:27px;padding:0}.ui-popup textarea.ui-text-input+.ui-text-input-textline{margin-left:0;margin-right:0;margin-bottom:5.5px}input.ui-text-input,textarea.ui-text-input{border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;display:block;width:100%;line-height:26px;font-family:Roboto-Regular;-webkit-text-fill-color:transparent;font-size:19px;background-color:transparent;border:0;caret-color:var(--primary-color);margin:8px 0}input.ui-text-input.ui-text-input-disabled,textarea.ui-text-input.ui-text-input-disabled,input.ui-text-input:disabled,textarea.ui-text-input:disabled{text-shadow:0 0 0 var(--text-input-disabled)}input.ui-text-input.ui-text-input-disabled::-webkit-input-placeholder,textarea.ui-text-input.ui-text-input-disabled::-webkit-input-placeholder,input.ui-text-input:disabled::-webkit-input-placeholder,textarea.ui-text-input:disabled::-webkit-input-placeholder{text-shadow:0 0 0 var(--text-input-disabled)}input.ui-text-input:not([disabled]),textarea.ui-text-input:not([disabled]){text-shadow:0 0 0 var(--text-color)}input.ui-text-input:not([disabled])::-webkit-input-placeholder,textarea.ui-text-input:not([disabled])::-webkit-input-placeholder{text-shadow:0 0 0 var(--text-input-underline-inactive)}input.ui-text-input+.ui-text-input-textline,textarea.ui-text-input+.ui-text-input-textline{height:1px;background:var(--text-input-underline-inactive);box-sizing:border-box;display:block}input.ui-text-input+.ui-text-input-textline+.ui-text-input-error-message,textarea.ui-text-input+.ui-text-input-textline+.ui-text-input-error-message{display:none;color:var(--text-input-invalid-color);font-size:12px}input.ui-text-input:focus,textarea.ui-text-input:focus{outline:0}input.ui-text-input:focus.ui-text-input-clear-active,textarea.ui-text-input:focus.ui-text-input-clear-active{padding-right:11px}input.ui-text-input:focus+.ui-text-input-textline,textarea.ui-text-input:focus+.ui-text-input-textline{height:2px;background:var(--primary-color)}input.ui-text-input:invalid+.ui-text-input-textline,textarea.ui-text-input:invalid+.ui-text-input-textline{background:var(--text-input-invalid-color)}input.ui-text-input:invalid+.ui-text-input-textline+.ui-text-input-error-message,textarea.ui-text-input:invalid+.ui-text-input-textline+.ui-text-input-error-message{display:block}input.ui-text-input~.ui-text-input-clear,textarea.ui-text-input~.ui-text-input-clear{display:block;float:right;top:-33.5px;box-sizing:border-box;margin-right:-8.5px;margin-left:8.5px;position:relative;width:40px;height:40px}input.ui-text-input~.ui-text-input-clear.ui-btn.ui-btn-icon.ui-btn-nobg::after,textarea.ui-text-input~.ui-text-input-clear.ui-btn.ui-btn-icon.ui-btn-nobg::after{-webkit-mask-image:url(images/controls/core_button_icon_clear.png);mask-image:url(images/controls/core_button_icon_clear.png);width:40px;height:40px}input.ui-text-input~.ui-text-input-clear-hidden,textarea.ui-text-input~.ui-text-input-clear-hidden{visibility:hidden}input.ui-text-input.ui-text-input-widget-focused,textarea.ui-text-input.ui-text-input-widget-focused{background-color:var(--textual-background)}.ui-textinput-box-with-right-button{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;-o-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;height:40px}.ui-textinput-box-with-right-button>*{height:33.5px;margin-top:3.5px;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item),.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item),.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg{max-width:64px;min-width:40px;-ms-flex-basis:auto;-o-flex-basis:auto;-webkit-flex-basis:auto;-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-order:1;-moz-order:1;-ms-order:1;-o-order:1;-ms-flex-order:1;order:1;width:auto;box-sizing:content-box;margin:0 10px 0 0;height:40px;min-height:40px;max-height:40px;padding:0 6px;background-color:transparent;overflow-x:visible;overflow-y:visible;color:#52c7d9;-webkit-mask-box-image-source:none;-webkit-align-self:flex-start;-ms-align-self:flex-start;-o-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::after,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::after,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg::after,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg::after{background-color:#52c7d9}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg::before,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg::before{background-color:var(--ripple-color);opacity:0}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active::before,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active::before,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-active::before,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-active::before{-webkit-animation:EXPAND 200ms;animation:EXPAND 200ms;-webkit-animation-fill-mode:both;animation-fill-mode:both;opacity:0}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon{padding:0 8.5px;margin-right:0}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::before,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::before,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon::before,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon::before{border-radius:20px;width:40px}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::after,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::after,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon::after,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon::after{-webkit-mask-size:40px,40px;-moz-mask-size:40px,40px;-ms-mask-size:40px,40px;-o-mask-size:40px,40px;mask-size:40px,40px;-webkit-mask-repeat:none;-moz-mask-repeat:none;-ms-mask-repeat:none;-o-mask-repeat:none;mask-repeat:none;-webkit-mask-position:center center;-moz-mask-position:center center;-ms-mask-position:center center;-o-mask-position:center center;mask-position:center center}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-text-light::before,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-text-light::before,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-text-light::before,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-text-light::before{border-radius:5px;width:58px;height:32.5px}.ui-textinput-box-with-right-button input.ui-text-input~.ui-text-input-clear{right:5px;left:5px}.ui-textinput-box-with-right-button input.ui-text-input:focus.ui-text-input-clear-active{padding-right:20px;margin-right:-15px}.ui-listview li.ui-textinput-box-with-right-button{padding-right:0}.ui-controlgroup .ui-radio>.ui-btn{background:var(--background-color)}.ui-controlgroup .ui-btn-inner.ui-corner-left{border-radius:0;background-clip:padding-box}.ui-controlgroup .ui-btn-inner.ui-corner-right.ui-controlgroup-last{border-radius:0;background-clip:padding-box}.ui-controlgroup .ui-radio-on .ui-btn-inner{color:#3b7796}.ui-controlgroup .ui-radio-off .ui-btn-inner{color:#c7c7c7}.ui-controlgroup.ui-controlgroup-horizontal .ui-radio-on .ui-btn-inner{color:#fafafa}.ui-page{border-top:0;background:var(--background-color);color:var(--text-color);font-weight:400;font-family:Roboto-Regular}.ui-page .ui-link-inherit{color:#fff}.ui-page .ui-link{color:#2489CE;font-weight:700}.ui-page .ui-link:hover{color:#2489CE}.ui-page .ui-link:active{color:#2489CE}.ui-page .ui-link:visited{color:#2489CE}a.ui-link-inherit{text-decoration:none!important}.ui-btn-active{color:var(--primary-color);cursor:pointer;text-decoration:none;background:var(--on-background);outline:0}.ui-btn-active a.ui-link-inherit{color:var(--primary-color)}.ui-corner-tl{border-top-left-radius:.3em}.ui-corner-tr{border-top-right-radius:.3em}.ui-corner-bl{border-bottom-left-radius:.3em}.ui-corner-br{border-bottom-right-radius:.3em}.ui-corner-top{border-top-left-radius:.3em;border-top-right-radius:.3em}.ui-corner-bottom{border-bottom-left-radius:.3em;border-bottom-right-radius:.3em}.ui-corner-right{border-top-right-radius:.3em;border-bottom-right-radius:.3em}.ui-corner-left{border-top-left-radius:.3em;border-bottom-left-radius:.3em}.ui-corner-none{border-radius:0}.ui-btn .ui-icon.ui-icon-naviframe-edit,.ui-btn .ui-icon.ui-icon-naviframe-plus,.ui-btn .ui-icon.ui-icon-naviframe-delete,.ui-btn .ui-icon.ui-icon-naviframe-search,.ui-btn .ui-icon.ui-icon-naviframe-selectall,.ui-btn .ui-icon.ui-icon-naviframe-drawer{-webkit-mask-size:100%;-moz-mask-size:100%;-ms-mask-size:100%;-o-mask-size:100%;mask-size:100%}.ui-popup.ui-ctxpopup{width:auto;padding:0;background-color:transparent;margin-top:0;max-width:100%}.ui-popup.ui-ctxpopup .ui-popup-content{width:auto;padding:0;overflow:hidden}.ui-popup.ui-ctxpopup .ui-popup-content>ul{overflow:auto}.ui-popup.ui-ctxpopup .ui-popup-content>ul::-webkit-scrollbar{height:4px}.ui-popup.ui-ctxpopup .ui-popup-content>ul::-webkit-scrollbar-thumb{background-color:var(--primary-color);border-radius:1.5px;border-bottom:1px solid #fff}.ui-popup.ui-ctxpopup .ui-popup-content>ul::-webkit-scrollbar-button{width:2px;height:4px;background-color:transparent}.ui-popup.ui-ctxpopup .ui-popup-wrapper{background-color:var(--more-options-background-color);border:1px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none;overflow:auto;margin-left:16px;margin-right:16px;width:auto}.ui-popup.ui-ctxpopup :focus{outline:0}.ui-popup.ui-ctxpopup.slideup.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:slideupfadeinfrombottom 250ms;animation:slideupfadeinfrombottom 250ms}.ui-popup.ui-ctxpopup.slideup.out{-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0);-webkit-animation:slideupfadeouttobottom 200ms;animation:slideupfadeouttobottom 200ms}.ui-popup.ui-ctxpopup .ui-listview{margin:0;border:0;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-popup.ui-ctxpopup .ui-listview li{-webkit-flex:1 0 auto;-moz-flex:1 0 auto;-ms-flex:1 0 auto;-o-flex:1 0 auto;flex:1 0 auto}.ui-popup.ui-ctxpopup .ui-listview .ui-li-anchor a{font-size:15px;line-height:20.5px;padding:0 16px;min-height:36px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview{-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview .ui-li-anchor a{height:40px;-webkit-flex-direction:row;-moz-flex-direction:row;-ms-flex-direction:row;-o-flex-direction:row;flex-direction:row;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:flex-start;-moz-justify-content:flex-start;-ms-justify-content:flex-start;-o-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;text-align:left;padding-top:0;padding-bottom:0}.ui-popup.ui-ctxpopup .ui-listview li{color:var(--text-color);font-size:15px;border-top:0;border-bottom:0;border-right:0;border-left:1px solid var(--more-options-background-color)}.ui-popup.ui-ctxpopup .ui-listview li:first-of-type{border-left-width:0}.ui-popup.ui-ctxpopup .ui-listview li.ui-li-anchor>a{box-sizing:border-box;padding-top:7.5px;padding-bottom:7.5px}.ui-popup.ui-ctxpopup .ui-listview li.ui-li-anchor.ui-li-active{background-color:var(--more-options-pressed-color)}.ui-popup.ui-ctxpopup.ui-ctxpopup-basic .ui-li-anchor{padding:0 16px;height:36px}.ui-popup.ui-ctxpopup.ui-ctxpopup-basic .ui-li-anchor>a{padding:0;margin:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor{padding:0;height:40px;width:53px}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor>a{padding:0;margin:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor>a>span{padding:0;margin:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor{padding:0 16px;height:59px}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor>a{padding:0;margin:0;font-size:13px;line-height:20px}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor>a>span{padding:0;margin:0 0 2px}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li{border-top:1px solid var(--more-options-background-color);border-bottom:0;border-right:0;border-left:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li:first-of-type{border-top-width:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li.ui-li-anchor{padding:0 12px;height:40px}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li.ui-li-anchor>a{margin:0;padding:0;overflow:visible}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-icon{display:inline-block;vertical-align:middle;margin-top:0;margin-bottom:0;margin-right:10px;margin-left:-2px}.ui-popup.ui-ctxpopup .ui-icon{width:20px;height:20px;display:block;vertical-align:middle;margin:2px auto}.ui-text-ellipsis{white-space:nowrap;text-overflow:ellipsis;-o-text-overflow:ellipsis;overflow:hidden!important}.ui-popup.ui-popup-toast{background-color:transparent;margin:0 auto;position:relative;bottom:0;width:100%}.ui-popup.ui-popup-toast .ui-popup-content{margin:auto;margin-bottom:64px;width:-webkit-fit-content;width:fit-content;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;border-radius:22px;background-color:var(--toast-background);padding:12px 20px;line-height:20px;color:var(--toast-text-color);font-size:16px;font-family:Roboto-Regular}@media all and (max-width:479px){.ui-popup.ui-popup-toast .ui-popup-content{max-width:84%}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button{width:84%}}@media all and (min-width:480px) and (max-width:959px){.ui-popup.ui-popup-toast .ui-popup-content{max-width:68%}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button{width:68%}}@media all and (min-width:960px) and (max-width:1919px){.ui-popup.ui-popup-toast .ui-popup-content{max-width:37.5%}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button{width:37.5%}}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button{text-align:left;min-height:44px;padding:0 20px;background-color:var(--btn-toast-background)}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn{padding:4px 0 4px 20px;margin:0;width:-webkit-fit-content;width:fit-content;color:var(--btn-toast-text-color);font-size:18px;font-family:Roboto-Medium;background-color:transparent;line-height:36px;overflow:visible}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item){background-color:transparent;border:0;border-radius:0;padding-right:20px;margin-right:-20px}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before{background-color:var(--ripple-color)}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active{background-color:transparent}.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content{display:block;padding:12px 20px}.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content.ui-popup-toast-has-button{padding-top:9px;padding-bottom:4px}.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content.ui-popup-toast-has-button .ui-btn{margin-left:auto;padding-top:5px;padding-bottom:0}@-webkit-keyframes ui-smallpopup-show{from{display:none;opacity:0;-webkit-transform:scaleY(0);-ms-transform:scaleY(0);transform:scaleY(0)}to{display:block;opacity:1;-webkit-transform:scaleY(1);-ms-transform:scaleY(1);transform:scaleY(1)}}@keyframes ui-smallpopup-show{from{display:none;opacity:0;-webkit-transform:scaleY(0);-ms-transform:scaleY(0);transform:scaleY(0)}to{display:block;opacity:1;-webkit-transform:scaleY(1);-ms-transform:scaleY(1);transform:scaleY(1)}}.ui-smallpopup{position:fixed;display:none;margin-bottom:32px;max-width:236px;z-index:1100;vertical-align:middle;font-size:16px;word-break:break-all}.ui-smallpopup::before{position:absolute;content:'';width:100%;height:100%}.ui-smallpopup.fix{display:block}.ui-smallpopup.show{display:block;-webkit-animation:ui-smallpopup-show 500ms 1 ease;animation:ui-smallpopup-show 500ms 1 ease}.ui-smallpopup.hide{display:none}.ui-smallpopup-text-bg{position:relative;padding:3.5px 12px 5px;line-height:18.5px;margin:0;color:var(--toast-text-color);font-size:16px}.ui-popup{display:none;position:absolute;left:0;margin-bottom:16px;margin-top:32px;z-index:1201!important;background-color:var(--popup-background);border-radius:26px}@media (max-width:479px){.ui-popup{width:100%}}@media (min-width:480px) and (max-width:672px){.ui-popup{width:63%}}@media (min-width:673px) and (max-width:985px){.ui-popup{width:55%}}@media (min-width:986px){.ui-popup{width:35%}}.ui-popup .ui-popup-wrapper{width:100%}.ui-popup.ui-popup-active{display:block}.ui-popup.in{display:block}.ui-popup.ui-build{display:block;visibility:hidden}.ui-popup .ui-popup-header{width:100%;text-align:left;background-color:var(--popup-background);position:-webkit-sticky;position:sticky;font-size:20px;color:var(--text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:Roboto-Medium}.ui-popup .ui-popup-header::after{content:"";position:absolute;left:24px;width:calc(100% - 48px);height:.75px;stroke-width:.5;visibility:hidden;background-color:var(--popup-scroll-divider-color)}@media (orientation:portrait){.ui-popup .ui-popup-header::after{top:68px}}@media (orientation:landscape){.ui-popup .ui-popup-header::after{top:45px}}.ui-popup .ui-popup-header.topDivider::after{visibility:visible}.ui-popup .ui-popup-header.ui-popup-header-has-subtitle{padding:9.75px 16px;line-height:28.5px;font-size:20px;color:T1212}.ui-popup .ui-popup-header .ui-popup-subtitle{line-height:19px}@media (orientation:portrait){.ui-popup .ui-popup-header{padding:26px 24px 19px}}@media (orientation:landscape){.ui-popup .ui-popup-header{padding:14px 24px 8px}}.ui-popup .ui-popup-content{width:100%;background-color:var(--popup-background);color:var(--popup-text);text-align:left;font-size:16px;overflow:auto;-webkit-overflow-scrolling:touch;-moz-overflow-scrolling:touch;-o-overflow-scrolling:touch;-ms-overflow-scrolling:touch;overflow-scrolling:touch;line-height:23px}.ui-popup .ui-popup-content img{display:block;margin:0 auto;padding-bottom:12px}.ui-popup .ui-popup-content.ui-date-picker-calendar{padding-left:16px;padding-right:16px}.ui-popup .ui-popup-content .ui-popup-body-text{margin-top:8px}.ui-popup .ui-popup-content .ui-popup-body-checkbox{margin-top:8px;height:32px;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-popup .ui-popup-content .ui-popup-body-checkbox input[type=Checkbox]{margin:0 12px 0 -4px}.ui-popup .ui-popup-content .ui-popup-body-checkbox span{margin-top:5px}.ui-popup .ui-popup-content ul .ui-li-has-checkbox .ui-li-text span{font-size:18px}.ui-popup .ui-popup-content ul .ui-li-has-checkbox input{margin-left:18px;margin-right:18px}.ui-popup .ui-popup-content .ui-popup-container-text{width:100%;height:19px;line-height:19px;color:var(--popup-text-color);font-size:14px;font-family:Roboto-Regular}.ui-popup .ui-popup-content .ui-popup-container-text .text-left{float:left}.ui-popup .ui-popup-content .ui-popup-container-text .text-right{float:right}@media (orientation:portrait){.ui-popup .ui-popup-content{padding:0 24px;margin-bottom:24px}}@media (orientation:landscape){.ui-popup .ui-popup-content{padding:0 24px;margin-bottom:11px}}.ui-popup .ui-popup-content.ui-popup-has-time-picker,.ui-popup .ui-popup-content.ui-popup-has-date-picker{padding-left:unset;padding-right:unset}.ui-popup .ui-popup-footer{background-color:var(--popup-background);position:-webkit-sticky;position:sticky;box-sizing:border-box;padding:12px 24px;text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;width:100%}.ui-popup .ui-popup-footer::before{content:"";position:absolute;left:24px;width:calc(100% - 48px);height:.75px;stroke-width:.5;visibility:hidden;background-color:var(--popup-scroll-divider-color)}@media (orientation:portrait){.ui-popup .ui-popup-footer::before{bottom:80px}}@media (orientation:landscape){.ui-popup .ui-popup-footer::before{bottom:50px}}.ui-popup .ui-popup-footer.bottomDivider::before{visibility:visible}.ui-popup .ui-popup-footer .ui-btn{height:36px;margin:0 auto;max-width:248px}.ui-popup .ui-popup-footer .ui-btn.ui-btn-flat{font-size:16px}.ui-popup .ui-popup-footer div.ui-li-divider::after{content:"";position:absolute;width:1px;height:16px;top:10px;background-color:var(--popup-footer-divider-color)}.ui-popup .ui-popup-footer .ui-popup-stack .ui-btn{margin-bottom:16px}.ui-popup .ui-popup-footer .ui-popup-stack .ui-btn:nth-last-child(1){margin-bottom:0}.ui-popup .ui-popup-footer .ui-li-action{width:50%}@media (orientation:portrait){.ui-popup .ui-popup-footer{padding:0 24px 20px}}@media (orientation:landscape){.ui-popup .ui-popup-footer{padding:0 24px 4px}}.ui-popup .ui-listview{margin-left:-24px}@media (orientation:portrait){.ui-popup .ui-popup-notitle{margin-top:26px}}@media (orientation:landscape){.ui-popup .ui-popup-notitle{margin-top:14px}}.ui-popup .ui-popup-2level-description{height:auto;margin-top:8px;margin-left:8px;color:var(--popup-text-secondary-color)}.ui-popup .ui-popup-2level-description span{padding-right:12px}.ui-popup .ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a{margin-top:14px;margin-bottom:14px}.ui-popup .ui-popup-header,.ui-popup .ui-popup-content,.ui-popup .ui-popup-footer{box-sizing:border-box}.ui-popup.ui-popup-listview{background-image:url(images/page/core_theme_bg_01.png);background-repeat:no-repeat;background-size:100% 100%;overflow:hidden;background-color:transparent}.ui-popup.ui-popup-listview .ui-popup-header{padding-top:8px;padding-bottom:8px}.ui-popup.ui-popup-listview .ui-popup-content{padding:0;background-color:transparent;position:relative}.ui-popup.ui-popup-listview .ui-listview{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui-popup.ui-popup-listview .ui-listview::before{content:"";background-color:var(--overlay);width:100%;height:100%;display:block;position:absolute;top:0;z-index:1;pointer-events:none}.ui-popup.ui-popup-moremenu{max-height:420px;overflow:hidden}@media (orientation:landscape){.ui-popup.ui-popup-moremenu{max-height:300px;width:360px}}.ui-popup-overlay{display:none;background-color:var(--overlay);background-repeat:no-repeat;background-size:100% 100%;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1200}.ui-popup-overlay.ui-popup-overlay-shown{display:block}.ui-popup.ui-popup-activity .ui-popup-content{text-align:right}@media (orientation:landscape){.ui-popup.ui-popup-activity .ui-popup-content{width:100%}}@-webkit-keyframes popup-activity{from{-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes popup-activity{from{-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@media (orientation:landscape){.ui-popup.ui-popup-activity{width:100%}}.ui-popup.ui-popup-activity.ui-popup-activity-small .ui-popup-content{text-align:right;height:39px;padding:8px 16px;font-size:20px;color:T120L1}.ui-popup.ui-popup-activity.ui-popup-activity-small .ui-popup-content::after{content:"";width:22px;height:22px;margin-left:16px;background-color:W157E1;-webkit-mask-image:url(images/core_activity_indicator_a.svg),url(images/core_activity_indicator_b.svg),url(images/core_activity_indicator_c.svg);mask-image:url(images/core_activity_indicator_a.svg),url(images/core_activity_indicator_b.svg),url(images/core_activity_indicator_c.svg);-webkit-mask-size:100% 100%,100% 100%,100% 100%;mask-size:100% 100%,100% 100%,100% 100%;float:right;-webkit-animation-name:popup-activity;animation-name:popup-activity;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.ui-popup.ui-popup-activity.ui-popup-activity-medium .ui-popup-content{text-align:left;height:60px;padding:16px;font-size:20px;color:T120L2}.ui-popup.ui-popup-activity.ui-popup-activity-medium .ui-popup-content::before{content:"";width:28px;height:28px;margin-right:16px;background-color:W157E1;float:left;-webkit-mask-image:url(images/core_activity_indicator_a.svg),url(images/core_activity_indicator_b.svg),url(images/core_activity_indicator_c.svg);mask-image:url(images/core_activity_indicator_a.svg),url(images/core_activity_indicator_b.svg),url(images/core_activity_indicator_c.svg);-webkit-mask-size:100% 100%,100% 100%,100% 100%;mask-size:100% 100%,100% 100%,100% 100%;-webkit-animation-name:popup-activity;animation-name:popup-activity;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.ui-popup.ui-popup-activity.ui-popup-activity-large .ui-popup-content{text-align:center;height:0;background-color:W157E1;-webkit-mask-image:url(images/core_activity_indicator_c.svg);mask-image:url(images/core_activity_indicator_c.svg);-webkit-mask-size:100% 100%;mask-size:100% 100%}.ui-popup:not(.ui-ctxpopup).slideup.out{-webkit-animation:popupslideouttobottom 400ms ease-out;animation:popupslideouttobottom 400ms ease-out}.ui-popup:not(.ui-ctxpopup).slideup.in{-webkit-animation:popupslideinfrombottom 400ms ease-out;animation:popupslideinfrombottom 400ms ease-out}.ui-popup.slideup.in:not(.ui-ctxpopup) .ui-popup-wrapper{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%);-webkit-animation:popupwrapperslideinfrombottom 350ms ease-out 50ms;animation:popupwrapperslideinfrombottom 350ms ease-out 50ms}.ui-popup.slideup.out:not(.ui-ctxpopup) .ui-popup-wrapper{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px);-webkit-animation:popupwrapperslideouttobottom 4000ms ease-out;animation:popupwrapperslideouttobottom 4000ms ease-out}.ui-popup-overlay.slideup.in:not(.ui-ctxpopup-overlay){-webkit-animation:popupoverlayfadein 400ms ease-out;animation:popupoverlayfadein 400ms ease-out}.ui-popup-overlay.slideup.out:not(.ui-ctxpopup-overlay){-webkit-animation:popupoverlayfadeout 400ms ease-out;animation:popupoverlayfadeout 400ms ease-out}@-webkit-keyframes popupslideouttobottom{from{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}to{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}}@keyframes popupslideouttobottom{from{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}to{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}}@-webkit-keyframes popupslideinfrombottom{from{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@keyframes popupslideinfrombottom{from{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@-webkit-keyframes popupwrapperslideinfrombottom{from{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@keyframes popupwrapperslideinfrombottom{from{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@-webkit-keyframes popupwrapperslideouttobottom{from{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}to{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px)}}@keyframes popupwrapperslideouttobottom{from{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}to{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px)}}@-webkit-keyframes popupoverlayfadein{from{opacity:0}to{opacity:1}}@keyframes popupoverlayfadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes popupoverlayfadeout{from{opacity:1}to{opacity:0}}@keyframes popupoverlayfadeout{from{opacity:1}to{opacity:0}}.ui-scrollview-clip{display:block;position:relative;z-index:100;overflow-x:hidden;overflow-y:visible}.ui-scrollview-clip[data-scroll="x"]{-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory}.ui-scrollview-clip[data-scroll="x"] .ui-scrollview-view{overflow:initial}.ui-scrollview-view{overflow:hidden;min-height:100%;min-width:100%;box-sizing:border-box}.ui-scrolllistview .ui-li-divider{z-index:10}.ui-scrollbar{position:absolute;overflow:hidden;opacity:0}.ui-scrollbar-visible{opacity:1}.ui-scrollbar-y{top:0;right:1px;bottom:0;width:4px}.ui-scrollbar-x{right:1px;bottom:1px;left:1px;height:4px}.ui-scrollbar-track{position:relative;width:100%;height:100%}.ui-scrollbar-thumb{position:absolute;top:0;left:0;background-color:var(--primary-color)}.ui-scrollbar-y .ui-scrollbar-thumb{width:2.5px;height:100%;border-radius:1px;-o-box-shadow:.5px .5px 2px #080808;-ms-box-shadow:.5px .5px 2px #080808;box-shadow:.5px .5px 2px #080808}.ui-scrollbar-x .ui-scrollbar-thumb{width:100%;height:2.5px;border-radius:1px}.ui-scroll-jump-top-bg{position:absolute;top:4.5px;right:6.5px;width:18.5px;height:18.5px}.ui-scroll-jump-left-bg{position:absolute;bottom:4.5px;left:6.5px;width:18.5px;height:18.5px}.ui-overflow-indicator-top,.ui-overflow-indicator-bottom{position:absolute;display:none;width:100%;height:14.5px;opacity:1;background-repeat:no-repeat;background-size:100% 100%}.ui-overflow-indicator-top{top:0}.ui-overflow-indicator-bottom{bottom:0}.ui-overflow-effect-bottom{position:absolute;display:none;bottom:0;width:100%}.ui-overflow-top{opacity:1}.ui-overflow-top.ui-overflow-top-hide{height:0!important}.ui-overflow-bottom{opacity:1}.ui-overflow-bottom.ui-overflow-bottom-hide{height:0!important}.ui-content.ui-scrollview-clip{padding:0}.ui-content.ui-scrollview-clip>div.ui-scrollview-view{margin:0}.ui-content.ui-scrollview-clip>.ui-listview.ui-scrollview-view{margin:0}.ui-content.ui-scrollview-clip.ui-hide-scrollbar::-webkit-scrollbar{display:none}.ui-slider{position:relative;box-sizing:border-box;height:32px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:space-around;-ms-flex-pack:distribute;justify-content:space-around}.ui-slider .ui-slider-bar{background-color:var(--slider-bg-color);height:3px;border-radius:1.5px;overflow:hidden}.ui-slider .ui-slider-bar .ui-slider-value{height:100%;background-color:var(--slider-handler-color)}.ui-slider:focus{outline:0}.ui-slider .ui-slider-handler-track{position:absolute;width:100%;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-slider .ui-slider-handler-track .ui-slider-before-space{height:1px}.ui-slider .ui-slider-handler-track .ui-slider-after-space{height:1px}.ui-slider .ui-slider-handler{width:17px;height:17px;min-width:17px;min-height:17px;background-color:var(--slider-value-color);position:relative;border-radius:50%;pointer-events:none;z-index:9}.ui-slider .ui-slider-handler::before{content:"";width:32px;height:32px;opacity:0;position:absolute;left:-5px;top:-5px;border-radius:100%;background-color:var(--ripple-color)}.ui-slider.ui-slider-active .ui-slider-handler{min-width:22px;min-height:22px}.ui-slider.ui-slider-active .ui-slider-handler::before{opacity:1}.ui-slider.ui-disabled .ui-slider-bar{background-color:var(--slider-bg-disabled-color)}.ui-slider.ui-disabled .ui-slider-bar .ui-slider-value{background-color:var(--slider-handler-disabled-color)}.ui-slider.ui-disabled .ui-slider-handler{background-color:var(--slider-handler-disabled-color)}.ui-slider.ui-slider-level-bar{margin-left:5px;margin-right:5px;height:32px}.ui-slider.ui-slider-level-bar .ui-slider-bar{background-color:var(--slider-level-bar-bg-color)}.ui-slider.ui-slider-level-bar .ui-slider-bar .ui-slider-value{display:none}.ui-slider.ui-slider-level-bar .ui-slider-bar::before{display:none;border-image:none}.ui-slider.ui-slider-level-bar input{width:100%}.ui-slider.ui-slider-level-bar .ui-slider-scale{position:absolute;width:100%;height:7px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;pointer-events:none}.ui-slider.ui-slider-level-bar .ui-slider-scale .ui-slider-scale-dot{width:7px;height:7px;border-radius:100%;background-color:var(--slider-scale-dot)}.ui-slider.ui-slider-level-bar .ui-slider-handler-track{width:calc(100% + 10px);left:-5px}.ui-slider-label{font-size:12px;color:var(--text-secondary-color)}.ui-slider-label-min{position:absolute;left:0;bottom:-2px}.ui-slider-label-max{position:absolute;right:0;bottom:-2px}.ui-slider.ui-slider-has-labels{height:50px}input[data-tau-built=Slider]{opacity:0;display:block;width:100%;position:absolute;margin:0}tau-toggleswitch{display:block}.ui-toggle-container{position:relative;width:36px;height:36px}.ui-toggle-container .ui-switch-handler{position:absolute;width:100%;height:100%;top:0;left:0;background-color:transparent;pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.ui-toggle-container .ui-switch-handler:before,.ui-toggle-container .ui-switch-handler:after{content:"";position:absolute;height:100%;width:100%;-webkit-mask-position:center center;mask-position:center center;-webkit-mask-size:100%;mask-size:100%}.ui-toggle-container .ui-switch-handler:before{background-color:W015L1i;-webkit-mask-image:url(images/controls/core_toggle_icon_off.svg);mask-image:url(images/controls/core_toggle_icon_off.svg);-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);transition:250ms ease-out 50ms}.ui-toggle-container .ui-switch-handler:after{background-color:W015L1i;-webkit-mask-image:url(images/controls/core_toggle_icon_on.svg);mask-image:url(images/controls/core_toggle_icon_on.svg);-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);transition:100ms ease-out}.ui-toggle-container input[type=checkbox].ui-toggle-switch{width:36px;height:36px;border-radius:50%;background-color:W015L1E1;-webkit-appearance:none;-moz-appearance:none;appearance:none;outline:0;margin:0;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px;transition:background-color 150ms}.ui-toggle-container input[type=checkbox].ui-toggle-switch::before{content:none}.ui-toggle-container input[type=checkbox].ui-toggle-switch:checked{background-color:var(--color-white)}.ui-toggle-container input[type=checkbox].ui-toggle-switch:checked~.ui-switch-handler::before{-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);transition:100ms ease-out}.ui-toggle-container input[type=checkbox].ui-toggle-switch:checked~.ui-switch-handler::after{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);transition:250ms ease-out 50ms}.ui-toggle-container input[type=checkbox].ui-toggle-switch:disabled{background-color:W015L1D}.ui-toggle-switch-focus{outline:2px solid var(--primary-color)}@-webkit-keyframes move-to-off{to{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes move-to-off{to{-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes move-to-on{to{-webkit-transform:translateX(17px);transform:translateX(17px)}}@keyframes move-to-on{to{-webkit-transform:translateX(17px);transform:translateX(17px)}}.ui-on-off-switch-container{position:relative;display:inline-block;width:43px;height:27px;max-width:43px;max-height:27px;min-width:43px;min-height:27px;overflow:hidden}.ui-on-off-switch-input{position:absolute;width:37px;height:18.5px;border-radius:9.25px;-webkit-appearance:none;display:block;margin:4.25px 3px;border:1px solid var(--on-off-switch-off-button-border);background-color:var(--on-off-switch-off-track-background);outline:0;box-sizing:border-box}.ui-on-off-switch-input:active~.ui-on-off-switch-button::before{opacity:1}.ui-on-off-switch-input:disabled{border-color:var(--on-off-switch-off-disabled-track-border)}.ui-on-off-switch-input:disabled~.ui-on-off-switch-button{border-color:var(--on-off-switch-off-disabled-button-border);background-color:var(--on-off-switch-on-disabled-button-background)}.ui-on-off-switch-button{width:22px;height:22px;border-radius:100%;margin:2.5px 2px;box-sizing:border-box;border:1px solid var(--on-off-switch-off-button-border);background-color:var(--color-white);position:absolute;top:0;left:0;pointer-events:none;z-index:1;transition:-webkit-transform cubic-bezier(0.6,.6,.8,1.49) 250ms;transition:transform cubic-bezier(0.6,.6,.8,1.49) 250ms;transition:transform cubic-bezier(0.6,.6,.8,1.49) 250ms, -webkit-transform cubic-bezier(0.6,.6,.8,1.49) 250ms;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui-on-off-switch-button::before{content:"";width:27px;height:27px;opacity:0;position:absolute;left:-3px;top:-3px;border-radius:100%;background-color:var(--ripple-color)}.ui-on-off-switch-button-on-drag{transition:none}.ui-on-off-switch-button-on-drag::before{opacity:1}.ui-on-off-switch-button-move-to-off{-webkit-animation:move-to-off 100ms ease-in-out 0s 1 normal both;animation:move-to-off 100ms ease-in-out 0s 1 normal both;transition:none}.ui-on-off-switch-button-move-to-on{-webkit-animation:move-to-on 100ms ease-in-out 0s 1 normal both;animation:move-to-on 100ms ease-in-out 0s 1 normal both;transition:none}.ui-on-off-switch-input:checked{background-color:var(--primary-color);border-color:var(--primary-color);width:37px;height:18.5px;margin:4.25px 3px}.ui-on-off-switch-input:checked:disabled{background-color:var(--on-off-switch-on-disabled-track-background);border-color:transparent}.ui-on-off-switch-input:checked:disabled~.ui-on-off-switch-button{border-color:var(--on-off-switch-on-disabled-button-border)}.ui-on-off-switch-input:checked~.ui-on-off-switch-button{border-color:var(--primary-color);-webkit-transform:translate3d(17px,0,0);transform:translate3d(17px,0,0)}.ui-master-on-off-switch{font-family:Roboto-Regular;font-size:18px;margin-left:0;margin-right:0;margin-bottom:20px;height:64px;position:relative}.ui-master-on-off-switch .ui-on-off-label{background-color:var(--master-on-off-off-color);position:absolute;left:0;right:0;width:100%;height:100%;border-radius:26px;box-sizing:border-box;padding-left:24px;padding-right:24px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-master-on-off-switch .ui-on-off-label::before{content:"";width:100%;height:64px;opacity:0;position:absolute;left:0;top:0;border-radius:26px;background-color:var(--ripple-color)}.ui-master-on-off-switch .ui-on-off-label-active::before{opacity:1}.ui-master-on-off-switch .ui-on-off-label span{-webkit-flex:1;-ms-flex:1;flex:1}.ui-master-on-off-switch .ui-on-off-label-on{color:var(--color-white);background-color:var(--master-on-off-on-color)}.ui-master-on-off-switch .ui-on-off-switch-input:active~.ui-on-off-switch-button::before{opacity:0}.ui-sub-tab{display:-webkit-flex;display:-ms-flexbox;display:flex;width:calc(100% - 48px);height:56px;margin-left:24px;margin-right:24px;background-color:var(--sub-tab-bg-color)}.ui-sub-tab a{font-family:Roboto-Regular;font-size:15px;line-height:22px;padding-left:12px;padding-right:12px;color:var(--sub-tab-text-color);border-radius:18px;box-sizing:border-box;border:0 solid var(--sub-tab-border-color);display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;width:100%;min-height:36px;text-decoration:none}.ui-sub-tab a span{position:relative;-webkit-order:1;-ms-flex-order:1;order:1;height:100%;overflow-x:hidden;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-sub-tab a.ui-tab-active{font-family:Roboto-Medium;color:var(--sub-tab-active-text-color);border-width:1px}.ui-sub-tab a.ui-sub-tab-inactive-text-overflow span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-sub-tab a::before{content:"";width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;background-color:var(--ripple-color);border-radius:26px}.ui-sub-tab a.ui-btn-active{background-color:inherit}.ui-sub-tab a.ui-btn-active::before{-webkit-animation:animation_opacity_in linear 100ms,animation_opacity_out linear 400ms 100ms;animation:animation_opacity_in linear 100ms,animation_opacity_out linear 400ms 100ms}.ui-sub-tab ul{display:-webkit-flex;display:-ms-flexbox;display:flex;margin:0;padding:0;list-style:none;position:relative;height:100%;white-space:nowrap;font-size:0}.ui-sub-tab li{text-align:center;margin:auto 0}.ui-sub-tab:not(.ui-sub-tab-static) ul li{min-width:105px}.ui-sub-tab:not(.ui-sub-tab-static).ui-sub-tab-landscape ul li{min-width:135px}.ui-main-tab{display:none;width:calc(100% - 32px);height:60px;margin-left:16px;margin-right:16px;background-color:var(--bottom-bar-color);position:fixed;bottom:0}.ui-main-tab-visible{display:block}.ui-main-tab a{font-family:Roboto-Regular;font-size:15px;line-height:22px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:relative;left:0;top:0;height:100%;text-decoration:none;color:var(--tab-text-color);padding-left:10px;padding-right:10px}.ui-main-tab a>span,.ui-main-tab a>div{position:relative;-webkit-order:1;-ms-flex-order:1;order:1;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding-bottom:4px;overflow:hidden}.ui-main-tab a>span::before,.ui-main-tab a>div::before{content:"";position:absolute;width:100%;height:4px;border-bottom:2.5px dotted var(--primary-dark-color);bottom:.75px;box-sizing:border-box;opacity:0}.ui-main-tab a.ui-tab-active{color:var(--primary-dark-color);font-family:Roboto-Medium}.ui-main-tab a.ui-tab-active>span::before,.ui-main-tab a.ui-tab-active>div::before{opacity:1}.ui-main-tab a:disabled{color:var(--tab-text-color-dim)}.ui-main-tab a::before{content:"";width:100%;height:43px;top:8.5px;border-radius:26px;left:0;position:absolute;opacity:0;background-color:var(--ripple-color)}.ui-main-tab a.ui-btn-active{background-color:transparent}.ui-main-tab a.ui-btn-active::before{opacity:1}.ui-main-tab ul{margin:0;padding:0;list-style:none;position:relative;height:100%;white-space:nowrap;font-size:0;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-main-tab li{text-align:center;display:block;position:relative;overflow:hidden;height:100%;-webkit-flex:1;-ms-flex:1;flex:1}.ui-main-tab .ui-li-active a::before{opacity:1}.ui-main-tab .ui-tabs-badge{position:absolute;border-radius:25px;min-width:12px;background-color:var(--accent-badge);color:var(--color-white);top:1px;right:7px;text-align:center;padding:3.5px 7.5px;font-family:Roboto-Medium;font-size:11px}.ui-marquee-content::after{content:attr(title);text-indent:75px;position:absolute;display:none}.ui-marquee-content.ui-visible{padding-right:75px}.ui-marquee-content.ui-visible::after{display:inline}.ui-footer{padding:0;z-index:100}.ui-footer .ui-bottom-bar{display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;min-height:56px;background-color:var(--bottom-bar-color);padding:0 24px}.ui-footer .ui-bottom-bar .ui-btn{font-family:Roboto-Medium;font-size:18px;text-align:center;line-height:18px;max-width:100%;height:56px}.ui-footer .ui-bottom-bar .ui-btn.ui-btn~.ui-btn{margin-left:0}.ui-footer .ui-bottom-bar .ui-btn.ui-btn-icon{font-family:Roboto-Regular;font-size:12px;line-height:normal;max-width:100%}.ui-footer .ui-bottom-bar .ui-btn.ui-btn-icon-top~.ui-btn-icon-top{margin-left:10px}.ui-footer .ui-bottom-bar .ui-btn.ui-btn-text{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-footer .ui-bottom-bar.ui-bottom-bar-icons{padding:0 10px}.ui-footer .ui-bottom-bar.ui-hidden{display:none}@media all and (min-width:673px) and (min-height:411px){.ui-footer .ui-bottom-bar{margin:0 auto;width:75%;min-width:625px}.ui-footer .ui-bottom-bar.ui-bottom-bar-icons{min-width:653px}}.ui-tokentextarea{display:table;outline:0;position:relative;background-color:W010;margin-left:-7.5px;margin-right:-7.5px}.ui-tokentextarea .ui-tokentextarea-input-area{height:26.5px}.ui-tokentextarea .ui-tokentextarea-input-area .ui-text-line{display:none}.ui-scrollview-view>.ui-tokentextarea{margin-left:-4px;margin-right:-4px}.ui-tokentextarea .ui-tokentextarea-label{display:inline-block;text-align:center;position:relative;margin-left:6.5px;margin-right:3px;padding:11.5px 0;color:T059L2;font-size:15px}.ui-tokentextarea .ui-tokentextarea-input.ui-input-text{height:26.5px;outline:0;position:relative;border:0;padding:0;color:T059L1;background-color:W010;text-align:left;font-size:15px}.ui-tokentextarea-input-visible{display:inline-block}.ui-tokentextarea-input-invisible{display:none}.ui-tokentextarea div{display:inline-block;text-align:center;cursor:pointer;position:relative;padding:.2em .5em;font-size:15px;color:T020;text-overflow:ellipsis;white-space:nowrap;margin:4px 1px}.ui-tokentextarea-block{-webkit-mask-box-image-repeat:repeat;-moz-mask-box-image-repeat:repeat;-ms-mask-box-image-repeat:repeat;-o-mask-box-image-repeat:repeat;mask-box-image-repeat:repeat;-webkit-mask-box-image-width:auto;-moz-mask-box-image-width:auto;-ms-mask-box-image-width:auto;-o-mask-box-image-width:auto;mask-box-image-width:auto;-webkit-mask-box-image-source:url(images/nine-patch/core_button_bg.png);-webkit-mask-box-image-slice:37 38 36 38 fill;-moz-mask-box-image-slice:37 38 36 38 fill;-ms-mask-box-image-slice:37 38 36 38 fill;-o-mask-box-image-slice:37 38 36 38 fill;mask-box-image-slice:37 38 36 38 fill;background-color:var(--button-background);background-color:W012;margin-left:7.5px;margin-top:6px}.ui-tokentextarea-sblock{-webkit-mask-box-image-repeat:repeat;-moz-mask-box-image-repeat:repeat;-ms-mask-box-image-repeat:repeat;-o-mask-box-image-repeat:repeat;mask-box-image-repeat:repeat;-webkit-mask-box-image-width:auto;-moz-mask-box-image-width:auto;-ms-mask-box-image-width:auto;-o-mask-box-image-width:auto;mask-box-image-width:auto;-webkit-mask-box-image-source:url(images/nine-patch/core_button_bg.png);-webkit-mask-box-image-slice:37 38 36 38 fill;-moz-mask-box-image-slice:37 38 36 38 fill;-ms-mask-box-image-slice:37 38 36 38 fill;-o-mask-box-image-slice:37 38 36 38 fill;mask-box-image-slice:37 38 36 38 fill;background-color:var(--on-background);background-color:W012P;color:T020;margin-left:7.5px;margin-top:6px}.ui-tokentextarea .ui-tokentextarea-desclabel{display:inline-block;outline:0;position:relative;border:0;color:T059L2;text-align:left;font-size:15px;margin-left:1.5px}.ui-tokentextarea-link-base{position:absolute;right:0;bottom:2px;margin-right:4.5px}.ui-triangle-container{position:relative}.ui-triangle-container .ui-triangle{position:absolute;border-style:solid;border-color:transparent;border-width:10}.ui-triangle-container .ui-triangle-top{top:0;border-top-width:0;border-left-color:transparent;border-right-color:transparent;margin-left:-10}.ui-triangle-container .ui-triangle-bottom{bottom:0;border-bottom-width:0;border-left-color:transparent;border-right-color:transparent;margin-left:-10}.ui-triangle-container .ui-triangle-left{left:0;margin-top:-10;border-left-width:0;border-left-color:transparent;border-right-color:transparent}.ui-triangle-container .ui-triangle-right{right:0;margin-top:-10;border-right-width:0;border-left-color:transparent;border-right-color:transparent}.ui-triangle-container-top{height:10;top:0;margin-top:-10}.ui-triangle-container-bottom{height:10;bottom:0;margin-bottom:-10}.ui-triangle-container-left{width:10}.ui-triangle-container-right{width:10}.ui-virtualgrid{overflow:hidden;position:absolute}.ui-virtualgrid-wrapblock{position:absolute;left:0}.ui-virtualgrid-wrapblock-x{float:left;overflow:hidden}.ui-virtualgrid-wrapblock-y{float:left;overflow:hidden}.ui-scrollbar-thumb-x{width:1.5rem!important}.ui-scrollbar-thumb-y{height:1.5rem!important}.ui-virtualgrid-overflow-indicator-x-top{position:absolute;display:block;left:0;top:0;width:56%;height:100%;opacity:0;background-repeat:no-repeat;background-size:100% 100%;background-image:url(images/00_grid_overscrolling_left.png);pointer-events:none}.ui-virtualgrid-overflow-indicator-x-bottom{position:absolute;display:block;right:0;bottom:0;width:56%;height:100%;opacity:0;background-repeat:no-repeat;background-size:100% 100%;background-image:url(images/00_grid_overscrolling_right.png);pointer-events:none}.ui-virtualgrid-overflow-indicator-y-top{position:absolute;display:block;top:0;width:100%;height:32%;opacity:0;background-repeat:no-repeat;background-size:100% 100%;background-image:url(images/00_grid_overscrolling_top.png);pointer-events:none}.ui-virtualgrid-overflow-indicator-y-bottom{position:absolute;display:block;bottom:0;width:100%;height:32%;opacity:0;background-repeat:no-repeat;background-size:100% 100%;background-image:url(images/00_grid_overscrolling_bottom.png);pointer-events:none}.ui-content.ui-virtualgrid-content{padding:0}.ui-virtualgrid{margin:4px -4px 0 0}.ui-virtualgrid .ui-li-static{padding:0;border:0;width:100%}.ui-virtualgrid .grid-icon{width:26.25px;margin:0 4px 4px 0;display:block;overflow:hidden}.ui-virtualgrid .grid-icon.ui-btn-icon-top .ui-btn-inner.ui-btn-hastxt{padding-top:15.75px}.ui-virtualgrid .grid-icon.ui-btn .ui-icon{width:106px;height:106px;-webkit-mask-size:106px 106px;-moz-mask-size:106px 106px;-ms-mask-size:106px 106px;-o-mask-size:106px 106px;mask-size:106px 106px;margin-left:-53px;background-size:106px 106px}.ui-virtualgrid .grid-icon:not(.ui-focus){background-color:#1b403d}.ui-virtualgrid .grid-thumbnail{width:38px;margin:0 4px 4px 0;display:block;overflow:hidden}.ui-virtualgrid .grid-thumbnail.ui-btn .ui-btn-inner{margin:0;padding:0}.ui-virtualgrid .grid-thumbnail.ui-btn .ui-btn-inner .ui-btn-text{display:block}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-info{left:2.625px;right:2.625px;top:1px;position:absolute;color:#c8c8c8;font-size:2.75px;text-align:right;z-index:3}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic{z-index:2;width:38px;height:38px;overflow:hidden;background-color:#1a465f;position:relative}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic img{width:25px;height:25px;position:absolute;top:19px;left:19px;margin:-12.5px}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic-full{width:38px;height:38px;overflow:hidden;position:relative;z-index:2;box-sizing:border-box}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic-full img{width:38px;height:38px;position:absolute;top:19px;left:19px;margin:-19px}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents{background:#21240d;padding:1.875px 2.5px;font-size:6.5px;overflow:hidden;text-overflow:ellipsis;color:#d3d3d3;z-index:2}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents .grid-thumbnail-content{overflow:hidden;text-overflow:ellipsis;height:3.875px;line-height:6.5px;min-height:6.5px;display:block}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents .grid-thumbnail-subtext{overflow:hidden;text-overflow:ellipsis;color:gray;font-size:2.75px;margin-top:-.75px;display:block}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic{border:solid #458fff;border-top-width:1px;border-left-width:1px;border-right-width:1px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic img{top:18px;left:18px;margin:-12.5px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic-full{border:solid #458fff;border-top-width:1px;border-left-width:1px;border-right-width:1px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic-full img{top:18px;left:18px;margin:-19px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents{background:#458fff}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents .grid-thumbnail-content,.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents .grid-thumbnail-subtext{color:#fff}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-selected .ui-btn-inner{border:solid #ffa955 1.25px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-selected .ui-btn-text{margin:-1.25px}.ui-mobile-viewport-transitioning,.ui-mobile-viewport-transitioning .ui-page{width:100%;height:100%;overflow:hidden}.in{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-duration:350ms;animation-duration:350ms}.out{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-duration:225ms;animation-duration:225ms}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes fadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadeout{from{opacity:1}to{opacity:0}}@keyframes fadeout{from{opacity:1}to{opacity:0}}.fade.out{opacity:0;-webkit-animation-duration:125ms;animation-duration:125ms;-webkit-animation-name:fadeout;animation-name:fadeout}.fade.in{opacity:1;-webkit-animation-duration:225ms;animation-duration:225ms;-webkit-animation-name:fadein;animation-name:fadein}.viewport-flip{position:absolute;-webkit-perspective:1000;-ms-perspective:1000;-o-perspective:1000;perspective:1000}.flip{backface-visiblity:hidden;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.flip.out{-webkit-transform:rotateY(-90 def) scale(0.9);transform:rotateY(-90 def) scale(0.9);-webkit-animation-name:flipouttoleft;animation-name:flipouttoleft;-webkit-animation-duration:175ms;animation-duration:175ms}.flip.out.ui-ctxpopup-container{border:2px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none}.flip.in{-webkit-animation-name:flipintoright;animation-name:flipintoright;-webkit-animation-duration:225ms;animation-duration:225ms}.flip.in.ui-ctxpopup-container{border:2px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none}.ui-popup.flip.out,.flip.out.reverse{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9);-webkit-animation-name:flipouttoright;animation-name:flipouttoright}.flip.in.reverse{-webkit-animation-name:flipintoleft;animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipouttoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}}@keyframes flipouttoright{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}.flow{box-shadow:0 0 20px rgba(0,0,0,.4);-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.ui-dialog.flow{box-shadow:none}.flow.out{-webkit-animation:flowouttoleft ease 350ms;animation:flowouttoleft ease 350ms;-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}.flow.in{-webkit-animation:flowinfromright ease 350ms;animation:flowinfromright ease 350ms;-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}.ui-popup.flow.out,.flow.out.reverse{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);-webkit-animation-name:flowouttoright;animation-name:flowouttoright}.flow.in.reverse{-webkit-animation-name:flowinfromleft;animation-name:flowinfromleft}@-webkit-keyframes flowouttoleft{0%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}60%,70%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}}@keyframes flowouttoleft{0%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}60%,70%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}}@-webkit-keyframes flowouttoright{0%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}60%,70%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(100%,0,0) scale(0.7);transform:translate3d(100%,0,0) scale(0.7)}}@keyframes flowouttoright{0%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}60%,70%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(100%,0,0) scale(0.7);transform:translate3d(100%,0,0) scale(0.7)}}@-webkit-keyframes flowinfromleft{0%{-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}30%,40%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}}@keyframes flowinfromleft{0%{-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}30%,40%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}}@-webkit-keyframes flowinfromright{0%{-webkit-transform:translate3d(100%,0,0) scale(0.7);transform:translate3d(100%,0,0) scale(0.7)}30%,40%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}}@keyframes flowinfromright{0%{-webkit-transform:translate3d(100%,0,0) scale(0.7);transform:translate3d(100%,0,0) scale(0.7)}30%,40%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}}.pop{-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.pop.in{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1;-webkit-animation:popin 350ms;animation:popin 350ms}.pop.in.ui-ctxpopup-container{border:2px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none}.pop.out{-webkit-animation:fadeout 100ms;animation:fadeout 100ms}.pop.out.ui-ctxpopup-container{border:2px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none}.pop.in.reverse{-webkit-animation-name:fadein;animation-name:fadein}.ui-popup.pop.out,.pop.out.reverse{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);-webkit-animation-name:popout;animation-name:popout}@-webkit-keyframes popin{from{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);opacity:0}to{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@keyframes popin{from{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);opacity:0}to{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes popout{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);opacity:0}}@keyframes popout{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);opacity:0}}.slide.out,.slide.in{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-duration:350ms;animation-duration:350ms}.slide.out{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);-webkit-animation-name:slideouttoleft;animation-name:slideouttoleft}.slide.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation-name:slideinfromright;animation-name:slideinfromright}.ui-popup.slide.out,.slide.out.reverse{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);-webkit-animation-name:slideouttoright;animation-name:slideouttoright}.slide.in.reverse{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation-name:slideinfromleft;animation-name:slideinfromleft}@-webkit-keyframes slideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideinfromleft{from{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideinfromleft{from{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@-webkit-keyframes slideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slidedown.out{-webkit-animation:fadeout 100ms;animation:fadeout 100ms}.slidedown.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:slideinfromtop 250ms;animation:slideinfromtop 250ms}.slidedown.in.reverse{-webkit-animation:fade 150ms;animation:fade 150ms}.ui-popup.slidedown.out,.slidedown.out.reverse{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);-webkit-animation:slideouttotop 200ms;animation:slideouttotop 200ms}@-webkit-keyframes slideinfromtop{from{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideinfromtop{from{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideouttotop{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideouttotop{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideupfade.out{-webkit-animation:fadeout 100ms;animation:fadeout 100ms}.slideupfade.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:slideupfadeinfrombottom 250ms;animation:slideupfadeinfrombottom 250ms}.slideupfade.in.reverse{-webkit-animation:fadein 150ms;animation:fadein 150ms}.ui-popup.slideupfade.out,.slideupfade.out.reverse{-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0);-webkit-animation:slideupfadeouttobottom 200ms;animation:slideupfadeouttobottom 200ms}@-webkit-keyframes slideupfadeinfrombottom{from{opacity:0;-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideupfadeinfrombottom{from{opacity:0;-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideupfadeouttobottom{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0)}}@keyframes slideupfadeouttobottom{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0)}}.slidedownfade.out{-webkit-animation:fadeout 100ms;animation:fadeout 100ms}.slidedownfade.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:slidedownfadeinfromtop 250ms;animation:slidedownfadeinfromtop 250ms}.slidedownfade.in.reverse{-webkit-animation:fadein 150ms;animation:fadein 150ms}.ui-popup.slidedownfade.out,.slidedownfade.out.reverse{-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0);-webkit-animation:slidedownfadeouttotop 200ms;animation:slidedownfadeouttotop 200ms}@-webkit-keyframes slidedownfadeinfromtop{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0)}}@keyframes slidedownfadeinfromtop{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0)}}@-webkit-keyframes slidedownfadeouttotop{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0)}}@keyframes slidedownfadeouttotop{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0)}}.slidefade.out{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);-webkit-animation:slideouttoleft 225ms;animation:slideouttoleft 225ms}.slidefade.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:fadein 200ms;animation:fadein 200ms}.ui-popup.slidefade.out,.slidefade.out.reverse{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);-webkit-animation:slideouttoright 200ms;animation:slideouttoright 200ms}.slidefade.in.reverse{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:fadein 200ms;animation:fadein 200ms}.viewport-turn{-webkit-perspective:1000;-ms-perspective:1000;-o-perspective:1000;perspective:1000;position:absolute}.turn{backface-visiblity:hidden;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.turn.out{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9);-webkit-animation:flipouttoleft 125ms;animation:flipouttoleft 125ms}.turn.in{-webkit-animation:flipintoright 250ms;animation:flipintoright 250ms}.ui-popup.turn.out,.turn.out.reverse{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9);-webkit-animation-name:flipouttoright;animation-name:flipouttoright}.turn.in.reverse{-webkit-animation-name:flipintoleft;animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}}@keyframes flipouttoleft{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}}@keyframes flipouttoright{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}.depth{-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.depth.out{opacity:0;-webkit-animation:depthout 250ms ease;animation:depthout 250ms ease}.depth.in{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1;-webkit-animation:depthin 350ms ease;animation:depthin 350ms ease}.depth.in.reverse{-webkit-animation-name:depthinreverse;animation-name:depthinreverse}.ui-popup.depth.out,.depth.out.reverse{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);-webkit-animation-name:depthoutreverse;animation-name:depthoutreverse}@-webkit-keyframes depthout{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}}@keyframes depthout{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}}@-webkit-keyframes depthin{0%{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}30%{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@keyframes depthin{0%{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}30%{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes depthinreverse{0%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}30%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@keyframes depthinreverse{0%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}30%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes depthoutreverse{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}}@keyframes depthoutreverse{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}}.ui-mobile-viewport-transitioning,.ui-mobile-viewport-transitioning .ui-page{width:100%;height:100%;overflow:hidden}.ui-page.slide.out,.ui-page.slide.in{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-duration:400ms;animation-duration:400ms}.ui-page.slide.out{-webkit-animation-name:pageslideouttoleft;animation-name:pageslideouttoleft}.ui-page.slide.in{-webkit-animation-name:pageslideinfromright;animation-name:pageslideinfromright}.ui-page.slide.out.reverse{-webkit-animation-name:pageslideouttoright;animation-name:pageslideouttoright;z-index:2000}.ui-page.slide.in.reverse{-webkit-animation-name:pageslideinfromleft;animation-name:pageslideinfromleft}.ui-page.slide.in.reverse::after,.ui-page.slide.out:not(.reverse)::after{content:"";background-image:url(images/page/core_theme_bg_01.png);background-repeat:no-repeat;background-size:100% 100%;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2000;opacity:0}.ui-page.slide.in.reverse::after{-webkit-animation:pagebgslideinreverse 400ms ease-out;animation:pagebgslideinreverse 400ms ease-out}.ui-page.slide.out:not(.reverse)::after{-webkit-animation:pagebgslideout 400ms ease-out;animation:pagebgslideout 400ms ease-out}@-webkit-keyframes pageslideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-25%,0,0);-ms-transform:translate3d(-25%,0,0);transform:translate3d(-25%,0,0)}}@keyframes pageslideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-25%,0,0);-ms-transform:translate3d(-25%,0,0);transform:translate3d(-25%,0,0)}}@-webkit-keyframes pageslideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes pageslideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes pageslideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes pageslideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@-webkit-keyframes pageslideinfromleft{from{-webkit-transform:translate3d(-25%,0,0);-ms-transform:translate3d(-25%,0,0);transform:translate3d(-25%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes pageslideinfromleft{from{-webkit-transform:translate3d(-25%,0,0);-ms-transform:translate3d(-25%,0,0);transform:translate3d(-25%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes pagebgslideinreverse{from{opacity:.5}to{opacity:0}}@keyframes pagebgslideinreverse{from{opacity:.5}to{opacity:0}}@-webkit-keyframes pagebgslideout{from{opacity:0}to{opacity:.5}}@keyframes pagebgslideout{from{opacity:0}to{opacity:.5}}.ui-page.slideup.out{-webkit-animation-name:fadeout;animation-name:fadeout;-webkit-animation-duration:250ms;animation-duration:250ms}.ui-page.slideup.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation-name:pageslideinfrombottom;animation-name:pageslideinfrombottom;-webkit-animation-duration:200ms;animation-duration:200ms}.ui-page.slideup.in.reverse{-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-duration:250ms;animation-duration:250ms}.ui-page.slideup.out.reverse{-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);-webkit-animation-name:pageslideouttobottom;animation-name:pageslideouttobottom;-webkit-animation-duration:200ms;animation-duration:200ms}@-webkit-keyframes pageslideinfrombottom{from{-webkit-transform:translate3d(0,100%,0)}to{-webkit-transform:translate3d(0,0,0)}}@-webkit-keyframes pageslideouttobottom{from{-webkit-transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(0,100%,0)}}ul.ui-virtual-list-container>ul.position_absolute{position:absolute}.ui-listview.ui-virtual-list-container .ui-li{position:relative}.ui-virtual-list-edge-effect{pointer-events:none;width:100%;height:0;position:absolute;top:0;left:0;box-shadow:0 0 rgba(0,0,0,0)}.ui-virtual-list-edge-effect.orientation-horizontal{height:100%;width:0}.ui-grid-a,.ui-grid-b,.ui-grid-c,.ui-grid-d{overflow:hidden}.ui-block-a,.ui-block-b,.ui-block-c,.ui-block-d,.ui-block-e{margin:0;padding:0;border:0;float:left;min-height:1px}.ui-grid-solo .ui-block-a{width:100%;float:none}.ui-grid-a .ui-block-a,.ui-grid-a .ui-block-b{width:50%}.ui-grid-a .ui-block-a{clear:left}.ui-grid-b .ui-block-a,.ui-grid-b .ui-block-b,.ui-grid-b .ui-block-c{width:33.333%}.ui-grid-b .ui-block-a{clear:left}.ui-grid-c .ui-block-a,.ui-grid-c .ui-block-b,.ui-grid-c .ui-block-c,.ui-grid-c .ui-block-d{width:25%}.ui-grid-c .ui-block-a{clear:left}.ui-grid-d .ui-block-a,.ui-grid-d .ui-block-b,.ui-grid-d .ui-block-c,.ui-grid-d .ui-block-d,.ui-grid-d .ui-block-e{width:20%}.ui-grid-d .ui-block-a{clear:left}.ui-navbar{overflow:hidden}.ui-navbar ul,.ui-navbar-expanded ul{list-style:none;padding:0;margin:0;position:relative;display:block;border:0}.ui-navbar-collapsed ul{float:left;width:75%;margin-right:-2px}.ui-navbar-collapsed .ui-navbar-toggle{float:left;width:25%}.ui-navbar .ui-navbar-truncate{position:absolute;left:-9999px;top:-9999px}.ui-navbar li .ui-btn,.ui-navbar .ui-navbar-toggle .ui-btn{display:block;text-align:center;margin:0;border-right-width:0}.ui-navbar li .ui-btn{margin-right:-1px}.ui-navbar li .ui-btn:last-child{margin-right:0}.ui-header .ui-navbar .ui-btn,.ui-footer .ui-navbar .ui-btn{border-top-width:0}.ui-navbar .ui-btn-inner{padding-left:2px;padding-right:2px}.ui-navbar-noicons .ui-btn-inner{padding-top:.8em;padding-bottom:.9em}.ui-navbar-expanded .ui-btn{margin:0;font-size:14px}.ui-navbar-expanded .ui-btn-inner{padding-left:5px;padding-right:5px}.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner{padding:45px 5px 15px;text-align:center}.ui-navbar-expanded .ui-btn-icon-top .ui-icon{top:15px}.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner{padding:15px 5px 45px;text-align:center}.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon{bottom:15px}.ui-navbar-expanded .ui-btn-inner{min-height:2.5em}.ui-navbar-expanded .ui-navbar-noicons .ui-btn-inner{padding-top:1.8em;padding-bottom:1.9em}.ui-select{display:block;position:relative}.ui-select select{position:absolute;left:-9999px;top:-9999px}.ui-select .ui-btn{overflow:hidden}.ui-select .ui-btn select{cursor:pointer;-webkit-appearance:button;left:0;top:0;width:100%;min-height:100%;height:3em;max-height:100%;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);z-index:2}.ui-select .ui-btn select.ui-select-nativeonly{opacity:1;text-indent:0}.ui-select .ui-btn-icon-right .ui-btn-inner{padding-right:45px}.ui-select .ui-btn-icon-right .ui-icon{right:15px}label.ui-select{font-size:16px;line-height:1.4;font-weight:400;margin:0 0 .3em;display:block}.ui-select .ui-btn-text,.ui-selectmenu .ui-btn-text{display:block;min-height:1em}.ui-select .ui-btn-text{text-overflow:ellipsis;overflow:hidden}.ui-selectmenu .ui-listview{margin:0}.ui-selectmenu .ui-btn.ui-li-divider{cursor:default}.ui-selectmenu-hidden{top:-9999px;left:-9999px;visibility:hidden}.ui-selectmenu-screen{position:absolute;top:0;left:0;width:100%;height:100%;z-index:99}.ui-selectmenu-list .ui-li .ui-icon{display:none}.ui-selectmenu-list .ui-li .ui-icon{display:block}.ui-li.ui-selectmenu-placeholder{display:none}.ui-selectmenu .ui-header .ui-title{margin:.6em 46px .8em}@media all and (min-width:450px){label.ui-select{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-select{width:60%;display:inline-block}}.ui-selectmenu .ui-header h1::after{content:'.';visibility:hidden}.ui-selectmenu .ui-header .ui-btn-icon_only .ui-btn-text{position:absolute;left:-9999px}.ui-selectmenu .ui-header .ui-btn-icon_only .ui-icon{margin:auto}.ui-page.ui-empty-state .ui-header{background-color:var(--background-color)}.ui-page.ui-empty-state .ui-content{position:relative;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;height:100%;background-color:var(--background-color)}.ui-page.ui-empty-state .ui-content::before{content:'';display:block;position:absolute;top:0;left:0;width:100%;height:100%;-webkit-mask-image:url(images/00_page_empty_bg.png);mask-image:url(images/00_page_empty_bg.png);-webkit-mask-size:100% auto;mask-size:100% auto;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;background-color:var(--background-color)}.ui-page.ui-empty-state .ui-content .ui-scrollview-view{padding-left:16px;padding-right:16px;text-align:center;font-size:16px;color:var(--text-color);line-height:21.5px;min-height:286px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-page.ui-empty-state .ui-content .ui-scrollview-view h1,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h2,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h3,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h4,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h5,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h6{margin:0;margin-bottom:27px;line-height:27px;font-size:20px;font-weight:lighter;color:T0222L1}@media only screen and (orientation:landscape){.ui-page.ui-empty-state .ui-content:before{-webkit-mask-image:url(images/00_page_empty_bg_h.png);mask-image:url(images/00_page_empty_bg_h.png);-webkit-mask-size:100% 100px;mask-size:100% 100px}}.ui-listview.ui-listview-empty-state-show{height:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-listview.ui-listview-empty-state-show .ui-li-empty-state{display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-listview.ui-listview-empty-state-show .ui-li-static{height:27px}.ui-listview .ui-li-empty-state{width:100%;display:none;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:relative;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;-webkit-flex:1;-ms-flex:1;flex:1;box-sizing:border-box;padding:0 0 42px}.ui-empty-state-content{pointer-events:none;padding-left:16px;padding-right:16px;text-align:center;font-size:16px;color:T0222L4;line-height:21.5px;height:286px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-empty-state-content h1,.ui-empty-state-content h2,.ui-empty-state-content h3,.ui-empty-state-content h4,.ui-empty-state-content h5,.ui-empty-state-content h6{margin:0;margin-bottom:27px;line-height:27px;font-size:20px;font-weight:lighter;color:T0222L3}.ui-page-floatingactions .ui-listview .ui-li-empty-state{padding:0 0 94px}input[type=search]::-webkit-search-decoration,input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}input[type=search][disabled]{background-color:transparent}.ui-search-input{font-size:20px;overflow:hidden;background-color:transparent;text-shadow:0 0 0 var(--text-color);color:var(--text-input-inactive);-webkit-text-fill-color:transparent}.ui-search-input:focus{text-shadow:0 0 0 var(--text-color);border-color:var(--text-input-underline-active)}.ui-search-input.ui-state-disabled{text-shadow:0 0 0 var(--text-input-disabled);border-bottom:2px solid var(--text-input-disabled)}.ui-search-input.ui-state-disabled::-webkit-input-placeholder{color:var(--text-input-label-inactive);text-shadow:none;-webkit-text-fill-color:initial}.ui-header-searchbar{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding:0 8.5px 0 5px;box-sizing:border-box;overflow:initial}.ui-header-searchbar>.ui-search-input,.ui-header-searchbar>input{border:0;outline:0;overflow:hidden;border-bottom:1px solid;border-bottom-color:var(--text-input-underline-active);font-size:20px;color:var(--primary-color);background-color:transparent;-webkit-text-fill-color:transparent;height:40px;text-shadow:0 0 0 var(--text-color);box-sizing:border-box;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:2px 5px 0;margin-right:7.5px}.ui-header-searchbar>.ui-search-input.ui-text-input-clear-active:focus,.ui-header-searchbar>input.ui-text-input-clear-active:focus,.ui-header-searchbar>.ui-search-input.ui-text-input-clear-active:active,.ui-header-searchbar>input.ui-text-input-clear-active:active{text-shadow:0 0 0 var(--text-color);padding:2px 41px 0 5px}.ui-header-searchbar>.ui-search-input[disabled],.ui-header-searchbar>input[disabled],.ui-header-searchbar>.ui-search-input.ui-state-disabled,.ui-header-searchbar>input.ui-state-disabled{text-shadow:0 0 0 var(--text-input-disabled)}.ui-header-searchbar>.ui-search-input[disabled]::-webkit-input-placeholder,.ui-header-searchbar>input[disabled]::-webkit-input-placeholder,.ui-header-searchbar>.ui-search-input.ui-state-disabled::-webkit-input-placeholder,.ui-header-searchbar>input.ui-state-disabled::-webkit-input-placeholder{text-shadow:var(--text-input-label-inactive)}.ui-header-searchbar>.ui-search-input::-webkit-input-placeholder,.ui-header-searchbar>input::-webkit-input-placeholder{text-shadow:0 0 0 var(--primary-color)}.ui-header-searchbar>.ui-search-input~.ui-text-input-clear.ui-btn.ui-btn-icon,.ui-header-searchbar>input~.ui-text-input-clear.ui-btn.ui-btn-icon{top:7.5px;position:absolute;right:8.5px;margin:0}.ui-header-searchbar>.ui-search-input~.ui-text-input-clear.ui-btn.ui-btn-icon::after,.ui-header-searchbar>input~.ui-text-input-clear.ui-btn.ui-btn-icon::after{background-color:var(--text-color)}.ui-header-searchbar>.ui-search-input+.ui-btn.ui-btn-icon+.ui-text-input-clear.ui-btn.ui-btn-icon,.ui-header-searchbar>input+.ui-btn.ui-btn-icon+.ui-text-input-clear.ui-btn.ui-btn-icon{right:49.5px}.ui-header-searchbar>.ui-search-input~.ui-btn-nobg::before,.ui-header-searchbar>input~.ui-btn-nobg::before{background-color:var(--ripple-color)}.ui-header-searchbar .ui-header-btn-right~.ui-text-input-clear.ui-btn.ui-btn-icon{right:49.5px}.ui-header-searchbar>.ui-btn:not(.ui-btn-nobg),.ui-header-searchbar .ui-header-btn-left.btn-icon-back,.ui-header-searchbar .ui-header-btn-icon.ui-header-btn-right{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;position:relative}.ui-header-searchbar>.ui-btn.ui-btn-icon:not(.ui-text-input-clear):not(.btn-icon-back)::after{-webkit-mask-size:25px 25px;mask-size:25px 25px}.ui-header-searchbar>.ui-header-btn-right{-webkit-order:2;-ms-flex-order:2;order:2;position:relative}.ui-handler{position:fixed;display:-webkit-flex;display:-ms-flexbox;display:flex;overflow:hidden;opacity:0;transition:opacity 400ms ease-out;height:100%;top:0;right:0}.ui-handler .ui-handler-track{-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;position:relative;width:100%;height:100%;display:block}.ui-handler .ui-handler-track .ui-handler-handle{-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;position:absolute;display:block;background-color:transparent}.ui-handler .ui-handler-track .ui-handler-handle .ui-handler-expander{width:100%;height:100%;float:right;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;background-color:var(--primary-color);border-radius:2.5px;transition-property:width border-width border-radius;transition-duration:100ms}.ui-handler .ui-handler-track .ui-handler-handle.ui-active .ui-handler-thumb:before{content:"";position:absolute;top:0;left:0;width:16px;height:16px;-webkit-mask-size:100%;-moz-mask-size:100%;-ms-mask-size:100%;-o-mask-size:100%;mask-size:100%;background-color:var(--icon-color)}.ui-handler .ui-handler-track .ui-handler-handle.ui-active .ui-handler-thumb:after{content:"";position:absolute;top:0;left:0;width:16px;height:16px;-webkit-mask-size:100%;-moz-mask-size:100%;-ms-mask-size:100%;-o-mask-size:100%;mask-size:100%;background-color:var(--icon-color)}.ui-handler.ui-handler-direction-x{right:5px;bottom:0;left:5px;height:19px;top:auto}.ui-handler.ui-handler-direction-x .ui-handler-handle{min-width:22px;height:16px;margin-bottom:3px;top:auto;bottom:0;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:flex-end;-moz-align-items:flex-end;-ms-align-items:flex-end;-o-align-items:flex-end;-ms-flex-align:end;align-items:flex-end}.ui-handler.ui-handler-direction-x .ui-handler-handle .ui-handler-expander{height:5px;width:100%;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-handler.ui-handler-direction-x .ui-handler-track .ui-handler-handle.ui-active{min-width:41px;margin-bottom:3px;border-radius:8px;-webkit-flex-direction:row;-moz-flex-direction:row;-ms-flex-direction:row;-o-flex-direction:row;flex-direction:row}.ui-handler.ui-handler-direction-x .ui-handler-track .ui-handler-handle.ui-active .ui-handler-expander{height:16px;border-radius:8px}.ui-handler.ui-handler-direction-x .ui-handler-thumb:before{-webkit-mask-image:url(images/core_index_scroll_handler_h_01.png);mask-image:url(images/core_index_scroll_handler_h_01.png)}.ui-handler.ui-handler-direction-x .ui-handler-thumb:after{-webkit-mask-image:url(images/core_index_scroll_handler_h_02.png);mask-image:url(images/core_index_scroll_handler_h_02.png)}.ui-handler.ui-handler-direction-y{top:0;right:0;bottom:0;width:19px;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}.ui-handler.ui-handler-direction-y:before{content:"";width:100%;height:55px;background-color:transparent}.ui-handler.ui-handler-direction-y .ui-handler-handle{width:16px;margin-right:3px;min-height:22px;left:auto;right:0}.ui-handler.ui-handler-direction-y .ui-handler-handle .ui-handler-expander{width:5px;height:100%}.ui-handler.ui-handler-direction-y .ui-handler-track{margin:5px 0;background-color:transparent;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}.ui-handler.ui-handler-direction-y .ui-handler-track .ui-handler-handle.ui-active{width:16px;margin-right:3px;min-height:41px;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}.ui-handler.ui-handler-direction-y .ui-handler-track .ui-handler-handle.ui-active .ui-handler-expander{border-radius:8px;width:16px}.ui-handler.ui-handler-direction-y .ui-handler-thumb:before{-webkit-mask-image:url(images/core_index_scroll_handler_v_01.png);mask-image:url(images/core_index_scroll_handler_v_01.png)}.ui-handler.ui-handler-direction-y .ui-handler-thumb:after{-webkit-mask-image:url(images/core_index_scroll_handler_v_02.png);mask-image:url(images/core_index_scroll_handler_v_02.png)}.ui-handler.disabled{display:none}.ui-handler .ui-handler-thumb{width:16px;height:16px;position:relative}.ui-handler-visible{opacity:1}.scrollbar-disabled{overflow:hidden!important}.scrollbar-disabled .ui-scrollview-clip{width:105%}.scrollbar-disabled .ui-scrollview-clip[data-direction="x"]{width:100%;height:105%}.ui-container{white-space:nowrap;padding-bottom:10px}.ui-container>*{scroll-snap-align:center}.ui-container .ui-container-item{display:inline-block;margin-left:3px;margin-right:3px;width:188px}.ui-container .ui-container-item:last-child{padding-right:20px}.ui-container.ui-container-middle .ui-favorite.ui-btn{width:103px}.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content{width:103px}.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content img{width:100px;height:100px}.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content .ui-title,.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content .ui-subtitle{font-family:Roboto-Medium;width:100%;text-align:left;text-overflow:ellipsis;color:#7b7b7b}.ui-drawer{position:absolute;background-color:var(--background-color);z-index:1201;box-sizing:border-box;overflow-x:hidden;overflow-y:scroll}.ui-drawer-header{height:56px;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-drawer-title{font-size:19px;color:var(--appbar-main-text-color);-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;margin-left:20px}.ui-drawer .ui-listview{margin:0;position:absolute;z-index:2000;width:100%;height:100%}.ui-drawer .ui-listview .ui-drawer-sub-list>.ui-btn-inner .ui-btn-text .ui-link-inherit{padding-left:13px}.ui-drawer-overlay{position:absolute;background-color:var(--overlay);z-index:1200}.ui-header .ui-btn.ui-drawer-button.ui-btn-icon-only{position:absolute;top:0;left:0;width:27px;height:36px}.ui-header .ui-btn.ui-drawer-button.ui-btn-icon-only::after{width:27px;height:36px;-webkit-mask-size:100%;mask-size:100%;margin-top:0;top:0;left:0}.ui-dropdownmenu-overlay{opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1200}.ui-dropdownmenu{box-sizing:border-box;width:100%;display:block;position:relative}.ui-dropdownmenu:focus{outline:0}.ui-dropdownmenu:active{outline:0}.ui-dropdownmenu:active .ui-dropdownmenu-placeholder{background-color:W021L1P}.ui-dropdownmenu::before{content:"";opacity:0;width:90%;height:26px;background-color:var(--ripple-color);position:absolute;top:17px;left:5%;transition-property:width,height,top,left;transition-duration:.2s;transition-timing-function:ease}.ui-dropdownmenu:active::before{content:"";opacity:1;width:94%;height:40px;background-color:var(--ripple-color);position:absolute;top:10px;left:3%}.ui-dropdownmenu .ui-dropdownmenu-placeholder{box-sizing:border-box;text-align:left;width:100%;display:inline-block;vertical-align:middle;position:relative;height:100%;line-height:60px;white-space:nowrap;padding:0 26px 0 16px;overflow:hidden;text-overflow:ellipsis;font-size:17px;text-indent:5px;background-color:W021L1}.ui-dropdownmenu .ui-dropdownmenu-placeholder::after{content:"";position:absolute;width:calc(100% - 32px);height:1px;bottom:9px;right:16px;background-color:F057}.ui-dropdownmenu select{width:100%;display:none}.ui-dropdownmenu.ui-focus{background-color:var(--ripple-color)}.ui-dropdownmenu-inline{width:auto;display:inline-block}.ui-dropdownmenu-disabled{opacity:1}.ui-dropdownmenu-disabled .ui-dropdownmenu-placeholder{color:var(--dropdown-menu-options-color-dim)}.ui-dropdownmenu-force-display{display:block!important}.ui-dropdownmenu-native select{display:block;top:0;left:0;position:absolute;height:100%;outline:0;opacity:0;border:0;margin:0}.ui-dropdownmenu-overlay-hidden{display:none}@-webkit-keyframes open-to-bottom{from{opacity:.5;-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes open-to-top{from{opacity:.5;-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes close-to-bottom{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-webkit-keyframes close-to-top{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.ui-dropdownmenu-options-wrapper{position:absolute;visibility:hidden;top:-5000px;overflow:hidden;z-index:1201;min-width:168px;max-width:100vw;padding:3px}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-vertical-margins{margin-top:3px;margin-bottom:3px}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-active{visibility:visible;overflow-y:auto}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-opening.ui-dropdownmenu-options-top .ui-dropdownmenu-options{-webkit-animation:open-to-top 300ms;animation:open-to-top 300ms}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-opening.ui-dropdownmenu-options-bottom .ui-dropdownmenu-options{-webkit-animation:open-to-bottom 300ms;animation:open-to-bottom 300ms}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-closing.ui-dropdownmenu-options-top .ui-dropdownmenu-options{-webkit-animation:close-to-bottom 300ms;animation:close-to-bottom 300ms}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-closing.ui-dropdownmenu-options-bottom .ui-dropdownmenu-options{-webkit-animation:close-to-top 300ms;animation:close-to-top 300ms}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options{box-sizing:border-box;list-style:none;padding:0;margin:0;max-height:calc(100vh - 6px);overflow-y:auto;background-color:var(--dropdown-menu-options-background);border-radius:26px;box-shadow:0 0 3px 0 rgba(0,0,0,.35);border:var(--dropdown-menu-options-border)}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options:focus{outline:0}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-disabled{color:var(--dropdown-menu-options-color-dim)}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-selected{color:var(--primary-dark-color);font-family:Roboto-Medium}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-selected::after{width:20px;height:20px;margin-left:16px;margin-right:24px;content:'';position:absolute;-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg);-webkit-mask-size:100%,0;mask-size:100%,0;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;background-color:var(--primary-dark-color)}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li{padding:15px 60px 15px 24px;font-size:17px;font-family:Roboto-Regular;display:block;position:relative;overflow:hidden;text-overflow:ellipsis;color:var(--dropdown-menu-options-color)}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li.ui-dropdown-two-lines{max-height:2em;line-height:1.4em}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:not(.ui-dropdown-two-lines){white-space:nowrap;height:20px}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:focus,.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:active{outline:0}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li::before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background-color:var(--ripple-color);opacity:0}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:active::before{opacity:1}.ui-dropdownmenu-active::-webkit-scrollbar{display:none}.ui-listview li.ui-li-static.ui-li-has-dropdownmenu{padding:0}.ui-listview li.ui-li-static.ui-li-has-dropdownmenu .ui-dropdownmenu-placeholder{line-height:60px}.ui-li-static.ui-li-has-dropdownmenu{height:60px}.ui-appbar .ui-dropdownmenu-placeholder{line-height:56px}.ui-appbar-expanded .ui-dropdownmenu-placeholder{line-height:59px}.ui-panel-changer{position:relative;display:block;width:100%;left:0}.ui-panel{position:absolute;height:100%;width:100%}.ui-panel.ui-panel-active{display:block}.ui-panel.slide-in,.ui-panel.slide-out,.ui-panel.slide-reverse-out,.ui-panel.slide-reverse-in{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-duration:400ms;animation-duration:400ms}.ui-panel.pre-in{z-index:100}.ui-panel.slide-out{-webkit-animation-name:panelslideouttoleft;animation-name:panelslideouttoleft}.ui-panel.slide-in{-webkit-animation-name:panelslideinfromright;animation-name:panelslideinfromright}.ui-panel.slide-reverse-out{-webkit-animation-name:panelslideouttoright;animation-name:panelslideouttoright}.ui-panel.slide-reverse-in{-webkit-animation-name:panelslideinfromleft;animation-name:panelslideinfromleft}.ui-panel .ui-content{height:100%}@-webkit-keyframes panelslideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes panelslideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@-webkit-keyframes panelslideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes panelslideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes panelslideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes panelslideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@-webkit-keyframes panelslideinfromleft{from{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes panelslideinfromleft{from{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.ui-navigation{-webkit-order:2;-moz-order:2;-ms-order:2;-o-order:2;-ms-flex-order:2;order:2;height:35px;box-sizing:border-box;background-color:var(--background-color);border-top:1px solid var(--color-white);white-space:nowrap;overflow-x:scroll;overflow-y:hidden}.ui-navigation::-webkit-scrollbar{display:none}.ui-navigation .ui-navigation-container{margin:0;padding:0;display:inline-block;list-style-type:none}.ui-navigation .ui-navigation-container .ui-navigation-item{position:relative;height:34px;line-height:34px;vertical-align:top;overflow:hidden;display:inline-block;color:var(--text-color);font-size:16px;background-color:transparent}.ui-navigation .ui-navigation-container .ui-navigation-item:first-child{margin-left:9px}.ui-navigation .ui-navigation-container .ui-navigation-item:first-child::before{content:none}.ui-navigation .ui-navigation-container .ui-navigation-item .ui-arrow{float:left;height:34px;width:30px;color:var(--text-color);background-color:var(--color-white);-webkit-mask-image:url(images/core_navigation_bar_icon_arrow.png);-webkit-mask-size:100% 100%;margin:0 -9px 0;opacity:.6}.ui-navigation .ui-navigation-container .ui-navigation-item .ui-text{display:block;position:relative;float:left;height:21.5px;color:var(--text-color);padding:3px 7px 4.5px;line-height:21.5px;margin-top:2.5px;text-decoration:none;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;opacity:.6}.ui-navigation .ui-navigation-container .ui-navigation-item .ui-text.ui-focus{background-color:rgba(50,150,166,.4);outline:0}.ui-navigation .ui-navigation-container .ui-navigation-item:last-child{margin-right:9px}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-active-animation .ui-arrow{-webkit-animation:navigation_active_show_animation_arrow linear 133ms;animation:navigation_active_show_animation_arrow linear 133ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-active-animation .ui-text{-webkit-animation:navigation_active_show_animation_text linear 166ms;animation:navigation_active_show_animation_text linear 166ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back .ui-arrow{-webkit-animation:none;animation:none}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back .ui-text{-webkit-animation:navigation_active_back_animation_text linear 184ms;animation:navigation_active_back_animation_text linear 184ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-hide .ui-arrow{-webkit-animation:navigation_active_hide_animation_text linear 150ms;animation:navigation_active_hide_animation_text linear 150ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-hide .ui-text{-webkit-animation:navigation_active_hide_animation_text linear 184ms;animation:navigation_active_hide_animation_text linear 184ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigation-active .ui-arrow{opacity:.6}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigation-active .ui-text{color:var(--ripple-color);opacity:1}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back-hide .ui-arrow{-webkit-animation:none;animation:none}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back-hide .ui-text{-webkit-animation:navigation_active_back_hide_animation_text linear 184ms;animation:navigation_active_back_hide_animation_text linear 184ms;opacity:1}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-btn-active .ui-text::before{content:"";position:absolute;width:100%;height:100%;left:50%;top:50%;background-color:var(--ripple-color);opacity:0;color:var(--ripple-color);-webkit-animation:navigation_press_animation linear 500ms;animation:navigation_press_animation linear 500ms}@-webkit-keyframes navigation_active_show_animation_text{0%{opacity:0}100%{opacity:1}}@keyframes navigation_active_show_animation_text{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes navigation_active_back_animation_text{0%{opacity:.6}100%{opacity:1}}@keyframes navigation_active_back_animation_text{0%{opacity:.6}100%{opacity:1}}@-webkit-keyframes navigation_active_back_hide_animation_text{0%{opacity:1}100%{opacity:.6}}@keyframes navigation_active_back_hide_animation_text{0%{opacity:1}100%{opacity:.6}}@-webkit-keyframes navigation_active_show_animation_arrow{0%{opacity:0}20%{opacity:0}100%{opacity:.6}}@keyframes navigation_active_show_animation_arrow{0%{opacity:0}20%{opacity:0}100%{opacity:.6}}@-webkit-keyframes navigation_active_hide_animation_text{0%{opacity:1}100%{opacity:0}}@keyframes navigation_active_hide_animation_text{0%{opacity:1}100%{opacity:0}}@-webkit-keyframes navigation_press_animation{0%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(0.7);-ms-transform:translate(-50%,-50%) scale(0.7);transform:translate(-50%,-50%) scale(0.7)}5%{opacity:.3}100%{opacity:.3;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@keyframes navigation_press_animation{0%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(0.7);-ms-transform:translate(-50%,-50%) scale(0.7);transform:translate(-50%,-50%) scale(0.7)}5%{opacity:.3}100%{opacity:.3;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@-webkit-keyframes navigation_pressup_animation{0%{opacity:.3}100%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@keyframes navigation_pressup_animation{0%{opacity:.3}100%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}.ui-tabs{position:relative;height:100%;overflow:hidden;border-bottom-left-radius:26px;border-bottom-right-radius:26px}.ui-tabs .ui-listview{overflow:hidden;min-height:100%;min-width:100%}.ui-section-changer{height:100%;position:relative;overflow:hidden;display:block}.ui-section-changer section{overflow:auto}.ui-indexscrollbar{display:block;position:absolute;right:0;top:0;width:20px;height:100%;padding-left:1px;background-color:var(--control-background);z-index:1000;overflow:visible;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;cursor:pointer;box-sizing:border-box}.ui-indexscrollbar::before{width:20px;display:block;position:absolute;right:20px;height:100%;content:" ";background-color:transparent}.ui-indexscrollbar ul{list-style-type:none;margin:0;position:absolute;width:100%;height:100%;left:0;visibility:visible;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;-webkit-align-items:stretch;-moz-align-items:stretch;-ms-align-items:stretch;-o-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center;padding:0;box-sizing:border-box}.ui-indexscrollbar ul li{cursor:pointer;color:var(--text-color);display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;text-align:center;font-size:12px;font-weight:700;border-bottom:1px solid var(--primary-color);border-left:1px solid var(--border-surface);-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;max-height:20px;min-height:20px}.ui-indexscrollbar ul li a{text-decoration:none;width:18px;height:19px;color:inherit;border:0;outline:0;box-sizing:border-box;margin:0;padding:0}.ui-indexscrollbar ul li a:focus{background-color:var(--ripple-color)}.ui-indexscrollbar ul li.ui-state-selected{border-left:2px solid var(--primary-color);position:relative;width:18px}.ui-indexscrollbar ul li.ui-state-selected::before{content:"";position:absolute;height:100%;width:17px;left:-1px;top:-1px;border:1px solid var(--border-surface);border-left:0}.ui-indexscrollbar ul::before,.ui-indexscrollbar ul::after{content:"";width:20px;border-left:1px solid var(--border-surface);display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;pointer-events:none;-webkit-flex-basis:auto;-ms-flex-preferred-size:auto;flex-basis:auto}.ui-indexscrollbar ul.ui-indexscrollbar-supplementary{position:relative;height:auto;top:0;right:-20px;width:100%}.ui-indexscrollbar .ui-indexscrollbar-margin{width:20px;position:absolute;bottom:0;left:0;border-left:1px solid var(--border-surface)}.ui-indexscrollbar+.ui-listview li{padding-right:20px}.ui-indexscrollbar ul li:first-child{padding-top:21px;position:relative}.ui-indexscrollbar ul li:first-child::before{content:"";height:20px;width:20px;position:absolute;top:0;left:0;background-color:var(--text-color);-webkit-mask-image:url(../default/images/controls/core_floating_icon_search.png);mask-image:url(../default/images/controls/core_floating_icon_search.png);-webkit-mask-size:80%;mask-size:80%;-webkit-mask-position:center center;mask-position:center center}.ui-indexscrollbar ul li:first-child::after{content:"";height:1px;width:20px;position:absolute;top:20px;left:0;background-color:var(--primary-color)}.ui-indexscrollbar ul li:last-child{border-bottom-color:transparent}.ui-indexscrollbar-indicator{position:fixed;top:0;left:0;z-index:999;display:none}.ui-indexscrollbar-indicator>span{width:84px;line-height:84px;position:absolute;display:block;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);font-size:56px;border-radius:50%;text-align:center;box-sizing:border-box;background-color:var(--control-background);color:var(--text-color)}.ui-icon-add::after{-webkit-mask-image:url(images/2_Buttons/tw_ic_ab_add_mtrl.svg);mask-image:url(images/2_Buttons/tw_ic_ab_add_mtrl.svg)}.ui-icon-delete::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_bb_delete_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_bb_delete_mtrl.svg)}.ui-icon-cancel::after{-webkit-mask-image:url(images/controls/core_button_cancel.png);mask-image:url(images/controls/core_button_cancel.png)}.ui-icon-reorder::after{-webkit-mask-image:url(images/3_Controllers/tw_list_icon_reorder.svg);mask-image:url(images/3_Controllers/tw_list_icon_reorder.svg)}.ui-icon-pause::after{-webkit-mask-image:url(images/controls/00_button_pause.png);mask-image:url(images/controls/00_button_pause.png)}.ui-icon-share::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_bb_share_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_bb_share_mtrl.svg)}.ui-icon-check::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg)}.ui-icon-move::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_bb_move_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_bb_move_mtrl.svg)}.ui-icon-plus::after{-webkit-mask-image:url(images/3_Controllers/tw_list_icon_add_mtrl.svg);mask-image:url(images/3_Controllers/tw_list_icon_add_mtrl.svg)}.ui-icon-minus::after{-webkit-mask-image:url(images/3_Controllers/tw_list_icon_delete_mtrl.svg);mask-image:url(images/3_Controllers/tw_list_icon_delete_mtrl.svg)}.ui-icon-up::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_close_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_close_mtrl.svg)}.ui-icon-down::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg)}.ui-icon-left::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg);-webkit-transform:translate(-50%,-50%) rotateZ(90deg);-ms-transform:translate(-50%,-50%) rotate(90deg);transform:translate(-50%,-50%) rotateZ(90deg)}.ui-icon-right::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg)}.ui-icon-next::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_close_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_close_mtrl.svg)}.ui-btn.ui-icon-next::after,.ui-btn.ui-icon-right::after{-webkit-transform:translate(-50%,-50%) rotateZ(90deg);-ms-transform:translate(-50%,-50%) rotate(90deg);transform:translate(-50%,-50%) rotateZ(90deg)}.ui-btn.ui-icon-left::after{-webkit-transform:translate(-50%,-50%) rotateZ(-90deg);-ms-transform:translate(-50%,-50%) rotate(-90deg);transform:translate(-50%,-50%) rotateZ(-90deg)}:root{--button-fab-radius:50%;--button-fab-icon-color:var(--color-white);--button-fab-right:24px;--button-fab-bottom:24px;--button-fab-width:56px;--button-fab-height:56px;--button-fab-icon-width:24px;--button-fab-icon-height:24px}tau-button{-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;background-color:#ddd;border-bottom-color:#ddd;border-bottom-style:outset;border-bottom-width:2px;border-image-outset:0;border-image-repeat:stretch;border-image-slice:100%;border-image-source:none;border-image-width:1;border-left-color:#ddd;border-left-style:outset;border-left-width:2px;border-right-color:#ddd;border-right-style:outset;border-right-width:2px;border-top-color:#ddd;border-top-style:outset;border-top-width:2px;box-sizing:border-box;color:#000;cursor:default;display:inline-block;font-family:Arial,'MS Trebuchet',sans-serif;font-size:13.3333330154419px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;line-height:normal;margin-bottom:0;margin-left:0;margin-right:0;margin-top:0;padding-bottom:1px;padding-left:6px;padding-right:6px;padding-top:1px;text-align:center;text-indent:0;text-rendering:auto;text-shadow:none;text-transform:none;word-spacing:0;-webkit-writing-mode:horizontal-tb;-ms-writing-mode:lr-tb;writing-mode:horizontal-tb}@-webkit-keyframes btn_pressup_animation{0%{opacity:1}33%{opacity:1}100%{opacity:0}}@keyframes btn_pressup_animation{0%{opacity:1}33%{opacity:1}100%{opacity:0}}@-webkit-keyframes btn_press_animation_nobg{0%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}100%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}}@keyframes btn_press_animation_nobg{0%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}100%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}}@-webkit-keyframes btn_press_animation_flat_opacity_in{0%{background-color:transparent}100%{background-color:var(--ripple-button-flat-color)}}@keyframes btn_press_animation_flat_opacity_in{0%{background-color:transparent}100%{background-color:var(--ripple-button-flat-color)}}@-webkit-keyframes btn_press_animation_flat_opacity_out{0%{background-color:var(--ripple-button-flat-color)}100%{background-color:transparent}}@keyframes btn_press_animation_flat_opacity_out{0%{background-color:var(--ripple-button-flat-color)}100%{background-color:transparent}}@-webkit-keyframes btn_press_animation_flat_icon_opacity_in{0%{background-color:var(--button-background-flat)}100%{background-color:var(--ripple-button-flat-color)}}@keyframes btn_press_animation_flat_icon_opacity_in{0%{background-color:var(--button-background-flat)}100%{background-color:var(--ripple-button-flat-color)}}@-webkit-keyframes btn_press_animation_flat_icon_opacity_out{0%{background-color:var(--ripple-button-flat-color)}100%{background-color:var(--button-background-flat)}}@keyframes btn_press_animation_flat_icon_opacity_out{0%{background-color:var(--ripple-button-flat-color)}100%{background-color:var(--button-background-flat)}}@-webkit-keyframes btn_press_animation_flat_scale{0%{-webkit-transform:translate(-50%,-50%) scale(0.95);transform:translate(-50%,-50%) scale(0.95)}100%{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@keyframes btn_press_animation_flat_scale{0%{-webkit-transform:translate(-50%,-50%) scale(0.95);transform:translate(-50%,-50%) scale(0.95)}100%{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@-webkit-keyframes btn_press_animation_flat_icon_scale{0%{-webkit-transform:translate(-50%,-50%) scale(0.95);transform:translate(-50%,-50%) scale(0.95)}100%{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@keyframes btn_press_animation_flat_icon_scale{0%{-webkit-transform:translate(-50%,-50%) scale(0.95);transform:translate(-50%,-50%) scale(0.95)}100%{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@-webkit-keyframes btn_press_animation_flat_icon_scale_left{0%{-webkit-transform:translateY(-50%) scale(0.95);transform:translateY(-50%) scale(0.95)}100%{-webkit-transform:translateY(-50%) scale(1);transform:translateY(-50%) scale(1)}}@keyframes btn_press_animation_flat_icon_scale_left{0%{-webkit-transform:translateY(-50%) scale(0.95);transform:translateY(-50%) scale(0.95)}100%{-webkit-transform:translateY(-50%) scale(1);transform:translateY(-50%) scale(1)}}@-webkit-keyframes btn_press_animation_flat_icon_scale_top{0%{-webkit-transform:translateX(-50%) scale(0.95);transform:translateX(-50%) scale(0.95)}100%{-webkit-transform:translateX(-50%) scale(1);transform:translateX(-50%) scale(1)}}@keyframes btn_press_animation_flat_icon_scale_top{0%{-webkit-transform:translateX(-50%) scale(0.95);transform:translateX(-50%) scale(0.95)}100%{-webkit-transform:translateX(-50%) scale(1);transform:translateX(-50%) scale(1)}}@-webkit-keyframes animation_opacity_in{0%{opacity:0}10%{opacity:1}100%{opacity:1}}@keyframes animation_opacity_in{0%{opacity:0}10%{opacity:1}100%{opacity:1}}@-webkit-keyframes animation_opacity_out{0%{opacity:1}100%{opacity:0}}@keyframes animation_opacity_out{0%{opacity:1}100%{opacity:0}}button.ui-btn,input[type=button].ui-btn{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;border:0;outline:0}a.ui-btn{text-decoration:none;width:100%}.ui-btn{position:relative;padding:0 16px;min-height:36px;vertical-align:middle;text-overflow:ellipsis;text-align:center;color:var(--primary-color);font-size:var(--button-text-font-size);white-space:nowrap;cursor:pointer;background-color:var(--button-background);box-sizing:border-box;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;z-index:0;border-radius:18px;font-family:Roboto-Medium}.ui-btn::before{position:absolute;top:50%;left:50%;width:100%;height:100%;opacity:0;content:"";border-width:0;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.ui-btn::after{position:absolute;top:50%;left:50%;-webkit-mask-size:100% 100%;-moz-mask-size:100% 100%;-ms-mask-size:100% 100%;-o-mask-size:100% 100%;mask-size:100% 100%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-mask-repeat:no-repeat;-moz-mask-repeat:no-repeat;-ms-mask-repeat:no-repeat;-o-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;-moz-mask-position:center;-ms-mask-position:center;-o-mask-position:center;mask-position:center;-webkit-mask-size:100%;-moz-mask-size:100%;-ms-mask-size:100%;-o-mask-size:100%;mask-size:100%;content:""}.ui-btn:focus{outline:0}.ui-btn:not(.ui-btn-nobg)::before{z-index:-1;border-radius:26px;background-color:var(--ripple-color);box-sizing:border-box}.ui-btn:not(.ui-btn-nobg).ui-btn-active::before{opacity:1;-webkit-animation:btn_press_animation_flat_opacity_in linear 100ms,btn_press_animation_flat_opacity_out linear 400ms 100ms,btn_press_animation_flat_scale cubic-bezier(0.33,0,.2,1) 350ms;animation:btn_press_animation_flat_opacity_in linear 100ms,btn_press_animation_flat_opacity_out linear 400ms 100ms,btn_press_animation_flat_scale cubic-bezier(0.33,0,.2,1) 350ms}.ui-btn.ui-btn-focus{outline:2px solid var(--primary-color)}.ui-btn.ui-btn-nobg{background-color:transparent;color:var(--primary-color)}.ui-btn.ui-btn-nobg::before{background-color:var(--ripple-color);opacity:0;border-radius:50%;width:40px;height:40px;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.ui-btn.ui-btn-nobg.ui-btn-active::before{-webkit-animation:btn_press_animation_nobg linear 315ms;animation:btn_press_animation_nobg linear 315ms;opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}.ui-btn.ui-btn-nobg.ui-btn-active.ui-btn-inactive::before{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}.ui-btn.ui-btn-nobg.ui-btn-active.ui-btn-inactive::after{-webkit-animation:btn_pressup_animation 300ms linear;animation:btn_pressup_animation 300ms linear;opacity:0}.ui-btn.ui-btn-nobg.ui-btn-icon::after{background-color:var(--text-color);-webkit-mask-size:100%;mask-size:100%;-webkit-mask-position:center;mask-position:center}.ui-btn.ui-btn-nobg.ui-btn-icon.ui-btn-active::after{background-color:var(--text-color)}.ui-btn.ui-btn-nobg.ui-btn-icon.ui-icon-delete::after{background-color:F060L3;transition:background-color 15ms}.ui-btn.ui-btn-nobg.ui-btn-icon.ui-icon-delete.ui-btn-active::after{background-color:F060L3P;transition:background-color 300ms}.ui-btn.ui-btn-icon.ui-state-disabled::after{opacity:.4}.ui-btn.ui-btn-icon.ui-btn-circle{width:49px;height:49px}.ui-btn.ui-btn-icon.ui-btn-circle::after{background-color:var(--text-color)}.ui-btn.ui-btn-icon.ui-btn-nobg{width:40px;height:40px;text-indent:-4999.5px;padding:10px 0;border-radius:0}.ui-btn.ui-btn-icon.ui-btn-nobg.ui-inline{width:40px}.ui-btn.ui-btn-icon.ui-btn-nobg::after{width:25px;height:25px}.ui-btn.ui-btn-icon.ui-color-add::after{background-color:var(--btn-add-color)}.ui-btn.ui-btn-icon.ui-color-delete::after{background-color:var(--btn-delete-color)}.ui-btn.ui-inline{display:inline-block;width:auto}.ui-btn.ui-hidden{display:none}.ui-btn.ui-state-disabled{pointer-events:none;background-color:var(--button-background);color:var(--button-text-color-disabled)}.ui-btn.ui-btn-icon.ui-btn-icon-only{text-indent:-4999.5px;width:104px}.ui-btn.ui-btn-icon::after{background-color:var(--button-icon-color)}.ui-btn.ui-btn-icon.ui-btn-active::after{background-color:var(--text-color)}.ui-btn.ui-btn-icon.ui-btn-icon-left{padding-left:65px;padding-right:30px}.ui-btn.ui-btn-icon.ui-btn-icon-left::after{left:29px}.ui-btn.ui-btn-icon.ui-btn-icon-right{padding-left:30px;padding-right:65px}.ui-btn.ui-btn-icon.ui-btn-icon-right::after{right:29px;left:auto}.ui-btn.ui-btn-icon.ui-btn-icon-left::after,.ui-btn.ui-btn-icon.ui-btn-icon-right::after{top:50%;-webkit-transform:translate(0,-50%);-ms-transform:translate(0,-50%);transform:translate(0,-50%)}.ui-btn.ui-btn-icon.ui-btn-icon-top{padding-top:65px;padding-bottom:40px}.ui-btn.ui-btn-icon.ui-btn-icon-top::after{top:28px}.ui-btn.ui-btn-icon.ui-btn-icon-bottom{padding-top:40px;padding-bottom:65px}.ui-btn.ui-btn-icon.ui-btn-icon-bottom::after{bottom:28px}.ui-btn.ui-btn-icon.ui-btn-icon-top::after,.ui-btn.ui-btn-icon.ui-btn-icon-bottom::after{left:50%;-webkit-transform:translate(-50%,0);-ms-transform:translate(-50%,0);transform:translate(-50%,0)}.ui-btn.ui-btn-text-light,.ui-btn.ui-btn-text-dark{min-height:24px;height:24px;line-height:17px;min-width:48px;font-size:16px;padding:4px 12px}.ui-btn.ui-btn-text-light.ui-btn-active,.ui-btn.ui-btn-text-dark.ui-btn-active{font-size:16px}.ui-btn.ui-btn-text-light{background-color:W019}.ui-btn.ui-btn-text-light.ui-btn-active{background-color:W019P}.ui-btn.ui-btn-text-dark{background-color:W020}.ui-btn.ui-btn-text-dark.ui-btn-active::before{background-color:W020P}.ui-btn.ui-btn-flat{color:var(--primary-dark-color)}.ui-btn.ui-btn-flat::before{border-radius:22px}.ui-btn.ui-btn-flat.ui-btn-icon{color:var(--text-color);min-height:32px;max-width:32px}.ui-btn.ui-btn-flat.ui-btn-icon::after{width:32px;height:32px;border-radius:28px;-webkit-mask-size:32px;mask-size:32px}.ui-btn.ui-btn-flat.ui-btn-icon::before{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);height:32px;width:32px;border-radius:28px;background-color:var(--button-background-flat)}.ui-btn.ui-btn-flat.ui-btn-icon-top{line-height:normal;height:60px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding:0;color:var(--appbar-subtitle-color)}.ui-btn.ui-btn-flat.ui-btn-icon-top::after{top:auto;left:auto;border-radius:0;width:24px;height:24px;-webkit-mask-size:24px;mask-size:24px;position:relative;padding-bottom:1px;-webkit-transform:none;-ms-transform:none;transform:none;background-color:var(--bottom-button-icon-color)}.ui-btn.ui-btn-flat.ui-btn-icon-top::before{top:auto;left:auto;border-radius:12px;-webkit-transform:none;-ms-transform:none;transform:none;width:100%;height:56px;opacity:0;background-color:var(--ripple-color)}.ui-btn.ui-btn-flat.ui-btn-icon-top.ui-btn-icon.ui-btn-active::before{-webkit-animation:animation_opacity_in 200ms linear;animation:animation_opacity_in 200ms linear;-webkit-animation-fill-mode:both;animation-fill-mode:both}.ui-btn.ui-btn-flat.ui-btn-icon-top.ui-btn-icon.ui-btn-inactive::before{-webkit-animation:animation_opacity_out 50ms linear;animation:animation_opacity_out 50ms linear}.ui-btn.ui-btn-flat.ui-btn-icon-left{padding-top:13px;padding-right:8px;padding-bottom:13px;max-height:56px}.ui-btn.ui-btn-flat.ui-btn-icon-left::after{left:0}.ui-btn.ui-btn-flat.ui-btn-icon-left::before{left:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.ui-btn.ui-btn-flat.ui-btn-icon-left.ui-btn-icon.ui-btn-active::before{-webkit-animation:btn_press_animation_flat_icon_opacity_in linear 100ms,btn_press_animation_flat_icon_opacity_out linear 400ms 100ms,btn_press_animation_flat_icon_scale_left cubic-bezier(0.33,0,.2,1) 350ms;animation:btn_press_animation_flat_icon_opacity_in linear 100ms,btn_press_animation_flat_icon_opacity_out linear 400ms 100ms,btn_press_animation_flat_icon_scale_left cubic-bezier(0.33,0,.2,1) 350ms}.ui-btn.ui-btn-flat.ui-btn-icon.ui-btn-active::before{-webkit-animation:btn_press_animation_flat_icon_opacity_in linear 100ms,btn_press_animation_flat_icon_opacity_out linear 400ms 100ms,btn_press_animation_flat_icon_scale cubic-bezier(0.33,0,.2,1) 350ms;animation:btn_press_animation_flat_icon_opacity_in linear 100ms,btn_press_animation_flat_icon_opacity_out linear 400ms 100ms,btn_press_animation_flat_icon_scale cubic-bezier(0.33,0,.2,1) 350ms}.ui-btn.ui-btn-flat.ui-btn-disabled{opacity:.4}.ui-btn.ui-btn-contained{background-color:var(--button-background-contained);color:var(--text-color);font-size:var(--button-contained-text-font-size);border-radius:22px;width:auto;text-overflow:ellipsis;overflow:hidden;padding-top:12px;padding-bottom:12px}.ui-btn.ui-btn-contained::before{border-radius:22px}.ui-btn.ui-btn-contained:not(.ui-btn-inline){max-width:75%;width:60%;display:block;margin:0 auto}.ui-btn.ui-btn-contained.ui-state-disabled{opacity:.4;color:var(--button-text-contained-dim-color)}.ui-btn.ui-btn-contained-colored{background-color:var(--primary-dark-color);font-size:17px;color:var(--color-white)}.ui-btn.ui-btn-contained-colored.ui-state-disabled{color:var(--color-white)}.ui-btn.ui-btn-fab{position:fixed;right:var(--button-fab-right);bottom:var(--button-fab-bottom);width:var(--button-fab-width);height:var(--button-fab-height);background-color:var(--primary-color);z-index:1000;border-radius:var(--button-fab-radius)}.ui-btn.ui-btn-fab::after{background-color:var(--button-fab-icon-color);width:var(--button-fab-icon-width);height:var(--button-fab-icon-height)}.ui-btn.ui-btn-fab.ui-btn-active.ui-btn-icon::after{background-color:var(--button-fab-icon-color)}.ui-btn .ui-btn-content{width:90px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin:0 auto}.ui-btn .ui-btn-content :first-child{font-size:13px;font-family:Roboto-Regular;color:#949494}.ui-btn .ui-btn-content :nth-child(2){font-size:13px;font-family:Roboto-Medium;color:#404040}@media all and (min-width:673px) and (min-height:411px){.ui-btn.ui-btn-contained:not(.ui-btn-inline):not(.ui-btn.ui-popup-toast-has-button){max-width:60%;min-width:240px}}.ui-listview li.ui-li-has-btn{box-sizing:border-box}.ui-listview li .ui-btn.ui-btn-contained{border-radius:18px;font-size:var(--button-contained-list-text-font-size);padding-top:8px;padding-bottom:8px}.ui-listview .ui-btn-flat,.ui-listview .ui-btn-contained{margin-right:24px;margin-left:8px}.ui-li-has-btn{display:-webkit-flex;display:-ms-flexbox;display:flex;height:60px}.ui-li-has-btn .ui-btn{margin:-7px auto;max-width:248px}.ui-li-has-btn .ui-btn~.ui-btn{margin-left:8px}.ui-listview .ui-expandable,.ui-content-area .ui-expandable{padding:0 24px;-webkit-user-select:none;-ms-user-select:none;user-select:none;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-listview .ui-expandable .ui-expandable-heading,.ui-content-area .ui-expandable .ui-expandable-heading{color:var(--text-color);font-size:18px;font-weight:400;padding-top:15px;padding-bottom:16px;line-height:21px;margin:0;position:relative}.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle,.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle{position:relative;display:block}.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle:focus,.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle:focus{outline:0}.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle::after,.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle::after{content:"";position:absolute;right:-8px;top:calc(50% - 16px);-webkit-mask-image:url(images/6_Lists/tw_expander_close_mtrl.svg);mask-image:url(images/6_Lists/tw_expander_close_mtrl.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:100%;mask-size:100%;background-color:var(--expander-color);width:32px;height:32px;transition:all 330ms ease;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}.ui-listview .ui-expandable .ui-expandable-heading .ui-btn,.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn{width:32px;height:32px;min-height:auto;position:absolute;right:-8px;top:calc(50% - 16px)}.ui-listview .ui-expandable .ui-expandable-heading .ui-btn::before,.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn::before{width:32px;height:32px;display:none}.ui-listview .ui-expandable .ui-expandable-heading .ui-btn::after,.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn::after{width:32px;height:32px;-webkit-mask-size:32px;mask-size:32px;background-color:var(--expander-color);transition:all 330ms ease;-webkit-transform:translate(-50%,-50%) rotate(0);-ms-transform:translate(-50%,-50%) rotate(0);transform:translate(-50%,-50%) rotate(0)}.ui-listview .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-expandable-heading-toggle::after,.ui-content-area .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-expandable-heading-toggle::after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.ui-listview .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-btn::after,.ui-content-area .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-btn::after{-webkit-transform:translate(-50%,-50%) rotate(180deg);-ms-transform:translate(-50%,-50%) rotate(180deg);transform:translate(-50%,-50%) rotate(180deg)}.ui-listview .ui-expandable .ui-expandable-content,.ui-content-area .ui-expandable .ui-expandable-content{transition:all 330ms ease;overflow:auto}.ui-listview .ui-expandable .ui-expandable-content .ui-listview,.ui-content-area .ui-expandable .ui-expandable-content .ui-listview{padding:0;margin-left:18px}.ui-listview .ui-expandable .ui-expandable-content .ui-listview li,.ui-content-area .ui-expandable .ui-expandable-content .ui-listview li{color:var(--expandable-text-color);padding-top:15px;padding-bottom:16px;line-height:21px;margin:0}.ui-listview .ui-expandable .ui-expandable-content-collapsed,.ui-content-area .ui-expandable .ui-expandable-content-collapsed{overflow:hidden;max-height:0!important;display:none;transition:all 330ms ease}.ui-listview .ui-expandable.ui-state-disabled,.ui-content-area .ui-expandable.ui-state-disabled{cursor:default!important;pointer-events:none;zoom:1}.ui-listview .ui-expandable.ui-state-disabled .ui-expandable-heading .ui-expandable-heading-toggle::after,.ui-content-area .ui-expandable.ui-state-disabled .ui-expandable-heading .ui-expandable-heading-toggle::after{background-color:var(--control-background)}.ui-expandable-from~:not(.ui-expandable-to){display:none}.ui-listview .ui-expandable-from~:not(.ui-expandable-to){display:none}.ui-expandable-from.ui-expandable-expanded~:not(.ui-expandable-to){display:inherit}.ui-listview .ui-expandable-to~:not(.ui-expandable-from){display:inherit}.ui-expandable-to .ui-btn.ui-btn-flat,.ui-expandable-from .ui-btn.ui-btn-flat{width:32px;height:32px;min-height:auto;margin:auto}.ui-expandable-to .ui-btn.ui-btn-flat::before,.ui-expandable-from .ui-btn.ui-btn-flat::before{width:32px;height:32px}.ui-expandable-to .ui-btn.ui-btn-flat::after,.ui-expandable-from .ui-btn.ui-btn-flat::after{width:32px;height:32px;-webkit-mask-size:32px;mask-size:32px;background-color:var(--expander-color);transition:all 330ms ease;-webkit-transform:translate(-50%,-50%) rotate(0);-ms-transform:translate(-50%,-50%) rotate(0);transform:translate(-50%,-50%) rotate(0)}.ui-expandable-from .ui-btn.ui-btn-flat{position:absolute;right:-6px}.ui-expandable-from.ui-expandable-expanded~.ui-expandable-to .ui-btn.ui-btn-flat::after,.ui-expandable-from.ui-expandable-expanded .ui-btn.ui-btn-flat::after{-webkit-transform:translate(-50%,-50%) rotate(180deg);-ms-transform:translate(-50%,-50%) rotate(180deg);transform:translate(-50%,-50%) rotate(180deg)}.ui-floatingactions{position:fixed;right:0;bottom:21.5px;height:60px;padding-left:15px;padding-right:15px;-webkit-transform:translate3d(12px,0,0);transform:translate3d(12px,0,0);-webkit-mask-box-image-repeat:repeat;-moz-mask-box-image-repeat:repeat;-ms-mask-box-image-repeat:repeat;-o-mask-box-image-repeat:repeat;mask-box-image-repeat:repeat;-webkit-mask-box-image-width:auto;-moz-mask-box-image-width:auto;-ms-mask-box-image-width:auto;-o-mask-box-image-width:auto;mask-box-image-width:auto;-webkit-mask-box-image-source:url(images/nine-patch/core_floating_button_bg.png);-webkit-mask-box-image-slice:60 64 60 64 fill;-moz-mask-box-image-slice:60 64 60 64 fill;-ms-mask-box-image-slice:60 64 60 64 fill;-o-mask-box-image-slice:60 64 60 64 fill;mask-box-image-slice:60 64 60 64 fill;background-color:var(--primary-dark-color);z-index:1000}.ui-floatingactions.ui-floatingactions-transitions{transition-property:all;transition-duration:500ms}.ui-floatingactions .ui-btn{display:inline-block;width:60px;height:60px;margin:0;background-color:transparent;color:var(--primary-color)}.ui-floatingactions .ui-btn.ui-btn-icon{width:60px}.ui-floatingactions .ui-btn::before{background-color:var(--ripple-color);opacity:0;border-radius:50%;width:40px;height:40px;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.ui-floatingactions .ui-btn.ui-btn-active::before{-webkit-animation:btn_press_animation_nobg linear 315ms;animation:btn_press_animation_nobg linear 315ms;opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}.ui-floatingactions .ui-btn.ui-btn-active.ui-btn-inactive::before{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}.ui-floatingactions .ui-btn.ui-btn-active.ui-btn-inactive::after{-webkit-animation:btn_pressup_animation 300ms linear;animation:btn_pressup_animation 300ms linear;opacity:0}.ui-floatingactions .ui-btn.ui-btn-icon::after{background-color:var(--text-color);-webkit-mask-size:100%;mask-size:100%;-webkit-mask-position:center;mask-position:center}.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-active::after{background-color:var(--text-color)}.ui-floatingactions .ui-btn.ui-btn-icon.ui-icon-delete::after{background-color:F060L3;transition:background-color 15ms}.ui-floatingactions .ui-btn.ui-btn-icon.ui-icon-delete.ui-btn-active::after{background-color:F060L3P;transition:background-color 300ms}.ui-floatingactions .ui-btn::before{background-color:var(--ripple-color)}.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left{padding:0}.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:40px;height:40px;background-color:var(--color-white);z-index:-100}.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active ::after{background-color:var(--ripple-color)}.ui-floatingactions .ui-btn.ui-icon-floating-add::after{-webkit-mask-image:url(images/controls/core_floating_icon_add.png);mask-image:url(images/controls/core_floating_icon_add.png)}.ui-floatingactions .ui-btn.ui-icon-floating-search::after{-webkit-mask-image:url(images/controls/core_floating_icon_search.png);mask-image:url(images/controls/core_floating_icon_search.png)}.ui-floatingactions .ui-btn-focus{outline:0;background-color:rgba(50,150,166,.4)}.ui-floatingactions .ui-btn~.ui-btn{margin-left:-10px}.ui-floatingactions.ui-floatingactions-expand-to-right{padding-right:30px;right:-15px}.ui-floatingactions.ui-floatingactions-expand-to-left{padding-left:30px}.ui-floatingactions:focus{outline:0;background-color:rgba(78,97,173,.8)}.ui-floatingactions-reposition:focus{background-color:var(--ripple-color)}.ui-content .ui-floatingactions,.ui-tabs .ui-floatingactions{background-color:var(--primary-dark-color)}.ui-content .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after,.ui-tabs .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after{background-color:var(--color-white)}.ui-content .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after,.ui-tabs .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after{background-color:var(--ripple-color)}.ui-content .ui-floatingactions .ui-btn::before,.ui-tabs .ui-floatingactions .ui-btn::before{background-color:var(--ripple-color)}.ui-content .ui-floatingactions:focus,.ui-tabs .ui-floatingactions:focus{outline:0;background-color:rgba(78,97,173,.8)}.ui-content .ui-floatingactions-reposition:focus,.ui-tabs .ui-floatingactions-reposition:focus{background-color:var(--ripple-color)}.ui-indexscrollbar~.ui-floatingactions{background-color:var(--primary-dark-color)}.ui-indexscrollbar~.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after{background-color:var(--color-white)}.ui-indexscrollbar~.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after{background-color:var(--ripple-color)}.ui-indexscrollbar~.ui-floatingactions .ui-btn::before{background-color:var(--ripple-color)}.ui-listview~.ui-floatingactions .ui-btn.ui-btn-icon::after{background-color:var(--color-white)}.ui-listview~.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-active::after{background-color:var(--ripple-color)}.ui-page-floatingactions.ui-empty-state .ui-content{box-sizing:border-box;border-bottom:127px solid transparent}tau-listview{display:block;list-style-type:disc;-webkit-margin-before:1em;-webkit-margin-after:1em;-webkit-margin-start:0;-webkit-margin-end:0;-webkit-padding-start:40px}tau-expandable{display:list-item;text-align:-webkit-match-parent}.ui-listview{margin:auto;padding:0;list-style:none;counter-reset:listnumbering;position:relative;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@media (min-width:673px) and (min-height:411px){.ui-listview{width:90%}}@media (min-width:960px){.ui-listview{width:75%}}.ui-listview.ui-content-area{margin-bottom:16px}.ui-listview.ui-content-area+button[data-style=fab]{display:block;min-height:0;margin-bottom:108px}.ui-listview li{display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;box-sizing:content-box;overflow:visible;text-align:left;font-size:18px}.ui-listview li[disabled]{opacity:.4}.ui-listview li.ui-li-subheader{margin-left:20px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-listview li.ui-li-subheader:empty{margin-top:16px}.ui-listview li.ui-li-subheader .ui-li-text-subheader{display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;color:var(--text-secondary-color);font-family:Roboto-Medium;font-size:14px;margin-left:4px;margin-right:16px;min-height:36px;-webkit-align-items:center;-ms-flex-align:center;align-items:center;white-space:nowrap}.ui-listview li.ui-li-subheader::after{content:"";display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;width:calc(100% - 20px);border-bottom:3px dotted var(--subheader-divider-color);height:0;-webkit-align-items:center;-ms-flex-align:center;align-items:center;margin-right:20px}.ui-listview li.ui-li-anchor{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:14px 0;margin:0 24px}.ui-listview li.ui-li-has-text-input{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:18px 0 8px;margin:0 24px}.ui-listview li .ui-li-checkbox-icon{-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li .ui-li-checkbox-icon img{width:40px;height:40px;margin-right:18px;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-listview li .ui-li-icon{width:40px;height:40px;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;position:relative;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;margin:0 12px}.ui-listview li .ui-li-icon.ui-li-icon-small,.ui-listview li .ui-li-icon.ui-li-icon-small:after{width:25px!important;height:25px!important}.ui-listview li .ui-li-icon::after,.ui-listview li .ui-li-icon *{content:"";position:absolute;width:40px;height:40px;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-position:center center;mask-position:center center}.ui-listview li .ui-li-text{display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:15px 0;margin-right:24px}.ui-listview li .ui-li-text .ui-li-text-title{font-size:18px;color:var(--text-color);line-height:21px;vertical-align:middle}.ui-listview li .ui-li-text .ui-li-text-title:only-child{padding-bottom:1px}.ui-listview li .ui-li-text .ui-li-text-title+.ui-li-text-sub::before{content:"";display:block;height:4px}.ui-listview li .ui-li-text .ui-li-text-sub{font-size:13px;color:var(--text-secondary-color);line-height:15px}.ui-listview li .ui-li-text .ui-li-text-sub+.ui-li-text-title::before{content:"";display:block;height:4px}.ui-listview li .ui-li-text .ui-li-text-sub img{width:15px;height:15px}.ui-listview li .ui-li-text .ui-li-text-value{color:var(--primary-color)}.ui-listview li>.ui-li-text:first-child{margin-left:24px}.ui-listview li.ui-li-divider::after{content:"";position:absolute;width:calc(100% - 40px);left:20px;bottom:-.75px;height:.75px;background-color:var(--divider-color);opacity:var(--divider-opacity)}.ui-listview li.ui-li-divider.ui-li-has-icon::after{width:calc(100% - 84px);left:64px}.ui-listview li.ui-li-divider.ui-li-has-checkbox::after,.ui-listview li.ui-li-divider.ui-li-has-radio::after{width:calc(100% - 92px);left:68px}.ui-listview li.ui-li-divider.ui-li-has-checkbox-icon::after{left:126px}.ui-listview li+li.ui-li-divider{margin-top:.75px}.ui-listview li .ui-li-divider{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;margin-left:12px;margin-right:9px}.ui-listview li .ui-li-divider::after{content:"";position:absolute;width:.5px;height:22px;background-color:var(--on-off-switch-divider-color)}.ui-listview li .ui-li-action{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;margin-left:auto;white-space:nowrap}.ui-listview li .ui-li-action .ui-on-off-switch-container{margin-right:24px}.ui-listview li .ui-li-right{margin-left:auto!important}.ui-listview li .ui-li-text-ellipse{min-width:0;white-space:nowrap}.ui-listview li .ui-li-text-ellipse *{text-overflow:ellipsis;overflow:hidden}.ui-listview li input[type=checkbox].ui-checkbox,.ui-listview li input[type=radio].ui-radio{-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li.ui-li-selected{background-color:var(--list-item-selected-color)}.ui-listview li,.ui-listview tau-expandable{box-shadow:none}.ui-listview li .ui-link-inherit,.ui-listview tau-expandable .ui-link-inherit{color:var(--text-color)}.ui-listview li:not(.ui-expandable).ui-li-active,.ui-listview tau-expandable:not(.ui-expandable).ui-li-active{background-color:var(--active)}.ui-listview li.ui-li-active.ui-expandable .ui-expandable-heading,.ui-listview tau-expandable.ui-li-active.ui-expandable .ui-expandable-heading{background-color:var(--active)}.ui-listview li>a:not(.ui-btn),.ui-listview tau-expandable>a:not(.ui-btn){display:block;width:100%;height:100%;margin:-16.5px -16px;padding:16.5px 16px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;color:var(--text-color);text-decoration:none;box-sizing:border-box}.ui-listview.ui-listview-focus{box-sizing:border-box;border:2px solid #00f}.ui-listview .ui-listview-item-focus{background-color:var(--ripple-color)}.ui-listview .ui-listview-item-focus a{outline:0}.ui-listview .ui-listview-background{display:block;box-sizing:border-box;position:absolute;top:0;left:0;pointer-events:none;z-index:-1}.ui-listview .ui-listview-background::before{content:"250,250,250,1::0,0,0,-0.04";display:none}.ui-listview.ui-listview-background-disabled .ui-listview-background{display:none}.ui-listview .ui-li-static{}.ui-listview .ui-li-static.ui-li-select-all{color:var(--background-color)}.ui-listview .ui-li-static.ui-li-select-all label{display:block}.ui-listview .ui-li-static.ui-li-select-all label input[type=checkbox]{float:right}.ui-listview .ui-li-static.li-has-thumb .li-thumb{position:absolute;left:16px;top:50%;margin-top:-13px;width:25px;height:25px}.ui-listview .ui-li-static.li-has-thumb .li-thumb.li-thumb-circle{border-radius:100%}.ui-listview .ui-li-static.li-has-thumb.li-thumbnail-right .li-thumb{float:right;left:auto;right:16px}.ui-listview .ui-li-static.li-has-progress{padding:12px 16px 11px}.ui-listview .ui-li-static.li-has-progress .ui-progress{margin:16px 0 10px}.ui-listview .ui-li-static .ui-btn.ui-btn-icon.ui-btn-nobg::after{width:40px;height:40px}.ui-listview li.ui-li-flex{display:-webkit-flex;display:-ms-flexbox;display:flex;padding:0;overflow-x:visible;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex.ui-li-select-all{color:var(--background-color)}.ui-listview li.ui-li-flex.ui-li-select-all label{display:block}.ui-listview li.ui-li-flex.ui-li-select-all label input[type=checkbox]{float:right}.ui-listview li.ui-li-flex .ui-li-text{display:-webkit-flex;display:-ms-flexbox;display:flex;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:18px;color:var(--text-color);max-height:24.25px;width:100%}.ui-listview li.ui-li-flex .ui-li-text>:not(.ui-li-text-sub-2){-webkit-flex:1;-ms-flex:1;flex:1;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text .ui-li-text-sub-2{-webkit-align-self:flex-end;-ms-align-self:flex-end;-o-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}.ui-listview li.ui-li-flex .ui-li-text-2{color:var(--text-secondary-color);line-height:21.5px;font-size:13px;max-height:17.5px;display:-webkit-flex;display:-ms-flexbox;display:flex;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text-2>:not(.ui-li-text-sub-3){-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text-2 .ui-li-text-sub-3{-webkit-align-self:flex-end;-ms-align-self:flex-end;-o-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;margin:auto 0 auto auto}.ui-listview li.ui-li-flex .ui-li-text-2 span+.ui-li-text-sub-3{margin-left:16px}.ui-listview li.ui-li-flex .ui-li-text-sub{line-height:21.5px;font-size:16px;color:var(--text-secondary-color);display:-webkit-flex;display:-ms-flexbox;display:flex;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text-sub>:not(.ui-li-text-sub-3){-webkit-flex:1;-ms-flex:1;flex:1;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text-sub .ui-li-text-sub-3{-webkit-align-self:flex-end;-ms-align-self:flex-end;-o-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;margin:auto 0 auto auto}.ui-listview li.ui-li-flex .ui-li-text-sub span+.ui-li-text-sub-3{margin-left:16px}.ui-listview li.ui-li-flex .ui-li-text-sub-2{line-height:27px;max-width:109px;margin-left:16px;font-size:15px;color:var(--text-secondary-color);float:right}.ui-listview li.ui-li-flex .ui-li-text-sub-3{line-height:22px;max-width:109px;margin-left:16px;font-size:16px;color:var(--text-secondary-color);float:right}.ui-listview li.ui-li-flex .ui-li-text-sub+.ui-li-text-sub-3{margin-top:-1rem}.ui-listview li.ui-li-flex .ui-li-area-a{position:relative;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-order:1;-ms-flex-order:1;order:1;min-width:1%;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;margin-top:16.5px;margin-bottom:16.5px;padding:0 24px 0 18px}.ui-listview li.ui-li-flex .ui-li-area-b{-webkit-order:0;-ms-flex-order:0;order:0;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-image,.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-circle-image,.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-icon{margin-left:16px}.ui-listview li.ui-li-flex .ui-li-area-c{-webkit-order:3;-ms-flex-order:3;order:3;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-image,.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-circle-image{margin-right:16px}.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-icon{margin-right:8.5px}.ui-listview li.ui-li-flex .ui-li-area-c .ui-toggle-container{margin-right:16px}.ui-listview li.ui-li-flex .ui-li-area-d{-webkit-order:2;-ms-flex-order:2;order:2;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-image,.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-circle-image{margin-right:16px}.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-icon{margin-right:16px}.ui-listview li.ui-li-flex input.ui-li-area-b[type=checkbox],.ui-listview li.ui-li-flex input.ui-li-area-b[type=radio]{margin-left:18px;margin-right:0}.ui-listview li.ui-li-flex input.ui-li-area-c[type=checkbox],.ui-listview li.ui-li-flex input.ui-li-area-c[type=radio]{margin-right:16px}.ui-listview li.ui-li-flex input.ui-li-area-d[type=checkbox],.ui-listview li.ui-li-flex input.ui-li-area-d[type=radio],.ui-listview li.ui-li-flex input.ui-li-area-d .ui-li-image,.ui-listview li.ui-li-flex input.ui-li-area-d .ui-li-circle-image{margin-right:16px}.ui-listview li.ui-li-flex .ui-li-icon::after{content:"";position:absolute;width:100%;height:100%;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-position:center center;mask-position:center center;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.ui-listview li.ui-li-flex .ui-li-area.ui-li-image{width:60px;height:60px}.ui-listview li.ui-li-flex .ui-li-area.ui-li-circle-image{width:49px;height:49px;border-radius:100%}.ui-listview li.ui-li-flex .ui-li-area.ui-li-icon{width:32px;height:32px;position:relative}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon{width:25px;min-width:25px;max-width:25px;height:25px;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;position:relative;margin-left:16px}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon.ui-li-icon-left{-webkit-order:-1;-ms-flex-order:-1;order:-1;margin-right:6px;margin-left:0}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon.ui-li-icon-middle{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-c.ui-li-icon{width:40px;height:40px;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-c.ui-li-icon:after{width:25px;height:25px}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-d.ui-li-icon{width:25px;height:25px}.ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a{margin-top:12px;margin-bottom:12px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a>.ui-li-icon{position:absolute;right:16px}.ui-listview li.ui-li-flex.ui-li-flex-reverse .ui-li-area{-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.ui-listview.ui-details .ui-li-static{color:var(--text-color);padding:12px 16px 11.5px;height:48.5px;line-height:27px}.ui-listview.ui-details .ui-li-static.li-has_icon{padding:64px 16px 11.5px}.ui-listview.ui-details .ui-li-static.li-has_icon img{position:absolute;top:20px;left:16px}.ui-listview.ui-details .ui-li-static .li-text-sub{color:var(--text-secondary-color);height:21.5px;position:initial;float:none;text-align:left;display:block;line-height:21.5px}.ui-listview.ui-details .ui-listview-background{display:none}.ui-listview .li-has-right-btn .ui-btn,.ui-listview .li-has-right-circle-btn .ui-btn{position:absolute;top:50%;right:16px;-webkit-transform:translate(0,-50%);-ms-transform:translate(0,-50%);transform:translate(0,-50%)}.ui-listview .li-has-right-btn .ui-toggle-container,.ui-listview .li-has-right-circle-btn .ui-toggle-container{position:absolute;top:50%;right:16px;-webkit-transform:translate(0,-50%);-ms-transform:translate(0,-50%);transform:translate(0,-50%)}.ui-listview .li-has-right-btn .ui-toggle-container:first-child:not(:only-child),.ui-listview .li-has-right-circle-btn .ui-toggle-container:first-child:not(:only-child){right:60px}.ui-listview .li-has-right-btn .ui-btn-icon.ui-btn-nobg,.ui-listview .li-has-right-circle-btn .ui-btn-icon.ui-btn-nobg{right:8.5px}.ui-listview .li-has-right-btn .ui-btn-icon.ui-btn-circle,.ui-listview .li-has-right-circle-btn .ui-btn-icon.ui-btn-circle{right:16px}.ui-listview .li-has-radio.li-has-right-radio .ui-radio{margin-top:0;position:absolute;right:13px;left:auto;top:18px}.ui-listview .li-has-radio.li-has-right-radio .ui-radio:first-child{right:60px}.ui-listview.ui-drag-mode li{}.ui-listview.ui-drag-mode li .ui-listview-handler{display:block;position:relative;width:32px;height:32px;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto;-webkit-order:10;-ms-flex-order:10;order:10;margin:auto 16px auto auto}.ui-listview.ui-drag-mode li .ui-listview-handler::after{content:"";position:absolute;width:100%;height:100%;-webkit-mask-size:100%;mask-size:100%;background-color:var(--reorder-color)}.ui-listview.ui-snapshot{height:100%}.ui-listview.ui-snapshot li{position:absolute;width:100%;box-sizing:border-box;transition:top .1s linear}.ui-listview.ui-snapshot li.ui-listview-helper{transition:none;background-color:var(--holder-reoder-background);box-sizing:border-box;border:.25px solid var(--holder-reoder-border)}.ui-listview.ui-snapshot li.ui-listview-helper::after{display:none}.ui-listview.ui-snapshot li.ui-listview-item.ui-listview-holder{background:0}.ui-listview.ui-snapshot li.ui-listview-item-moved{opacity:.75;transition:opacity .1s}.ui-listview.ui-snapshot li:nth-last-child(2){transition:none}.ui-listview.ui-activate-handlers li .ui-listview-handler{-webkit-animation:button-handler-activate 200ms linear alternate;animation:button-handler-activate 200ms linear alternate}.ui-listview.ui-deactivate-handlers li .ui-listview-handler{-webkit-animation:button-handler-deactivate 200ms linear alternate;animation:button-handler-deactivate 200ms linear alternate}.ui-listview.ui-cancel-animation li .ui-listview-handler{-webkit-animation:none;animation:none}.ui-listview[data-colored-background=false]{background-color:var(--background-area-color)}.ui-listview[data-colored-background=false] li:not(.ui-group-index){border-bottom:1px solid #e6e6e6;box-sizing:border-box}@-webkit-keyframes button-handler-activate{0%{margin-right:-40px}100%{margin-right:0}}@keyframes button-handler-activate{0%{margin-right:-40px}100%{margin-right:0}}@-webkit-keyframes button-handler-deactivate{0%{margin-right:0}100%{margin-right:-40px}}@keyframes button-handler-deactivate{0%{margin-right:0}100%{margin-right:-40px}}.ui-page-indicator{display:block;position:absolute;left:50%;bottom:10px;-webkit-transform:translate3d(-50%,0,0);-ms-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0)}.ui-page-indicator-item{position:relative;display:inline-block;width:16px;height:16px;-webkit-mask-image:-webkit-radial-gradient(#000 4px,transparent 5.5px);-webkit-transform:scale3d(0.7,.7,1);-ms-transform:scale3d(0.7,.7,1);transform:scale3d(0.7,.7,1);background-color:var(--primary-dark-color);margin-right:10px;transition-duration:150ms}.ui-page-indicator-item:last-child{margin-right:0}.ui-page-indicator-item.ui-page-indicator-active{background-color:var(--primary-dark-color);-webkit-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);transform:scale3d(1,1,1);transition-duration:150ms}.ui-page-indicator-dashed .ui-page-indicator-item{position:relative;display:inline-block;width:20px;height:20px;-webkit-mask-image:url(images/core_page_indicator_off.png);mask-image:url(images/core_page_indicator_off.png);-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg);background-color:var(--primary-dark-color);margin-right:1px;transition-duration:150ms;-webkit-mask-size:20px;-moz-mask-size:20px;-ms-mask-size:20px;-o-mask-size:20px;mask-size:20px}.ui-page-indicator-dashed .ui-page-indicator-item::before{content:"";position:absolute;width:20px;height:20px;-webkit-mask-image:url(images/core_page_indicator_off_ef.png);mask-image:url(images/core_page_indicator_off_ef.png);-webkit-mask-size:20px;-moz-mask-size:20px;-ms-mask-size:20px;-o-mask-size:20px;mask-size:20px}.ui-page-indicator-dashed .ui-page-indicator-item:last-child{margin-right:0}.ui-page-indicator-dashed .ui-page-indicator-item.ui-page-indicator-active{background-color:var(--primary-dark-color);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);transition-duration:150ms}tau-progress{display:block}.ui-progress-container{width:360px;height:inherit;position:absolute;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);box-sizing:border-box}.ui-progress-bar{position:relative;min-width:12px;-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;height:32px;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-ms-grid-column-align:center;justify-items:center}.ui-progress-bar .ui-progress-current-value{font-size:36px}.ui-progress-text{padding-top:17px;display:block;font-size:15px;text-align:center;color:var(--text-color)}.ui-progress-bar-labels-top{-webkit-order:1;-ms-flex-order:1;order:1;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-progress-bar-labels-bottom{-webkit-order:3;-ms-flex-order:3;order:3;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-progress-bar-value-bg{height:3px;max-height:3px;width:100%;position:relative;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-order:2;-ms-flex-order:2;order:2;background-color:var(--progress-bar-bg-color);border-radius:1.5px}.ui-progress-bar-label span~span{margin-left:2px}.ui-progress-bar-label-left-bottom{padding:4px 0 0;color:var(--text-secondary-color);font-size:16px;-webkit-flex:1;-ms-flex:1;flex:1;text-align:left;line-height:normal}.ui-progress-bar-label-right-bottom{padding:4px 0 0;color:var(--text-secondary-color);font-size:16px;-webkit-flex:1;-ms-flex:1;flex:1;text-align:right;line-height:normal}.ui-progress-bar-label-right-top{padding:0 0 4px;color:var(--progress-bar-color);font-size:16px;-webkit-flex:1;-ms-flex:1;flex:1;text-align:right;line-height:normal}.ui-progress-bar-value{height:3px;position:absolute;left:0;top:0;background-color:var(--progress-bar-color);border-radius:1.5px}.ui-progress-circle.ui-progress-circle-full{position:fixed;top:0;left:0;width:100%;height:100%}.ui-progress-circle.ui-progress-circle-large{width:124px;height:124px}.ui-progress-circle.ui-progress-circle-medium{width:56px;height:56px}.ui-progress-circle.ui-progress-circle-small{width:44px;height:44px}.ui-progress-circle{position:relative;display:inline-block;box-sizing:border-box}.ui-progress-circle *{pointer-events:none}.ui-progress-circle .ui-progress-circle-value.ui-progress-circle-half{box-sizing:border-box;clip:rect(auto,auto,auto,auto)}.ui-progress-circle .ui-progress-circle-value.ui-progress-circle-half .ui-progress-circle-value-right{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.ui-progress-circle .ui-progress-circle-value{clip:rect(0,1em,1em,.5em);width:100%;height:100%;position:absolute;box-sizing:border-box}.ui-progress-circle .ui-progress-circle-value .ui-progress-circle-value-left{border:2px solid var(--primary-color);border-radius:50%;clip:rect(0,.5em,1em,0);height:100%;width:100%;position:absolute;box-sizing:border-box}.ui-progress-circle .ui-progress-circle-value .ui-progress-circle-value-right{border:2px solid var(--primary-color);border-radius:50%;clip:rect(0,.5em,1em,0);width:100%;height:100%;position:absolute;box-sizing:border-box}.ui-progress-circle .ui-progress-circle-bg{border:2px solid var(--progress-background-color);border-radius:50%;width:100%;height:100%;box-sizing:border-box}.ui-indeterminate-bar{overflow:hidden;position:relative;height:3px;border-radius:1.5px;background-color:var(--progress-bar-bg-color)}.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate{position:relative;top:0;height:100%;padding:0;background-color:transparent;border-radius:1.5px}.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate::before{content:"";position:absolute;width:46%;left:0;top:0;height:100%;background-color:var(--progress-bar-color);-webkit-animation:indeterminate-bar1 1200ms infinite linear;animation:indeterminate-bar1 1200ms infinite linear}.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate::after{content:"";position:absolute;width:46%;left:93%;top:0;height:100%;background-color:var(--progress-bar-color);-webkit-animation:indeterminate-bar2 1200ms infinite linear;animation:indeterminate-bar2 1200ms infinite linear}@-webkit-keyframes indeterminate-bar1{0%{left:-30%}74.9%{left:100%;opacity:1}75%{left:-70%;opacity:0}75.1%{left:-70%;opacity:1}100%{left:-30%}}@keyframes indeterminate-bar1{0%{left:-30%}74.9%{left:100%;opacity:1}75%{left:-70%;opacity:0}75.1%{left:-70%;opacity:1}100%{left:-30%}}@-webkit-keyframes indeterminate-bar2{0%{left:93%}59.9%{left:232%;opacity:1}60%{left:-46%;opacity:0}60.1%{left:-46%;opacity:1}100%{left:93%}}@keyframes indeterminate-bar2{0%{left:93%}59.9%{left:232%;opacity:1}60%{left:-46%;opacity:0}60.1%{left:-46%;opacity:1}100%{left:93%}}@-webkit-keyframes rotating{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotating{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui-indeterminate-circle{box-sizing:border-box;margin:auto;-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.ui-indeterminate-circle::before{content:"";border-top-style:solid;border-left-style:solid;border-color:var(--progress-circle-second-color);border-radius:100% 0 0;display:block}.ui-indeterminate-circle::after{content:"";position:relative;left:50%;border-right-style:solid;border-bottom-style:solid;border-color:var(--primary-color);display:block;border-radius:100% 0}.ui-indeterminate-circle-small-title{width:16px;height:16px}.ui-indeterminate-circle-small-title::before,.ui-indeterminate-circle-small-title::after{width:6.5px;height:6.5px}.ui-indeterminate-circle-small-title::before{border-top-width:1.5px;border-left-width:1.5px}.ui-indeterminate-circle-small-title::after{border-right-width:1.5px;border-bottom-width:1.5px}.ui-indeterminate-circle-small{width:24px;height:24px}.ui-indeterminate-circle-small::before,.ui-indeterminate-circle-small::after{width:10px;height:10px}.ui-indeterminate-circle-small::before{border-top-width:2px;border-left-width:2px}.ui-indeterminate-circle-small::after{border-right-width:2px;border-bottom-width:2px}.ui-indeterminate-circle-medium{width:48px;height:48px}.ui-indeterminate-circle-medium::before,.ui-indeterminate-circle-medium::after{width:21px;height:21px}.ui-indeterminate-circle-medium::before{border-top-width:3px;border-left-width:3px}.ui-indeterminate-circle-medium::after{border-right-width:3px;border-bottom-width:3px}.ui-indeterminate-circle-large{width:60px;height:60px}.ui-indeterminate-circle-large::before,.ui-indeterminate-circle-large::after{width:27px;height:27px}.ui-indeterminate-circle-large::before{border-top-width:3px;border-left-width:3px}.ui-indeterminate-circle-large::after{border-right-width:3px;border-bottom-width:3px}.ui-listview .ui-li-has-progress{height:4px;padding:28px 0}.ui-listview .ui-li-has-progress-with-labels{height:4px;padding:34px 0}.ui-scrollview-view>.ui-progress-container{padding-left:56px;padding-right:56px}.ui-listview .ui-group-index+.ui-li-static{padding-top:16.5px;padding-bottom:16.5px}.ui-listview .ui-group-index~.ui-li-static>input[type=checkbox]{position:absolute;right:16px;top:17.5px}tau-textenveloper{display:block}.ui-text-enveloper{z-index:1;position:relative;background-color:transparent;display:-webkit-flex;display:-ms-flexbox;display:flex;outline:0;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;overflow-x:visible}.ui-text-enveloper.ui-text-enveloper-with-container{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-align-content:stretch;-ms-flex-line-pack:stretch;align-content:stretch}.ui-text-enveloper.ui-text-enveloper-with-container .ui-text-enveloper-container{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;white-space:pre-wrap;overflow:visible}.ui-text-enveloper .ui-text-enveloper-start{line-height:27px;height:27px;font-size:20px;margin-top:6.5px;color:var(--primary-color);margin-right:10px;display:inline-block;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn{position:relative;line-height:27px;height:40px;border-radius:7.5px;font-size:20px;margin-top:-1px;padding:7px 6px 6px;margin-left:-6px;min-height:40px;vertical-align:top;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;background-color:transparent;color:var(--primary-color);overflow:auto}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded::before,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn::before{top:50%;left:50%;width:100%;height:100%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);border-radius:0;opacity:0}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded::after,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn::after{position:absolute;content:"";top:50%;left:50%;width:100%;height:100%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;transition:opacity linear 200ms;-webkit-mask-box-image-source:url(images/nine-patch/core_focus_round.png);-webkit-mask-box-image-slice:20 20 fill;-moz-mask-box-image-slice:20 20 fill;-ms-mask-box-image-slice:20 20 fill;-o-mask-box-image-slice:20 20 fill;mask-box-image-slice:20 20 fill;background-color:var(--text-input-underline-active)}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-blur,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-blur{display:none}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-blur+span,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-blur+span{display:none}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-selected::after,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-selected::after{opacity:1}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-btn-active::before,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-btn-active::before{opacity:1;background-color:var(--ripple-color);-webkit-animation:navigation_press_animation linear 315ms;animation:navigation_press_animation linear 315ms}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-btn-active.ui-btn-inactive::before,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-btn-active.ui-btn-inactive::before{-webkit-animation:navigation_pressup_animation linear 200ms;animation:navigation_pressup_animation linear 200ms}.ui-text-enveloper .ui-text-enveloper-btn.ui-btn:not(.ui-inline){margin-left:3px;padding-left:5px;border-bottom:1px solid var(--primary-color);overflow:visible;border-radius:0;-webkit-flex:1;-ms-flex:1;flex:1;text-align:left;margin-bottom:1px}.ui-text-enveloper .ui-text-enveloper-btn.ui-btn:not(.ui-inline)+.ui-text-enveloper-input{display:block;position:absolute;width:100%;text-indent:100%;height:27px}.ui-text-enveloper .ui-text-enveloper-btn-separator{display:inline-block;margin:0 6px;width:7.5px}.ui-text-enveloper .ui-text-enveloper-btn-separator::after{content:"";display:block;position:absolute;width:7.5px;height:16.5px;margin-top:-15px;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-image:url(images/core_contact_div.png);mask-image:url(images/core_contact_div.png);background-color:var(--control-active-color);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.ui-text-enveloper .ui-text-enveloper-btn-expanded{color:var(--control-inactive-color)}.ui-text-enveloper .ui-text-enveloper-slash{margin-top:-1px;width:13.5px;height:40px;opacity:1;transition:opacity linear 200ms;display:inline-block;overflow:auto}.ui-text-enveloper .ui-text-enveloper-slash::after{content:"";width:7.5px;margin-top:12px;height:16.5px;position:absolute;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-image:url(images/core_contact_div.png);mask-image:url(images/core_contact_div.png);background-color:var(--control-active-color);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.ui-text-enveloper .ui-text-enveloper-slash.ui-text-enveloper-slash-hidden{opacity:0}.ui-text-enveloper .ui-text-enveloper-input{display:inline-block;width:auto;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;min-width:60px;line-height:27px;height:27px;margin-top:6px;font-size:20px;background-color:transparent;margin-left:-5px;margin-bottom:0}.ui-text-enveloper .ui-text-enveloper-input-new-line{clear:left;width:100%}.ui-text-enveloper .ui-text-enveloper-input-new-line .ui-text-enveloper-input{margin-left:0}.ui-text-enveloper .ui-text-enveloper-input-new-line.ui-text-enveloper-input-blur{display:none}.ui-text-enveloper input.ui-text-input~.ui-text-input-clear{top:auto}.ui-listview .ui-li-static .ui-text-enveloper,.ui-listview .ui-li-flex .ui-text-enveloper{margin-top:-7px;margin-bottom:-6px;margin-right:8.5px;width:100%}.ui-listview .ui-li-static .ui-text-enveloper input.ui-text-input+.ui-text-input-textline,.ui-listview .ui-li-flex .ui-text-enveloper input.ui-text-input+.ui-text-input-textline{margin-bottom:0}tau-gridview{display:block;list-style-type:disc}.ui-gridview{position:relative;width:100%;height:100%;padding:0;margin:0;list-style:none}.ui-gridview .ui-gridview-item{position:absolute;border:.25px solid var(--grid-border-color);box-sizing:border-box;opacity:0;border-radius:26px;overflow:hidden}.ui-gridview .ui-gridview-item.ui-gridview-item-active{transition:-webkit-transform .4s cubic-bezier(0.25,.46,.45,1);transition:transform .4s cubic-bezier(0.25,.46,.45,1);transition:transform .4s cubic-bezier(0.25,.46,.45,1), -webkit-transform .4s cubic-bezier(0.25,.46,.45,1);opacity:1}.ui-gridview .ui-gridview-item.ui-gridview-helper{transition:none;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui-gridview .ui-gridview-item .ui-gridview-handler{display:block;position:absolute;width:100%;height:100%;left:0;top:0;opacity:0}.ui-gridview .ui-gridview-item>label{position:absolute;top:0;left:0;width:100%;height:100%}.ui-gridview .ui-gridview-item>label.ui-gridview-image-checked{background-color:var(--checkbox-image-checked)}.ui-gridview .ui-gridview-item>label>input[type=checkbox]{position:absolute;margin:8px 0 0 8px;background-image:url(images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg);background-size:100%;background-repeat:no-repeat;opacity:1}.ui-gridview .ui-gridview-item>label>input[type=checkbox]:checked{background-image:url(images/3_Controllers/gallery_btn_check_bg_mtrl.svg)}.ui-gridview .ui-gridview-item>label>input[type=checkbox]::after{background-color:var(--color-white)}.ui-gridview .ui-gridview-item>label>input[type=checkbox]:disabled{opacity:.4}.ui-gridview .ui-gridview-item .ui-gridview-image{display:block;width:100%;height:auto;pointer-events:none}.ui-gridview .ui-gridview-item.ui-gridview-item-has-label .ui-gridview-image{-webkit-transform:translateY(-28.5px);-ms-transform:translateY(-28.5px);transform:translateY(-28.5px)}.ui-gridview .ui-gridview-item .ui-gridview-label{position:absolute;width:calc(100% - 30px);margin:auto;padding:0 15px;font-family:Roboto-Regular;font-size:16px;color:var(--grid-label-color);text-align:left;overflow:hidden;text-overflow:ellipsis;bottom:0;background-color:var(--background-area-color);height:57px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-gridview .ui-gridview-item .ui-gridview-label p{margin:0;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ui-gridview .ui-gridview-item .ui-gridview-label p:nth-child(1){font-size:16px;color:var(--grid-label-color)}.ui-gridview .ui-gridview-item .ui-gridview-label p:nth-child(2){margin-top:3px;font-size:13px;color:var(--grid-label-secondary-color)}.ui-gridview .ui-gridview-item .ui-gridview-badge{position:absolute;border-radius:25px;min-width:11px;background-color:var(--accent-badge);color:var(--color-white);top:4.5px;right:4.5px;padding:3px 7px;font-size:11px;text-align:center}.ui-gridview .ui-gridview-item.ui-focus{-webkit-filter:invert(0.2);filter:invert(0.2)}.ui-gridview.ui-gridview-label-in .ui-gridview-label{position:absolute;bottom:6px;display:block;color:var(--grid-label-color)}.ui-gridview.ui-gridview-label-out .ui-gridview-label{display:block;margin:0;color:var(--grid-label-color);margin-bottom:11.5px}.ui-gridview.ui-gridview-reorder .ui-gridview-item .ui-gridview-handler{opacity:1}.ui-gridview-cols::after{content:"2";position:absolute;width:1px;height:1px;opacity:0}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out){box-sizing:content-box}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item{display:-webkit-flex;display:-ms-flexbox;display:flex}@-webkit-keyframes grid_show_item{0%{opacity:0}100%{opacity:1}}@keyframes grid_show_item{0%{opacity:0}100%{opacity:1}}@media (orientation:portrait){.ui-content:not(.ui-popup-content-gridview) .ui-gridview{min-height:509px}}@media (orientation:portrait) and (min-width:480px) and (max-width:959px){.ui-gridview-cols::after{content:"3"}}@media (orientation:landscape){.ui-gridview-cols::after{content:"4"}}@media (min-width:960px){.ui-gridview-cols::after{content:"5"}}.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper{width:100%;height:auto;overflow:auto;border-radius:26px}.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper .ui-popup-content.ui-popup-content-gridview{padding:0;margin:0;height:135px}.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper .ui-popup-content.ui-popup-content-gridview-multiple{padding:0;margin:0;height:252px}@media (orientation:landscape){.ui-popup.ui-popup-gridview{width:360px;left:70px}.ui-gridview-image{display:block;width:90.5px;height:90.5px;pointer-events:none}}@media (min-width:1920px){.ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out{min-width:1920px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out .ui-gridview-item .ui-gridview-image{width:240px;height:238px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out .ui-gridview-item .ui-gridview-label{height:39px;line-height:39px;padding:0 10px;margin:0;margin-bottom:23px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out){min-width:1920px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item{width:240px;height:238px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item .ui-gridview-image{width:240px;height:238px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item .ui-gridview-label{height:39px;line-height:39px;padding:0 10px}}.ui-welcome-page .ui-content .ui-scrollview-view{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;padding-bottom:41.5px}.ui-welcome-page .ui-content .ui-welcome-icon{height:80px;width:auto;-webkit-flex:0 0 auto;-moz-flex:0 0 auto;-ms-flex:0 0 auto;-o-flex:0 0 auto;flex:0 0 auto;-webkit-align-self:center;-ms-align-self:center;-o-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-welcome-page .ui-content .ui-welcome-primary-text,.ui-welcome-page .ui-content .ui-welcome-secondary-text{margin:0 20px;font-weight:400}.ui-welcome-page .ui-content .ui-welcome-primary-text{color:var(--text-color);line-height:33.5px;font-size:24.5px}.ui-welcome-page .ui-content .ui-welcome-secondary-text{color:var(--text-secondary-color);line-height:21.5px;font-size:17.5px}.ui-welcome-page .ui-content .ui-welcome-primary-text+.ui-welcome-secondary-text{margin-top:29px}.ui-welcome-page .ui-footer{height:86px;text-align:center;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center}.ui-welcome-page .ui-footer button,.ui-welcome-page .ui-footer .ui-btn-welcome{min-width:248px;height:52px;background-color:var(--primary-color);display:inline-block;width:auto;-webkit-flex:0 0 auto;-moz-flex:0 0 auto;-ms-flex:0 0 auto;-o-flex:0 0 auto;flex:0 0 auto}.ui-welcome-page .ui-footer button:active,.ui-welcome-page .ui-footer .ui-btn-welcome:active,.ui-welcome-page .ui-footer button:focus,.ui-welcome-page .ui-footer .ui-btn-welcome:focus{background-color:var(--ripple-color)}.ui-welcome-page .ui-footer button[disabled],.ui-welcome-page .ui-footer .ui-btn-welcome[disabled],.ui-welcome-page .ui-footer button.ui-disabled,.ui-welcome-page .ui-footer .ui-btn-welcome.ui-disabled{background-color:var(--control-inactive-color)}.ui-dimmer{position:relative;border:60px solid rgba(0,151,216,.5);border-radius:100%;max-width:720px}.ui-dimmer::after{display:block;content:" ";padding-bottom:100%}.ui-dimmer .ui-dimmer-hidden{display:none}.ui-dimmer .ui-dimmer-text{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.ui-dimmer.ui-dimmer-lightbulb{width:50%;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);padding-bottom:50%;border-radius:0;border:0;background-image:url(images/dimmer/lightbulb.png);background-size:contain;display:block}.ui-dimmer.ui-dimmer-lightbulb::after{display:none}.ui-dimmer.ui-dimmer-lightbulb .ui-dimmer-lightbulb-light{display:block;position:absolute;width:60%;height:60%;left:50%;top:5%;opacity:.7;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);background-color:#ff0;-webkit-filter:blur(1.3rem);filter:blur(1.3rem);border-radius:50%;border:0;transition:background-color .3s}.wrapper{-webkit-perspective:600px;perspective:600px;margin:32px auto;margin-top:15%;margin-right:5%;width:100%;height:150px}.wrapper_test{-webkit-perspective:600px;perspective:600px;white-space:nowrap}.outer{transition:.8s;-webkit-transform:rotateY(40deg);transform:rotateY(40deg);width:auto;height:auto;overflow-x:scroll;margin-top:10%;margin-left:30%}.inner{transition:.8s;-webkit-transform:rotateY(40deg);transform:rotateY(40deg);margin-left:-15%;width:auto;height:auto}.inner figure{box-shadow:-3.5px 3.5px 1px -1.5px rgba(100,100,100,.5);display:inline-block}.inner img{display:block;width:50px;height:50px;max-width:100%;box-reflect:below 0 -webkit-gradient(linear,left bottom,left top,color-stop(0.05,rgba(255,255,255,.12)),color-stop(0.35,transparent));-webkit-box-reflect:below 0 -webkit-gradient(linear,left bottom,left top,color-stop(0.05,rgba(255,255,255,.12)),color-stop(0.35,transparent))}.flipster{display:block;overflow-x:hidden;overflow-y:visible;position:relative}.flipster:focus{outline:0}.flipster__container{margin:0;padding:0;list-style-type:none;position:relative;display:block;white-space:nowrap;word-spacing:-.25em;-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-backface-visibility:hidden;backface-visibility:hidden}.flipster__item{margin:0;padding:0;list-style-type:none;position:relative;display:inline-block;white-space:normal;word-spacing:normal;vertical-align:bottom}.flipster__item img{max-width:100%}.flipster--click .flipster__item--past{cursor:pointer}.flipster--click .flipster__item--future{cursor:pointer}.flipster__button{position:absolute;top:50%;display:block;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:0;border:0;padding:0;z-index:999;cursor:pointer;font-size:7.5px;opacity:.5;transition:opacity 500ms ease;margin:-1em 2em}.flipster__button svg{width:2em;stroke:currentColor;fill:transparent;stroke-width:3;stroke-linecap:round}.flipster__button:hover{opacity:1}.flipster__button:focus{opacity:1}.flipster__button--prev{left:0}.flipster__button--next{right:0}.flipster__nav{list-style-type:none;margin:0;padding:0;display:block;margin:0 0 4em;text-align:center;position:relative}.flipster__nav__item{list-style-type:none;margin:0;padding:0;display:inline-block;margin:0 .25em}.flipster__nav__link{display:block;color:inherit;padding:.5em 1em;position:relative;overflow:hidden;transition:all 250ms ease-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98)}.flipster__nav__link::after{content:'';display:block;background:#232221;position:absolute;top:0;left:0;width:100%;height:100%;z-index:-1;-webkit-transform:translateY(100%) translateY(-.25em);-ms-transform:translateY(100%) translateY(-.25em);transform:translateY(100%) translateY(-.25em);transition:inherit}.flipster__nav__link:hover{color:#FFF}.flipster__nav__link:hover::after{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.flipster__nav__link:focus{color:#FFF}.flipster__nav__link:focus::after{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.flipster__nav__item--current>.flipster__nav__link{color:#FFF}.flipster__nav__item--current>.flipster__nav__link::after{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.flipster__nav__item--current .flipster__nav__child{display:block}.flipster__nav__child{display:none;position:absolute;top:100%;left:0;right:0;margin-top:-.5px;padding:.5em;background:#4e4441;z-index:1}.flipster__nav__child .flipster__nav__link{color:#FFF}.flipster__nav__child .flipster__nav__link::after{background:#FFF}.flipster__nav__child .flipster__nav__link:hover{color:#232221}.flipster__nav__child .flipster__nav__link:focus{color:#232221}.flipster__nav__child .flipster__nav__item--current>.flipster__nav__link{color:#232221}.flipster--carousel .flipster__container{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98)}.flipster--carousel .flipster__item{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);-webkit-perspective:400px;perspective:400px}.flipster--carousel .flipster__item__content{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98)}.flipster--carousel .flipster__item--past{opacity:0;transition-delay:115ms}.flipster--carousel .flipster__item--past .flipster__item__content{-webkit-transform:translateX(100%) rotateY(-20deg) scale(0.5);transform:translateX(100%) rotateY(-20deg) scale(0.5)}.flipster--carousel .flipster__item--future{opacity:0;transition-delay:115ms}.flipster--carousel .flipster__item--future .flipster__item__content{-webkit-transform:translateX(-100%) rotateY(20deg) scale(0.5);transform:translateX(-100%) rotateY(20deg) scale(0.5)}.flipster--carousel .flipster__item--past-2{opacity:.6;transition-delay:20ms}.flipster--carousel .flipster__item--past-2 .flipster__item__content{-webkit-transform:translateX(25%) rotateY(40deg) scale(0.65);transform:translateX(25%) rotateY(40deg) scale(0.65)}.flipster--carousel .flipster__item--future-2{opacity:.6;transition-delay:20ms}.flipster--carousel .flipster__item--future-2 .flipster__item__content{-webkit-transform:translateX(-25%) rotateY(-40deg) scale(0.65);transform:translateX(-25%) rotateY(-40deg) scale(0.65)}.flipster--carousel .flipster__item--past-1{opacity:.6;transition-delay:20ms}.flipster--carousel .flipster__item--past-1 .flipster__item__content{-webkit-transform:rotateY(45deg) scale(0.8);transform:rotateY(45deg) scale(0.8)}.flipster--carousel .flipster__item--future-1{opacity:.6;transition-delay:20ms}.flipster--carousel .flipster__item--future-1 .flipster__item__content{-webkit-transform:rotateY(-45deg) scale(0.8);transform:rotateY(-45deg) scale(0.8)}.flipster--carousel .flipster__item--current .flipster__item__content{-webkit-transform:translateX(0) rotateY(0deg) scale(1);transform:translateX(0) rotateY(0deg) scale(1);transition-delay:60ms}.flipster--carousel.no-rotate .flipster__item--past .flipster__item__content{-webkit-transform:translateX(175%) scale(0.5);-ms-transform:translateX(175%) scale(0.5);transform:translateX(175%) scale(0.5)}.flipster--carousel.no-rotate .flipster__item--past-2 .flipster__item__content{-webkit-transform:translateX(25%) scale(0.65);-ms-transform:translateX(25%) scale(0.65);transform:translateX(25%) scale(0.65)}.flipster--carousel.no-rotate .flipster__item--past-1 .flipster__item__content{-webkit-transform:translateX(0%) scale(0.8);-ms-transform:translateX(0%) scale(0.8);transform:translateX(0%) scale(0.8)}.flipster--carousel.no-rotate .flipster__item--future .flipster__item__content{-webkit-transform:translateX(-175%) scale(0.5);-ms-transform:translateX(-175%) scale(0.5);transform:translateX(-175%) scale(0.5)}.flipster--carousel.no-rotate .flipster__item--future-2 .flipster__item__content{-webkit-transform:translateX(-25%) scale(0.65);-ms-transform:translateX(-25%) scale(0.65);transform:translateX(-25%) scale(0.65)}.flipster--carousel.no-rotate .flipster__item--future-1 .flipster__item__content{-webkit-transform:translateX(0%) scale(0.8);-ms-transform:translateX(0%) scale(0.8);transform:translateX(0%) scale(0.8)}.flipster--coverflow .flipster__container{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);padding-bottom:10%}.flipster--coverflow .flipster__item{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);-webkit-perspective:400px;perspective:400px}.flipster--coverflow .flipster__item__content{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);-webkit-transform-origin:50% 100%;-ms-transform-origin:50% 100%;transform-origin:50% 100%;box-reflect:below 0 -webkit-gradient(linear,left bottom,left top,color-stop(0.05,rgba(255,255,255,.12)),color-stop(0.35,transparent));-webkit-box-reflect:below 0 -webkit-gradient(linear,left bottom,left top,color-stop(0.05,rgba(255,255,255,.12)),color-stop(0.35,transparent))}.flipster--coverflow .flipster__item__content img:only-child{display:block}.flipster--coverflow .flipster__item--past .flipster__item__content{-webkit-transform-origin:0 50%;-ms-transform-origin:0 50%;transform-origin:0 50%;-webkit-transform:scale(0.75) rotateY(55deg);transform:scale(0.75) rotateY(55deg)}.flipster--coverflow .flipster__item--future .flipster__item__content{-webkit-transform-origin:100% 50%;-ms-transform-origin:100% 50%;transform-origin:100% 50%;-webkit-transform:scale(0.75) rotateY(-55deg);transform:scale(0.75) rotateY(-55deg)}.flipster--coverflow .flip-current .flipster__item__content{-webkit-transform:rotateY(0deg);transform:rotateY(0deg)}.flipster--flat .flipster__container{transition:all 400ms ease-in-out}.flipster--flat .flipster__item{transition:all 400ms ease-in-out}.flipster--flat .flipster__item__content{transition:all 400ms ease-in-out}.flipster--flat .flipster__item--past{opacity:.5}.flipster--flat .flipster__item--past .flipster__item__content{-webkit-transform:scale(0.75);-ms-transform:scale(0.75);transform:scale(0.75)}.flipster--flat .flipster__item--future{opacity:.5}.flipster--flat .flipster__item--future .flipster__item__content{-webkit-transform:scale(0.75);-ms-transform:scale(0.75);transform:scale(0.75)}.flipster--wheel{overflow:hidden}.flipster--wheel .flipster__container{transition:all 400ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);padding-bottom:20%}.flipster--wheel .flipster__item__content{transition:all 400ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);-webkit-transform-origin:50% 100%;-ms-transform-origin:50% 100%;transform-origin:50% 100%}.flipster--wheel .flipster__item__content img:only-child{display:block}.flipster--wheel .flipster__item--past .flipster__item__content{-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0;-webkit-transform:rotateZ(-80deg) translate(-170%,110%);-ms-transform:rotate(-80deg) translate(-170%,110%);transform:rotateZ(-80deg) translate(-170%,110%)}.flipster--wheel .flipster__item--future .flipster__item__content{-webkit-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%;opacity:0;-webkit-transform:rotateZ(80deg) translate(170%,110%);-ms-transform:rotate(80deg) translate(170%,110%);transform:rotateZ(80deg) translate(170%,110%)}.flipster--wheel .flipster__item--past-3 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(-60deg) translate(-70%,75%);-ms-transform:rotate(-60deg) translate(-70%,75%);transform:rotateZ(-60deg) translate(-70%,75%)}.flipster--wheel .flipster__item--future-3 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(60deg) translate(70%,75%);-ms-transform:rotate(60deg) translate(70%,75%);transform:rotateZ(60deg) translate(70%,75%)}.flipster--wheel .flipster__item--past-2 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(-40deg) translate(-17%,30%);-ms-transform:rotate(-40deg) translate(-17%,30%);transform:rotateZ(-40deg) translate(-17%,30%)}.flipster--wheel .flipster__item--future-2 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(40deg) translate(17%,30%);-ms-transform:rotate(40deg) translate(17%,30%);transform:rotateZ(40deg) translate(17%,30%)}.flipster--wheel .flipster__item--past-1 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(-20deg);-ms-transform:rotate(-20deg);transform:rotateZ(-20deg)}.flipster--wheel .flipster__item--future-1 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(20deg);-ms-transform:rotate(20deg);transform:rotateZ(20deg)}.flipster--wheel .flip-current .flipster__item__content{-webkit-transform:rotateX(0deg);transform:rotateX(0deg)}.ui-graph{width:100%;height:250px}.ui-toggle-slider-container{position:relative;display:inline-block;width:50px;height:26px}.ui-toggle-slider-container input{background-color:#CCC;transition:.5s;border-radius:26px;width:50px;height:26px;-webkit-appearance:none;-moz-appearance:none;appearance:none;outline:0;margin:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui-toggle-slider-container input:checked{background-color:#3695DD}.ui-toggle-slider-container input:disabled{background-color:W015L1D}.ui-toggle-slider-container .ui-toggle-slider:before{position:absolute;content:'';height:22px;width:22px;left:1px;bottom:2px;background-color:#FFF;transition:.5s;border-radius:50%;pointer-events:none}.ui-toggle-slider-container input:checked+.ui-toggle-slider:before{-webkit-transform:translateX(25.5px);-ms-transform:translateX(25.5px);transform:translateX(25.5px)}.ui-coverflow:focus{background-color:var(--ripple-color)}.ui-spin{position:relative;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;height:164px;background-color:transparent;overflow:hidden;font-size:32px;padding:0;box-sizing:content-box;width:50px}.ui-spin-item{-webkit-align-items:center;-ms-flex-align:center;align-items:center;background-color:transparent;width:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;color:var(--primary-dark-color);opacity:var(--spin-item-opacity)!important;-webkit-user-select:none;-ms-user-select:none;user-select:none;font-family:Roboto-Medium}.ui-spin-item-selected{opacity:1!important}.ui-spin-carousel-item{position:absolute;left:0;top:0;width:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-spin-enabling .ui-spin-item{transition:300ms opacity linear}.ui-spin-placeholder{opacity:0;pointer-events:none;position:absolute;display:none}.ui-time-picker{display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;height:164px;-webkit-justify-content:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.ui-time-picker[data-format="12"] .ui-time-picker-container{width:28%}.ui-time-picker[data-format="12"] .ui-time-picker-container-hour::after{content:":";height:164px;width:4%;font-size:32px;color:var(--primary-dark-color);position:absolute;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-time-picker[data-format="12"] .ui-time-picker-container-format .ui-spin-item{font-size:24px;line-height:54px}.ui-time-picker[data-format="24"] .ui-time-picker-container{width:30%}.ui-time-picker[data-format="24"] .ui-time-picker-container-hour::after{content:":";height:164px;width:13.33333333%;font-size:32px;color:var(--primary-dark-color);position:absolute;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-time-picker[data-format="24"] .ui-time-picker-container-format{display:none}.ui-time-picker .ui-spin{width:100%;height:164px;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-time-picker .ui-spin .ui-time-picker-input{width:50px;height:50px;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;text-align:center;font-size:32px;color:transparent;font-family:Roboto-Regular;border-width:0;outline:unset;outline-offset:unset;text-shadow:0 0 0 var(--primary-dark-color);opacity:0;background-color:transparent}.ui-time-picker .ui-spin .ui-time-picker-input:focus{background-color:var(--primary-color-20p)}.ui-time-picker .ui-spin-item{font-family:Roboto-Regular;line-height:56px}.ui-time-picker-input-active .ui-time-picker-container-hour .ui-spin-item,.ui-time-picker-input-active .ui-time-picker-container-minute .ui-spin-item{opacity:0!important}.ui-time-picker-input-active .ui-time-picker-container-hour .ui-time-picker-input,.ui-time-picker-input-active .ui-time-picker-container-minute .ui-time-picker-input{opacity:1}.ui-calendar-view{width:100%;border-spacing:0}.ui-calendar-view tr td{height:32px;text-align:center;vertical-align:middle;font-size:15px;font-family:Roboto-Regular;color:var(--calendar-text-color);padding:0}.ui-calendar-view tr td div{border-radius:100%;width:28px;height:28px;line-height:28px;margin:0 auto}.ui-calendar-view tr td div.ui-calendar-selection{background-color:var(--primary-color);color:var(--calendar-select-text-color)}.ui-calendar-view tr td:only-child{width:100%}.ui-calendar-view tr td:nth-last-child(2){width:50%}.ui-calendar-view tr td:nth-last-child(2)+td{width:50%}.ui-calendar-view tr td:nth-last-child(3){width:33.3%}.ui-calendar-view tr td:nth-last-child(3)~td{width:33.3%}.ui-calendar-view tr td:nth-last-child(4){width:25%}.ui-calendar-view tr td:nth-last-child(4)~td{width:25%}.ui-calendar-view tr td:nth-last-child(5){width:20%}.ui-calendar-view tr td:nth-last-child(5)~td{width:20%}.ui-calendar-view tr td:nth-last-child(6){width:16.6%}.ui-calendar-view tr td:nth-last-child(6)~td{width:16.6%}.ui-calendar-view tr td:nth-last-child(7){width:14.2%}.ui-calendar-view tr td:nth-last-child(7)~td{width:14.2%}.ui-calendar-view tr td:nth-child(7){color:var(--calendar-weekend-day-color)}.ui-calendar-view .ui-calendar-one-week{height:32px}.ui-calendar-view .ui-calendar-one-week td{font-family:Roboto-Regular;font-size:11px;color:var(--text-secondary-color)}.ui-calendar-view .ui-calendar-one-week .ui-sunday{color:var(--calendar-weekend-color)}.ui-calendar-top-space{height:10px}.ui-calendar-prev-month-day{opacity:.1}.ui-calendar-next-month-day{opacity:.4}.ui-calendar-controller{width:100%;height:36px;line-height:36px;margin:0 auto;text-align:center}.ui-calendar-controller div.ui-calendar-switch{text-align:center;font-family:Roboto-Regular;font-size:17px;color:var(--calendar-text-color);line-height:36px;display:inline}.ui-calendar-arrow{width:36px;height:36px;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:100%;mask-size:100%;background-color:var(--calendar-arrow-color)}.ui-calendar-left-arrow{float:left;-webkit-mask-image:url(images/4_Dialogs/tw_numberpicker_prev_mtrl.svg);mask-image:url(images/4_Dialogs/tw_numberpicker_prev_mtrl.svg)}.ui-calendar-right-arrow{float:right;-webkit-mask-image:url(images/4_Dialogs/tw_numberpicker_next_mtrl.svg);mask-image:url(images/4_Dialogs/tw_numberpicker_next_mtrl.svg)}.ui-calendar-disabled{opacity:.1}.ui-calendar-disabled-arrow{opacity:.4}@media (min-width:361px){.ui-calendar-controller{width:328px;margin:0 auto}}.ui-content-area .ui-calendar,.ui-popup-content .ui-calendar{padding:14px 16px}.ui-date-picker{display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-date-picker-header{font-family:Roboto-Regular;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;height:36px;font-size:17px;color:var(--date-picker-header-text-color);line-height:36px;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;margin-top:14px;margin-bottom:10px}.ui-date-picker-content{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.ui-date-picker-content .ui-date-picker-container{width:28%;height:164px;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-date-picker-content .ui-date-picker-container .ui-spin{width:100%}.ui-date-picker-content .ui-date-picker-container .ui-spin-item{font-size:32px;line-height:54px;font-family:Roboto-Regular}.ui-date-picker-content .ui-date-picker-container .ui-spin-item-selected{line-height:56px}.ui-date-picker-content .ui-date-picker-container-month .ui-spin-item{font-size:30px}.ui-datetime-picker-wheel{display:-webkit-flex;display:-ms-flexbox;display:flex;height:164px;margin-left:4%;margin-right:6%;padding-top:60px;padding-bottom:81px}.ui-datetime-picker-wheel-container{-webkit-flex:1;-ms-flex:1;flex:1;font-size:22px}.ui-datetime-picker-wheel-container-separator{position:relative}.ui-datetime-picker-wheel-container-separator::after{content:":";height:100%;width:auto;color:var(--primary-dark-color);position:absolute;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;right:0}.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-date{min-width:47%}.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-hour{min-width:14%}.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-minute{min-width:14%}.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-format{min-width:13%}.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-date{min-width:47%}.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-hour{min-width:14%}.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-minute{min-width:14%}.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-format{display:none}.ui-datetime-picker-wheel .ui-spin{width:100%;height:164px;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;white-space:nowrap;font-size:22px}.ui-datetime-picker-wheel .ui-spin .ui-datetime-picker-wheel-input{width:50px;height:50px;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;text-align:center;font-size:22px;color:transparent;font-family:Roboto-Regular;border-width:0;outline:unset;outline-offset:unset;text-shadow:0 0 0 var(--primary-dark-color);opacity:0;background-color:transparent}.ui-datetime-picker-wheel .ui-spin .ui-datetime-picker-wheel-input:focus{background-color:var(--primary-color-20p)}.ui-datetime-picker-wheel .ui-spin-item{font-family:Roboto-Regular;line-height:54px}.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-hour .ui-spin-item,.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-minute .ui-spin-item{opacity:0!important}.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-hour .ui-datetime-picker-wheel-input,.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-minute .ui-datetime-picker-wheel-input{opacity:1}.ui-datetime-picker-hidden{display:none}.ui-chip{display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;font-family:Roboto-Regular;font-size:14px;height:30px;border-radius:15px;padding:0 0 0 16px;background-color:var(--chip-background-color);border:.25px solid var(--chip-border-color);box-sizing:border-box;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-chip .ui-chip-text{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;-webkit-order:1;-ms-flex-order:1;order:1}.ui-chip .ui-chip-button{-webkit-order:2;-ms-flex-order:2;order:2}.ui-chip .ui-btn.ui-btn-flat{-webkit-order:2;-ms-flex-order:2;order:2;width:20px;height:20px;max-width:20px;max-height:20px;min-width:20px;min-height:20px;max-width:100%;margin:auto 5px auto 10px;padding:0;border-radius:100%;background-color:var(--chip-btn-background-color);border:.5px solid var(--chip-btn-border-color);box-sizing:border-box}.ui-chip .ui-btn.ui-btn-flat::after{width:20px;height:20px;-webkit-mask-size:20px;mask-size:20px}.ui-chip .ui-btn.ui-btn-flat::before{width:30px;height:30px}.ui-chip .ui-btn.ui-btn-flat.ui-btn-icon{background-color:var(--chip-btn-background-color)}.ui-chip .ui-btn.ui-btn-flat.ui-icon-add::after{-webkit-mask-image:url(images/3_Controllers/tw_chips_icon_add_mtrl.svg);mask-image:url(images/3_Controllers/tw_chips_icon_add_mtrl.svg)}.ui-chip .ui-btn.ui-btn-flat.ui-icon-delete::after{-webkit-mask-image:url(images/3_Controllers/tw_chips_icon_delete_mtrl.svg);mask-image:url(images/3_Controllers/tw_chips_icon_delete_mtrl.svg)}.ui-chips{display:-webkit-flex;display:-ms-flexbox;display:flex;margin:0 20px;row-gap:4px;-webkit-column-gap:7px;column-gap:7px;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-height:114px;overflow-y:auto}.ui-chips .ui-chip{margin-top:4px;max-width:100%}.ui-chips.ui-chips-inline{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;overflow-x:scroll;height:44px}.tau-info-theme:after{content:"default"}
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Light.ttf b/d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Light.ttf
new file mode 100644 (file)
index 0000000..cc55284
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Light.ttf differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Medium.ttf b/d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Medium.ttf
new file mode 100644 (file)
index 0000000..048ad9c
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Medium.ttf differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Regular.ttf b/d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Regular.ttf
new file mode 100644 (file)
index 0000000..51822cd
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/fonts/Roboto-Regular.ttf differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/bottom_left.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/bottom_left.svg
new file mode 100644 (file)
index 0000000..fb76663
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="78px" height="78px" viewBox="0 0 78 78" enable-background="new 0 0 78 78" xml:space="preserve">
+<path d="M0,0c0,43.078,34.921,78,78,78H0L0,0z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/bottom_right.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/bottom_right.svg
new file mode 100644 (file)
index 0000000..3fc6b14
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="78px" height="78px" viewBox="0 0 78 78" enable-background="new 0 0 78 78" xml:space="preserve">
+<path d="M78,0c0,43.078-34.922,78-78,78h78V0z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/top_left.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/top_left.svg
new file mode 100644 (file)
index 0000000..c997dd8
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="78px" height="78px" viewBox="0 0 78 78" enable-background="new 0 0 78 78" xml:space="preserve">
+<path d="M78,0C34.922,0,0,34.922,0,78V0L78,0z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/top_right.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/0_Round_corner/top_right.svg
new file mode 100644 (file)
index 0000000..27265de
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="78px" height="78px" viewBox="0 0 78 78" enable-background="new 0 0 78 78" xml:space="preserve">
+<path d="M0,0c43.078,0,78,34.922,78,78V0H0z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_action_bar_icon_current_location_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_action_bar_icon_current_location_mtrl.svg
new file mode 100644 (file)
index 0000000..380382c
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <path fill="#FFFFFF" d="M59.277,33C57.924,22.452,49.549,14.076,39,12.724V6.75h-6v5.974C22.451,14.076,14.076,22.452,12.723,33
+               H6.75v6h5.973C14.076,49.549,22.451,57.924,33,59.276v5.974h6v-5.974C49.549,57.924,57.924,49.549,59.277,39h5.973v-6H59.277z
+                M36,53.475c-9.636,0-17.476-7.839-17.476-17.475S26.364,18.525,36,18.525S53.476,26.364,53.476,36S45.636,53.475,36,53.475z"/>
+       <path fill="#FFFFFF" d="M36,25.5c-5.796,0-10.5,4.704-10.5,10.5S30.204,46.5,36,46.5S46.5,41.796,46.5,36S41.796,25.5,36,25.5z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_ab_back_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_ab_back_mtrl.svg
new file mode 100644 (file)
index 0000000..d210dad
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <polygon fill="#FFFFFF" points="40.897,61.521 12.748,34.989 40.897,8.453 44.773,12.423 20.843,34.989 44.773,57.549 
+               40.897,61.521   "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_ab_more_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_ab_more_mtrl.svg
new file mode 100644 (file)
index 0000000..774d42f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<ellipse fill="#FFFFFF" cx="36" cy="17.914" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="36.006" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="54.086" rx="6.183" ry="6.086"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_clear_search_api_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_clear_search_api_mtrl.svg
new file mode 100644 (file)
index 0000000..54ea990
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <polygon fill="#FFFFFF" points="54,21.626 50.375,18 36,32.374 21.626,18 18,21.626 32.374,36 18,50.375 21.626,54 36,39.626 
+               50.375,54 54,50.375 39.625,36   "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_voice_search_api_mtrl_alpha.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/10_Search/tw_ic_voice_search_api_mtrl_alpha.svg
new file mode 100644 (file)
index 0000000..23f2dba
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<path fill="#FFFFFF" d="M57.379,34.732l-5.22-0.078c-0.13,8.72-7.209,15.55-16.116,15.55c-9.548,0-16.202-8.176-16.202-15.512
+       h-5.221c0,9.107,7.584,19.174,18.769,20.572v9.988h5.22v-9.969C49.166,54.075,57.22,45.485,57.379,34.732z"/>
+<path fill="#FFFFFF" d="M36,44.958c5.651,0,10.249-4.621,10.249-10.298l0.029-17.612c0-5.68-4.611-10.301-10.278-10.301
+       c-5.667,0-10.278,4.621-10.278,10.301v17.609C25.721,40.337,30.333,44.958,36,44.958z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/13_View_controls/tw_spinner_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/13_View_controls/tw_spinner_mtrl.svg
new file mode 100644 (file)
index 0000000..5e827db
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 68 72"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="17.5 25.5 34.06 46.5 50.5 25.5 17.5 25.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_cursor_handler_bottom.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_cursor_handler_bottom.svg
new file mode 100644 (file)
index 0000000..54eaefd
--- /dev/null
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 27.5"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M10.82,0h.36C12.17,0,22,10.52,22,16.24v.88A10.52,10.52,0,0,1,11.37,27.5h-.74A10.52,10.52,0,0,1,0,17.12v-.88C0,10.52,9.9,0,10.82,0Z"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_cursor_handler_top.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_cursor_handler_top.svg
new file mode 100644 (file)
index 0000000..6889ba3
--- /dev/null
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 22 27.5"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M10.82,27.5h0C9.9,27.5,0,17,0,11.26v-.88A10.52,10.52,0,0,1,10.63,0h.74A10.52,10.52,0,0,1,22,10.38v.88C22,17,12.17,27.5,11.18,27.5Z"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_select_handler_left.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_select_handler_left.svg
new file mode 100644 (file)
index 0000000..e75b116
--- /dev/null
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 23"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M20,0h0l-.58.07-11,2.47A12.06,12.06,0,0,0,3.2,5.18a10.29,10.29,0,0,0-.34,14.58c3.86,4.14-3.83-4.11,0,0a10,10,0,0,0,14.37.28A11.49,11.49,0,0,0,20,14V0Z"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_select_handler_right.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_copypaste_select_handler_right.svg
new file mode 100644 (file)
index 0000000..855cea2
--- /dev/null
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 23"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M0,0V14a11.49,11.49,0,0,0,2.74,6.05,10,10,0,0,0,14.37-.28c3.86-4.14-3.83,4.11,0,0A10.29,10.29,0,0,0,16.8,5.18a12.06,12.06,0,0,0-5.27-2.64L.58.07,0,0Z"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_ic_ab_back_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_ic_ab_back_mtrl.svg
new file mode 100644 (file)
index 0000000..d210dad
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <polygon fill="#FFFFFF" points="40.897,61.521 12.748,34.989 40.897,8.453 44.773,12.423 20.843,34.989 44.773,57.549 
+               40.897,61.521   "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_ic_ab_more_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/17_Copy_paste/tw_ic_ab_more_mtrl.svg
new file mode 100644 (file)
index 0000000..774d42f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<ellipse fill="#FFFFFF" cx="36" cy="17.914" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="36.006" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="54.086" rx="6.183" ry="6.086"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_add_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_add_mtrl.svg
new file mode 100644 (file)
index 0000000..87f9388
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<polygon fill="#FFFFFF" points="62.25,32.625 39.375,32.625 39.375,9.75 32.625,9.75 32.625,32.625 9.75,32.625 9.75,39.375 
+       32.625,39.375 32.625,62.25 39.375,62.25 39.375,39.375 62.25,39.375 "/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_back_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_back_mtrl.svg
new file mode 100644 (file)
index 0000000..d210dad
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<g>
+       <polygon fill="#FFFFFF" points="40.897,61.521 12.748,34.989 40.897,8.453 44.773,12.423 20.843,34.989 44.773,57.549 
+               40.897,61.521   "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_more_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_more_mtrl.svg
new file mode 100644 (file)
index 0000000..774d42f
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<ellipse fill="#FFFFFF" cx="36" cy="17.914" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="36.006" rx="6.183" ry="6.086"/>
+<ellipse fill="#FFFFFF" cx="36" cy="54.086" rx="6.183" ry="6.086"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_search_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_ab_search_mtrl.svg
new file mode 100644 (file)
index 0000000..3efa86a
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<path fill="#FFFFFF" d="M62.387,57.766L49.55,44.93c2.734-3.684,4.355-8.242,4.355-13.171c0-12.211-9.937-22.146-22.149-22.146
+       c-12.21,0-22.144,9.934-22.144,22.146c0,12.212,9.934,22.148,22.144,22.148c4.929,0,9.488-1.62,13.172-4.355l12.837,12.836
+       L62.387,57.766z M16.147,31.758c0-8.607,7.002-15.611,15.609-15.611c8.61,0,15.614,7.003,15.614,15.611
+       c0,8.609-7.004,15.613-15.614,15.613C23.149,47.371,16.147,40.367,16.147,31.758z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_delete_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_delete_mtrl.svg
new file mode 100644 (file)
index 0000000..5aaff06
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<path fill="#FFFFFF" d="M48.584,19.564v-6.375c0-2.274-1.851-4.125-4.125-4.125h-15.75c-2.274,0-4.125,1.851-4.125,4.125v6.375
+       H12.209v5.25h5.98h0.117l2.25,35.25c0,2.486,2.015,4.5,4.5,4.5h23.25c2.484,0,4.5-2.014,4.5-4.5l2.25-35.25h5.902v-5.25H48.584z
+        M29.834,14.314h13.5v5.25h-13.5V14.314z M33.213,55.582h-5.25V28.586h5.25V55.582z M45.205,55.582h-5.25V28.586h5.25V55.582z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_move_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_move_mtrl.svg
new file mode 100644 (file)
index 0000000..eb15bfb
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
+</style>
+<title>Mobile/Light_theme/ICON/01_ACTION_BAR/Bottom_bar_move</title>
+<desc>Created with Sketch.</desc>
+<g id="Mobile_x2F_Light_x5F_theme_x2F_ICON_x2F_01_x5F_ACTION_x5F_BAR_x2F_Bottom_x5F_bar_x5F_move">
+       <polygon id="Fill-1" class="st0" points="41.4,15 37,19.6 49.7,32.8 10.5,32.8 10.5,39.2 49.7,39.2 37,52.4 41.4,57 61.5,36        "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_share_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/1_App_bar/tw_ic_bb_share_mtrl.svg
new file mode 100644 (file)
index 0000000..98aab86
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<path fill="#FFFFFF" d="M50.91,45.764c-2,0-3.834,0.711-5.262,1.896l-16.537-9.773c0.142-0.607,0.226-1.237,0.226-1.887
+       c0-0.65-0.083-1.279-0.226-1.885l16.534-9.776c1.43,1.185,3.264,1.898,5.265,1.898c4.557,0,8.25-3.694,8.25-8.246
+       c0-4.561-3.693-8.254-8.25-8.254c-4.556,0-8.252,3.693-8.252,8.254c0,0.649,0.084,1.276,0.225,1.882L26.35,29.649
+       c-1.428-1.185-3.262-1.897-5.261-1.897c-4.556,0-8.249,3.695-8.249,8.249c0,4.551,3.692,8.252,8.249,8.252
+       c2,0,3.833-0.715,5.262-1.898l16.535,9.771c-0.144,0.607-0.226,1.236-0.226,1.887c0,4.559,3.694,8.252,8.25,8.252
+       s8.25-3.693,8.25-8.252C59.16,49.457,55.466,45.764,50.91,45.764z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/2_Buttons/tw_ic_ab_add_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/2_Buttons/tw_ic_ab_add_mtrl.svg
new file mode 100644 (file)
index 0000000..87f9388
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="72px" height="72px" viewBox="0 0 72 72" enable-background="new 0 0 72 72" xml:space="preserve">
+<polygon fill="#FFFFFF" points="62.25,32.625 39.375,32.625 39.375,9.75 32.625,9.75 32.625,32.625 9.75,32.625 9.75,39.375 
+       32.625,39.375 32.625,62.25 39.375,62.25 39.375,39.375 62.25,39.375 "/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_000.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_000.svg
new file mode 100644 (file)
index 0000000..03db0e3
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_00_1_">
+               <g>
+                       <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3.2
+                               C32.6,3.2,20.2,15.6,20.2,31c0,15.4,12.5,27.8,27.8,27.8c15.4,0,27.8-12.5,27.8-27.8C75.8,15.6,63.4,3.2,48,3.2z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_001.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_001.svg
new file mode 100644 (file)
index 0000000..5ec318d
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:3.000000e-02;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_01_1_">
+               <g id="_x33__x25_" class="st0">
+                       <path class="st1" d="M48,1.5c16.3,0,29.5,13.2,29.5,29.5c0,16.3-13.2,29.5-29.5,29.5S18.5,47.3,18.5,31
+                               C18.5,14.7,31.7,1.5,48,1.5"/>
+               </g>
+               <g>
+                       <path class="st1" d="M48,61.5c-16.8,0-30.5-13.7-30.5-30.5C17.5,14.2,31.2,0.5,48,0.5c16.8,0,30.5,13.7,30.5,30.5
+                               C78.5,47.8,64.8,61.5,48,61.5z M48,3.6C32.9,3.6,20.6,15.9,20.6,31c0,15.1,12.3,27.4,27.4,27.4S75.4,46.1,75.4,31
+                               C75.4,15.9,63.1,3.6,48,3.6z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_002.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_002.svg
new file mode 100644 (file)
index 0000000..ac5f275
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:5.000000e-02;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_02_1_">
+               <path id="_x35__x25_" class="st0" d="M48,2c16,0,29,13,29,29c0,16-13,29-29,29c-16,0-29-13-29-29C19,15,32,2,48,2"/>
+               <path class="st1" d="M48,61c-16.5,0-30-13.5-30-30C18,14.5,31.5,1,48,1s30,13.5,30,30C78,47.5,64.5,61,48,61z M48,4.1
+                       C33.2,4.1,21.1,16.2,21.1,31c0,14.8,12.1,26.9,26.9,26.9S74.9,45.8,74.9,31C74.9,16.2,62.8,4.1,48,4.1z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_003.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_003.svg
new file mode 100644 (file)
index 0000000..4306f53
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.1;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_03_1_">
+               <path id="_x31_0_x25_" class="st0" d="M48,2.5c15.7,0,28.5,12.8,28.5,28.5c0,15.7-12.8,28.5-28.5,28.5
+                       c-15.7,0-28.5-12.8-28.5-28.5C19.5,15.3,32.3,2.5,48,2.5"/>
+               <path class="st1" d="M48,60.5c-16.3,0-29.5-13.2-29.5-29.5C18.5,14.7,31.7,1.5,48,1.5c16.3,0,29.5,13.2,29.5,29.5
+                       C77.5,47.3,64.3,60.5,48,60.5z M48,4.6C33.4,4.6,21.6,16.4,21.6,31c0,14.6,11.8,26.4,26.4,26.4c14.6,0,26.4-11.8,26.4-26.4
+                       C74.4,16.4,62.6,4.6,48,4.6z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_004.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_004.svg
new file mode 100644 (file)
index 0000000..eb0d57a
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.2;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_04_1_">
+               <g id="_x32_0_x25_" class="st0">
+                       <path class="st1" d="M48,3c15.5,0,28,12.5,28,28c0,15.5-12.5,28-28,28S20,46.5,20,31C20,15.5,32.5,3,48,3"/>
+               </g>
+               <path class="st1" d="M48,60c-16,0-29-13-29-29C19,15,32,2,48,2c16,0,29,13,29,29C77,47,64,60,48,60z M48,5.1
+                       C33.7,5.1,22.1,16.7,22.1,31c0,14.3,11.6,25.9,25.9,25.9c14.3,0,25.9-11.6,25.9-25.9C73.9,16.7,62.3,5.1,48,5.1z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_005.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_005.svg
new file mode 100644 (file)
index 0000000..f5eca30
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.5;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_05_1_">
+               <path id="_x35_0_x25_" class="st0" d="M48,3.5c15.2,0,27.5,12.3,27.5,27.5c0,15.2-12.3,27.5-27.5,27.5S20.5,46.2,20.5,31
+                       C20.5,15.8,32.8,3.5,48,3.5"/>
+               <path class="st1" d="M48,59.5c-15.7,0-28.5-12.8-28.5-28.5C19.5,15.3,32.3,2.5,48,2.5S76.5,15.3,76.5,31
+                       C76.5,46.7,63.7,59.5,48,59.5z M48,5.6C34,5.6,22.6,17,22.6,31C22.6,45,34,56.4,48,56.4C62,56.4,73.4,45,73.4,31
+                       C73.4,17,62,5.6,48,5.6z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_006.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_006.svg
new file mode 100644 (file)
index 0000000..e67d418
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.7;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_06_1_">
+               <path id="_x37_0_x25_" class="st0" d="M48,4c14.9,0,27,12.1,27,27c0,14.9-12.1,27-27,27c-14.9,0-27-12.1-27-27
+                       C21,16.1,33.1,4,48,4"/>
+               <path class="st1" d="M48,59c-15.4,0-28-12.6-28-28C20,15.6,32.6,3,48,3s28,12.6,28,28C76,46.4,63.4,59,48,59z M48,6
+                       C34.2,6,23,17.2,23,31c0,13.8,11.2,25,25,25c13.8,0,25-11.2,25-25C73,17.2,61.8,6,48,6z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_007.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_007.svg
new file mode 100644 (file)
index 0000000..282a6b9
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.8;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_07_1_">
+               <path id="_x38_0_x25_" class="st0" d="M48,4.5c14.6,0,26.5,11.9,26.5,26.5c0,14.6-11.9,26.5-26.5,26.5S21.5,45.6,21.5,31
+                       C21.5,16.4,33.4,4.5,48,4.5"/>
+               <path class="st1" d="M48,58.5c-15.2,0-27.5-12.3-27.5-27.5C20.5,15.8,32.8,3.5,48,3.5c15.2,0,27.5,12.3,27.5,27.5
+                       C75.5,46.2,63.2,58.5,48,58.5z M48,6.5c-13.5,0-24.5,11-24.5,24.5c0,13.5,11,24.5,24.5,24.5s24.5-11,24.5-24.5
+                       C72.5,17.5,61.5,6.5,48,6.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_008.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_008.svg
new file mode 100644 (file)
index 0000000..82ed67f
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.9;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_08_1_">
+               <path id="_x39_0_x25_" class="st0" d="M48,5c14.4,0,26,11.6,26,26c0,14.4-11.6,26-26,26c-14.4,0-26-11.6-26-26
+                       C22,16.6,33.6,5,48,5"/>
+               <path class="st1" d="M48,58c-14.9,0-27-12.1-27-27C21,16.1,33.1,4,48,4c14.9,0,27,12.1,27,27C75,45.9,62.9,58,48,58z M48,7
+                       C34.8,7,24,17.8,24,31c0,13.2,10.8,24,24,24s24-10.8,24-24C72,17.8,61.2,7,48,7z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_009.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_009.svg
new file mode 100644 (file)
index 0000000..6bd0d8d
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.95;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_09_1_">
+               <path id="_x39_5" class="st0" d="M48,5c14.4,0,26,11.6,26,26c0,14.4-11.6,26-26,26c-14.4,0-26-11.6-26-26C22,16.6,33.6,5,48,5"/>
+               <path class="st1" d="M48,58c-14.9,0-27-12.1-27-27C21,16.1,33.1,4,48,4c14.9,0,27,12.1,27,27C75,45.9,62.9,58,48,58z M48,7
+                       C34.8,7,24,17.8,24,31c0,13.2,10.8,24,24,24s24-10.8,24-24C72,17.8,61.2,7,48,7z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_010.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_010.svg
new file mode 100644 (file)
index 0000000..36cc669
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_10_1_" fill="#FFFFFF" d="M47.993,4.509c-14.635,0-26.5,11.865-26.5,26.498c0,14.638,11.865,26.502,26.5,26.502
+               c14.636,0,26.501-11.864,26.501-26.502C74.494,16.374,62.629,4.509,47.993,4.509z M41.913,45.359l-9.984-9.873l2.823-2.789
+               l7.161,7.078l15.147-14.979l2.823,2.792L41.913,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_011.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_011.svg
new file mode 100644 (file)
index 0000000..f666e83
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_11_1_" fill="#FFFFFF" d="M48,4C33.089,4,21,16.089,21,30.998C21,45.911,33.089,58,48,58
+               c14.912,0,27-12.089,27-27.002C75,16.089,62.912,4,48,4z M41.917,45.359l-10.073-9.963l2.849-2.813l7.225,7.142l15.283-15.112
+               l2.848,2.817L41.917,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_012.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_012.svg
new file mode 100644 (file)
index 0000000..31d1263
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_12_1_" fill="#FFFFFF" d="M48,3.5c-15.188,0-27.5,12.313-27.5,27.498C20.5,46.188,32.813,58.5,48,58.5
+               c15.188,0,27.5-12.313,27.5-27.502C75.5,15.813,63.188,3.5,48,3.5z M41.91,45.359L31.39,34.956l2.975-2.938l7.544,7.457
+               l15.959-15.782l2.975,2.942L41.91,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_013.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_013.svg
new file mode 100644 (file)
index 0000000..ccc3a28
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_13_1_" fill="#FFFFFF" d="M48,3C32.536,3,20,15.537,20,30.998C20,46.464,32.536,59,48,59s28-12.536,28-28.002
+               C76,15.537,63.464,3,48,3z M41.915,45.359l-11.29-11.166l3.193-3.153l8.097,8.004l17.128-16.937l3.191,3.158L41.915,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_014.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_014.svg
new file mode 100644 (file)
index 0000000..8727436
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_14_1_" fill="#FFFFFF" d="M48,2.5c-15.74,0-28.5,12.76-28.5,28.498C19.5,46.74,32.26,59.5,48,59.5
+               s28.5-12.76,28.5-28.502C76.5,15.26,63.74,2.5,48,2.5z M41.891,45.359L29.552,33.157l3.49-3.448l8.849,8.748l18.72-18.511
+               l3.488,3.451L41.891,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_015.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_015.svg
new file mode 100644 (file)
index 0000000..d9919a1
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_15_1_" fill="#FFFFFF" d="M48,2C31.983,2,19,14.984,19,30.998C19,47.018,31.983,60,48,60
+               c16.018,0,29-12.982,29-29.002C77,14.984,64.018,2,48,2z M41.915,45.359L28.706,32.297l3.736-3.69l9.473,9.364l20.04-19.816
+               l3.734,3.694L41.915,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_016.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_016.svg
new file mode 100644 (file)
index 0000000..be25a6f
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_16_1_" fill="#FFFFFF" d="M48,1.5c-16.293,0-29.5,13.208-29.5,29.498C18.5,47.293,31.707,60.5,48,60.5
+               s29.5-13.207,29.5-29.502C77.5,14.708,64.293,1.5,48,1.5z M41.896,45.359L28.063,31.68l3.913-3.866l9.921,9.808l20.988-20.753
+               l3.912,3.869L41.896,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_017.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_017.svg
new file mode 100644 (file)
index 0000000..7d01500
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_17_1_" fill="#FFFFFF" d="M48,1C31.431,1,18,14.431,18,30.998C18,47.568,31.431,61,48,61
+               c16.568,0,30-13.432,30-30.002C78,14.431,64.568,1,48,1z M41.904,45.359L27.52,31.134l4.068-4.02l10.316,10.198l21.825-21.58
+               l4.066,4.023L41.904,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_018.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_018.svg
new file mode 100644 (file)
index 0000000..8a147a7
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_18_1_" fill="#FFFFFF" d="M48,0.5c-16.846,0-30.5,13.655-30.5,30.498C17.5,47.846,31.154,61.5,48,61.5
+               c16.846,0,30.5-13.654,30.5-30.502C78.5,14.155,64.846,0.5,48,0.5z M41.894,45.359L27.141,30.77l4.172-4.123l10.58,10.46
+               l22.382-22.133l4.172,4.126L41.894,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_019.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_019.svg
new file mode 100644 (file)
index 0000000..5175afc
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_19_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.91,45.359L26.881,30.497l4.25-4.2L41.91,36.953l22.803-22.548l4.25,4.204L41.91,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_020.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_020.svg
new file mode 100644 (file)
index 0000000..978d6ad
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_20_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.91,45.359L26.881,30.497l4.25-4.2L41.91,36.953l22.803-22.548l4.25,4.204L41.91,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_021.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_021.svg
new file mode 100644 (file)
index 0000000..404091f
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_21_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.921,45.359L27.038,30.64l4.209-4.159l10.674,10.553l22.583-22.331l4.209,4.164L41.921,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_022.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_022.svg
new file mode 100644 (file)
index 0000000..d62dcc6
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_22_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.928,45.359L27.1,30.695l4.194-4.144l10.634,10.514l22.498-22.247l4.193,4.148L41.928,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_023.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_023.svg
new file mode 100644 (file)
index 0000000..20fc97b
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_23_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.92,45.359L27.209,30.811L31.37,26.7l10.55,10.431L64.24,15.06l4.16,4.115L41.92,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_024.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_024.svg
new file mode 100644 (file)
index 0000000..efbb5ae
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_24_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.826,45.359L27.209,30.905l4.134-4.084l10.482,10.363L64,15.255l4.134,4.089L41.826,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_025.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_025.svg
new file mode 100644 (file)
index 0000000..fe3399b
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_25_1_" fill="#FFFFFF" d="M48,0C30.878,0,17,13.878,17,30.998C17,48.122,30.878,62,48,62s31-13.878,31-31.002
+               C79,13.878,65.122,0,48,0z M41.913,45.359L27.428,31.035l4.097-4.047l10.388,10.27l21.976-21.731l4.098,4.052L41.913,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_026.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/96x62/sem_checkedtextview_check_to_on_mtrl_026.svg
new file mode 100644 (file)
index 0000000..9ef9ac5
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="62px" viewBox="0 0 96 62" enable-background="new 0 0 96 62" xml:space="preserve">
+<g id="Check">
+       <path id="_x30_26_1_" fill="#FFFFFF" d="M47.999,0C30.879,0,17,13.877,17,31c0,17.124,13.879,31,30.999,31
+               C65.122,62,79,48.124,79,31C79,13.877,65.122,0,47.999,0z M41.905,45.359L27.599,31.214l4.046-4l10.261,10.146l21.704-21.464
+               l4.048,4.001L41.905,45.359z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_000.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_000.svg
new file mode 100644 (file)
index 0000000..7d688ae
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_00_1_">
+               <g>
+                       <path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+                               c-16,0-28,12-28,28c0,16,12,28,28,28c16,0,28-12,28-28C76,32,64,20,48,20z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_001.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_001.svg
new file mode 100644 (file)
index 0000000..5d5fd17
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:3.000000e-02;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_01_1_">
+               <g id="_x33__x25_" class="st0">
+                       <path class="st1" d="M48,18.5c16.3,0,29.5,13.2,29.5,29.5c0,16.3-13.2,29.5-29.5,29.5S18.5,64.3,18.5,48
+                               C18.5,31.7,31.7,18.5,48,18.5"/>
+               </g>
+               <g>
+                       <path class="st1" d="M48,78.5c-16.8,0-30.5-13.7-30.5-30.5c0-16.8,13.7-30.5,30.5-30.5c16.8,0,30.5,13.7,30.5,30.5
+                               C78.5,64.8,64.8,78.5,48,78.5z M48,20.5c-15.7,0-27.5,11.8-27.5,27.5c0,15.7,11.8,27.5,27.5,27.5S75.5,63.7,75.5,48
+                               C75.5,32.3,63.7,20.5,48,20.5z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_002.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_002.svg
new file mode 100644 (file)
index 0000000..e658ca0
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:5.000000e-02;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_02_1_">
+               <path id="_x35__x25_" class="st0" d="M48,19c16,0,29,13,29,29c0,16-13,29-29,29c-16,0-29-13-29-29C19,32,32,19,48,19"/>
+               <path class="st1" d="M48,78c-16.5,0-30-13.5-30-30c0-16.5,13.5-30,30-30s30,13.5,30,30C78,64.5,64.5,78,48,78z M48,21
+                       c-15.4,0-27,11.6-27,27c0,15.4,11.6,27,27,27s27-11.6,27-27C75,32.6,63.4,21,48,21z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_003.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_003.svg
new file mode 100644 (file)
index 0000000..df31ec1
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.1;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_03_1_">
+               <path id="_x31_0_x25_" class="st0" d="M48,19.5c15.7,0,28.5,12.8,28.5,28.5c0,15.7-12.8,28.5-28.5,28.5
+                       c-15.7,0-28.5-12.8-28.5-28.5C19.5,32.3,32.3,19.5,48,19.5"/>
+               <path class="st1" d="M48,77.5c-16.3,0-29.5-13.2-29.5-29.5c0-16.3,13.2-29.5,29.5-29.5c16.3,0,29.5,13.2,29.5,29.5
+                       C77.5,64.3,64.3,77.5,48,77.5z M48,21.5c-15.2,0-26.5,11.3-26.5,26.5c0,15.2,11.3,26.5,26.5,26.5c15.2,0,26.5-11.3,26.5-26.5
+                       C74.5,32.8,63.2,21.5,48,21.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_004.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_004.svg
new file mode 100644 (file)
index 0000000..5ccb9bf
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.2;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_04_1_">
+               <g id="_x32_0_x25_" class="st0">
+                       <path class="st1" d="M48,20c15.5,0,28,12.5,28,28c0,15.5-12.5,28-28,28S20,63.5,20,48C20,32.5,32.5,20,48,20"/>
+               </g>
+               <path class="st1" d="M48,77c-16,0-29-13-29-29c0-16,13-29,29-29c16,0,29,13,29,29C77,64,64,77,48,77z M48,22
+                       c-14.9,0-26,11.1-26,26c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,33.1,62.9,22,48,22z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_005.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_005.svg
new file mode 100644 (file)
index 0000000..0fb4b8e
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.5;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_05_1_">
+               <path id="_x35_0_x25_" class="st0" d="M48,20.5c15.2,0,27.5,12.3,27.5,27.5c0,15.2-12.3,27.5-27.5,27.5S20.5,63.2,20.5,48
+                       C20.5,32.8,32.8,20.5,48,20.5"/>
+               <path class="st1" d="M48,76.5c-15.7,0-28.5-12.8-28.5-28.5c0-15.7,12.8-28.5,28.5-28.5S76.5,32.3,76.5,48
+                       C76.5,63.7,63.7,76.5,48,76.5z M48,22.5c-14.6,0-25.5,10.9-25.5,25.5c0,14.6,10.9,25.5,25.5,25.5c14.6,0,25.5-10.9,25.5-25.5
+                       C73.5,33.4,62.6,22.5,48,22.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_006.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_006.svg
new file mode 100644 (file)
index 0000000..a8538b8
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.7;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_06_1_">
+               <path id="_x37_0_x25_" class="st0" d="M48,21c14.9,0,27,12.1,27,27c0,14.9-12.1,27-27,27c-14.9,0-27-12.1-27-27
+                       C21,33.1,33.1,21,48,21"/>
+               <path class="st1" d="M48,76c-15.4,0-28-12.6-28-28c0-15.4,12.6-28,28-28s28,12.6,28,28C76,63.4,63.4,76,48,76z M48,23
+                       c-14.3,0-25,10.7-25,25c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,33.7,62.3,23,48,23z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_007.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_007.svg
new file mode 100644 (file)
index 0000000..fecdcbd
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.8;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_07_1_">
+               <path id="_x38_0_x25_" class="st0" d="M48,21.5c14.6,0,26.5,11.9,26.5,26.5c0,14.6-11.9,26.5-26.5,26.5S21.5,62.6,21.5,48
+                       C21.5,33.4,33.4,21.5,48,21.5"/>
+               <path class="st1" d="M48,75.5c-15.2,0-27.5-12.3-27.5-27.5c0-15.2,12.3-27.5,27.5-27.5c15.2,0,27.5,12.3,27.5,27.5
+                       C75.5,63.2,63.2,75.5,48,75.5z M48,23.5c-14.1,0-24.5,10.4-24.5,24.5c0,14.1,10.4,24.5,24.5,24.5S72.5,62.1,72.5,48
+                       C72.5,33.9,62.1,23.5,48,23.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_008.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_008.svg
new file mode 100644 (file)
index 0000000..eace498
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.9;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_08_1_">
+               <path id="_x39_0_x25_" class="st0" d="M48,22c14.4,0,26,11.6,26,26c0,14.4-11.6,26-26,26c-14.4,0-26-11.6-26-26
+                       C22,33.6,33.6,22,48,22"/>
+               <path class="st1" d="M48,75c-14.9,0-27-12.1-27-27c0-14.9,12.1-27,27-27c14.9,0,27,12.1,27,27C75,62.9,62.9,75,48,75z M48,24
+                       c-13.8,0-24,10.2-24,24c0,13.8,10.2,24,24,24s24-10.2,24-24C72,34.2,61.8,24,48,24z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_009.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_009.svg
new file mode 100644 (file)
index 0000000..03c14bc
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{opacity:0.95;fill:#FFFFFF;enable-background:new    ;}
+       .st1{fill:#FFFFFF;}
+</style>
+<g id="Check">
+       <g id="_x30_09_1_">
+               <path id="_x39_5" class="st0" d="M48,22c14.4,0,26,11.6,26,26c0,14.4-11.6,26-26,26c-14.4,0-26-11.6-26-26C22,33.6,33.6,22,48,22"
+                       />
+               <path class="st1" d="M48,75c-14.9,0-27-12.1-27-27c0-14.9,12.1-27,27-27c14.9,0,27,12.1,27,27C75,62.9,62.9,75,48,75z M48,24
+                       c-13.8,0-24,10.2-24,24c0,13.8,10.2,24,24,24s24-10.2,24-24C72,34.2,61.8,24,48,24z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_010.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_010.svg
new file mode 100644 (file)
index 0000000..aa0b9e2
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_10" fill="#FFFFFF" d="M47.993,21.509c-14.635,0-26.5,11.865-26.5,26.498c0,14.638,11.865,26.502,26.5,26.502\r
+               c14.636,0,26.501-11.864,26.501-26.502C74.494,33.374,62.629,21.509,47.993,21.509z M41.913,62.359l-9.984-9.873l2.823-2.789\r
+               l7.161,7.078l15.147-14.979l2.823,2.792L41.913,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_011.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_011.svg
new file mode 100644 (file)
index 0000000..e8b7c80
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_11_1_" fill="#FFFFFF" d="M48,21c-14.911,0-27,12.089-27,26.998C21,62.911,33.089,75,48,75\r
+               c14.912,0,27-12.089,27-27.002C75,33.089,62.912,21,48,21z M41.917,62.359l-10.073-9.963l2.849-2.813l7.225,7.142l15.283-15.112\r
+               l2.848,2.817L41.917,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_012.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_012.svg
new file mode 100644 (file)
index 0000000..ed480b3
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_12" fill="#FFFFFF" d="M48,20.5c-15.188,0-27.5,12.313-27.5,27.498C20.5,63.188,32.813,75.5,48,75.5\r
+               c15.188,0,27.5-12.313,27.5-27.502C75.5,32.813,63.188,20.5,48,20.5z M41.91,62.359L31.39,51.956l2.975-2.938l7.544,7.457\r
+               l15.959-15.782l2.975,2.942L41.91,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_013.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_013.svg
new file mode 100644 (file)
index 0000000..b90d769
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_13" fill="#FFFFFF" d="M48,20c-15.464,0-28,12.537-28,27.998C20,63.464,32.536,76,48,76s28-12.536,28-28.002\r
+               C76,32.537,63.464,20,48,20z M41.915,62.359l-11.29-11.166l3.193-3.153l8.097,8.004l17.128-16.937l3.191,3.158L41.915,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_014.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_014.svg
new file mode 100644 (file)
index 0000000..1a9c783
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_14" fill="#FFFFFF" d="M48,19.5c-15.74,0-28.5,12.76-28.5,28.498C19.5,63.74,32.26,76.5,48,76.5\r
+               s28.5-12.76,28.5-28.502C76.5,32.26,63.74,19.5,48,19.5z M41.891,62.359L29.552,50.157l3.49-3.448l8.849,8.748l18.72-18.511\r
+               l3.488,3.451L41.891,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_015.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_015.svg
new file mode 100644 (file)
index 0000000..9313e40
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_15_1_" fill="#FFFFFF" d="M48,19c-16.017,0-29,12.984-29,28.998C19,64.018,31.983,77,48,77\r
+               c16.018,0,29-12.982,29-29.002C77,31.984,64.018,19,48,19z M41.915,62.359L28.706,49.297l3.736-3.69l9.473,9.364l20.04-19.816\r
+               l3.734,3.694L41.915,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_016.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_016.svg
new file mode 100644 (file)
index 0000000..3c1f955
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_16" fill="#FFFFFF" d="M48,18.5c-16.293,0-29.5,13.208-29.5,29.498C18.5,64.293,31.707,77.5,48,77.5\r
+               s29.5-13.207,29.5-29.502C77.5,31.708,64.293,18.5,48,18.5z M41.896,62.359L28.063,48.68l3.913-3.866l9.921,9.808l20.988-20.753\r
+               l3.912,3.869L41.896,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_017.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_017.svg
new file mode 100644 (file)
index 0000000..4b4e9ca
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_17" fill="#FFFFFF" d="M48,18c-16.569,0-30,13.431-30,29.998C18,64.568,31.431,78,48,78\r
+               c16.568,0,30-13.432,30-30.002C78,31.431,64.568,18,48,18z M41.904,62.359L27.52,48.134l4.068-4.02l10.316,10.198l21.825-21.58\r
+               l4.066,4.023L41.904,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_018.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_018.svg
new file mode 100644 (file)
index 0000000..df93745
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_18_1_" fill="#FFFFFF" d="M48,17.5c-16.846,0-30.5,13.655-30.5,30.498C17.5,64.846,31.154,78.5,48,78.5\r
+               c16.846,0,30.5-13.654,30.5-30.502C78.5,31.155,64.846,17.5,48,17.5z M41.894,62.359L27.141,47.77l4.172-4.123l10.58,10.46\r
+               l22.382-22.133l4.172,4.126L41.894,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_019.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_019.svg
new file mode 100644 (file)
index 0000000..fbc7eb2
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_19_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.91,62.359L26.881,47.497l4.25-4.2L41.91,53.953l22.803-22.548l4.25,4.204L41.91,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_020.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_020.svg
new file mode 100644 (file)
index 0000000..976d946
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_20" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.91,62.359L26.881,47.497l4.25-4.2L41.91,53.953l22.803-22.548l4.25,4.204L41.91,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_021.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_021.svg
new file mode 100644 (file)
index 0000000..fc607e3
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_21_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.921,62.359L27.038,47.64l4.209-4.159l10.674,10.553l22.583-22.331l4.209,4.164L41.921,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_022.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_022.svg
new file mode 100644 (file)
index 0000000..fbd72a8
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_22_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.928,62.359L27.1,47.695l4.194-4.144l10.634,10.514l22.498-22.247l4.193,4.148L41.928,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_023.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_023.svg
new file mode 100644 (file)
index 0000000..6ee1043
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_23_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.92,62.359L27.209,47.811L31.37,43.7l10.55,10.431L64.24,32.06l4.16,4.115L41.92,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_024.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_024.svg
new file mode 100644 (file)
index 0000000..2635d45
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_24_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.826,62.359L27.209,47.905l4.134-4.084l10.482,10.363L64,32.255l4.134,4.089L41.826,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_025.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_025.svg
new file mode 100644 (file)
index 0000000..fd48538
--- /dev/null
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_25_1_" fill="#FFFFFF" d="M48,17c-17.122,0-31,13.878-31,30.998C17,65.122,30.878,79,48,79s31-13.878,31-31.002\r
+               C79,30.878,65.122,17,48,17z M41.913,62.359L27.428,48.035l4.097-4.047l10.388,10.27l21.976-21.731l4.098,4.052L41.913,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_026.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sem_checkedtextview_check_to_on_mtrl_026.svg
new file mode 100644 (file)
index 0000000..b07bf29
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<g id="Check">\r
+       <path id="_x30_26_1_" fill="#FFFFFF" d="M47.999,17C30.879,17,17,30.877,17,48c0,17.124,13.879,31,30.999,31\r
+               C65.122,79,79,65.124,79,48C79,30.877,65.122,17,47.999,17z M41.905,62.359L27.599,48.214l4.046-4l10.261,10.146l21.704-21.464\r
+               l4.048,4.001L41.905,62.359z"/>\r
+</g>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg
new file mode 100644 (file)
index 0000000..89366d8
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="2592" height="96" viewBox="0 0 2592 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_000" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Check"><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-16 0-28 12-28 28s12 28 28 28 28-12 28-28-12-28-28-28z" id="_x30_00_1_"/></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_001" x="96" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:3.000000e-02}.st1{fill:#fff}</style><g id="Check"><g id="_x30_01_1_"><g id="_x33__x25_" class="st0"><path class="st1" d="M48 18.5c16.3 0 29.5 13.2 29.5 29.5S64.3 77.5 48 77.5 18.5 64.3 18.5 48 31.7 18.5 48 18.5"/></g><path class="st1" d="M48 78.5c-16.8 0-30.5-13.7-30.5-30.5S31.2 17.5 48 17.5 78.5 31.2 78.5 48 64.8 78.5 48 78.5zm0-58c-15.7 0-27.5 11.8-27.5 27.5S32.3 75.5 48 75.5 75.5 63.7 75.5 48 63.7 20.5 48 20.5z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_002" x="192" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:5.000000e-02;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_02_1_"><path id="_x35__x25_" class="st0" d="M48 19c16 0 29 13 29 29S64 77 48 77 19 64 19 48s13-29 29-29"/><path class="st1" d="M48 78c-16.5 0-30-13.5-30-30s13.5-30 30-30 30 13.5 30 30-13.5 30-30 30zm0-57c-15.4 0-27 11.6-27 27s11.6 27 27 27 27-11.6 27-27-11.6-27-27-27z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_003" x="288" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.1;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_03_1_"><path id="_x31_0_x25_" class="st0" d="M48 19.5c15.7 0 28.5 12.8 28.5 28.5S63.7 76.5 48 76.5 19.5 63.7 19.5 48 32.3 19.5 48 19.5"/><path class="st1" d="M48 77.5c-16.3 0-29.5-13.2-29.5-29.5S31.7 18.5 48 18.5 77.5 31.7 77.5 48 64.3 77.5 48 77.5zm0-56c-15.2 0-26.5 11.3-26.5 26.5S32.8 74.5 48 74.5 74.5 63.2 74.5 48 63.2 21.5 48 21.5z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_004" x="384" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.2}.st1{fill:#fff}</style><g id="Check"><g id="_x30_04_1_"><g id="_x32_0_x25_" class="st0"><path class="st1" d="M48 20c15.5 0 28 12.5 28 28S63.5 76 48 76 20 63.5 20 48s12.5-28 28-28"/></g><path class="st1" d="M48 77c-16 0-29-13-29-29s13-29 29-29 29 13 29 29-13 29-29 29zm0-55c-14.9 0-26 11.1-26 26s11.1 26 26 26 26-11.1 26-26-11.1-26-26-26z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_005" x="480" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.5;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_05_1_"><path id="_x35_0_x25_" class="st0" d="M48 20.5c15.2 0 27.5 12.3 27.5 27.5S63.2 75.5 48 75.5 20.5 63.2 20.5 48 32.8 20.5 48 20.5"/><path class="st1" d="M48 76.5c-15.7 0-28.5-12.8-28.5-28.5S32.3 19.5 48 19.5 76.5 32.3 76.5 48 63.7 76.5 48 76.5zm0-54c-14.6 0-25.5 10.9-25.5 25.5S33.4 73.5 48 73.5 73.5 62.6 73.5 48 62.6 22.5 48 22.5z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_006" x="576" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.7;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_06_1_"><path id="_x37_0_x25_" class="st0" d="M48 21c14.9 0 27 12.1 27 27S62.9 75 48 75 21 62.9 21 48s12.1-27 27-27"/><path class="st1" d="M48 76c-15.4 0-28-12.6-28-28s12.6-28 28-28 28 12.6 28 28-12.6 28-28 28zm0-53c-14.3 0-25 10.7-25 25s10.7 25 25 25 25-10.7 25-25-10.7-25-25-25z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_007" x="672" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.8;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_07_1_"><path id="_x38_0_x25_" class="st0" d="M48 21.5c14.6 0 26.5 11.9 26.5 26.5S62.6 74.5 48 74.5 21.5 62.6 21.5 48 33.4 21.5 48 21.5"/><path class="st1" d="M48 75.5c-15.2 0-27.5-12.3-27.5-27.5S32.8 20.5 48 20.5 75.5 32.8 75.5 48 63.2 75.5 48 75.5zm0-52c-14.1 0-24.5 10.4-24.5 24.5S33.9 72.5 48 72.5 72.5 62.1 72.5 48 62.1 23.5 48 23.5z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_008" x="768" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.9;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_08_1_"><path id="_x39_0_x25_" class="st0" d="M48 22c14.4 0 26 11.6 26 26S62.4 74 48 74 22 62.4 22 48s11.6-26 26-26"/><path class="st1" d="M48 75c-14.9 0-27-12.1-27-27s12.1-27 27-27 27 12.1 27 27-12.1 27-27 27zm0-51c-13.8 0-24 10.2-24 24s10.2 24 24 24 24-10.2 24-24-10.2-24-24-24z"/></g></g></svg><svg version="1.1" id="icon_sem_checkedtextview_check_to_on_mtrl_009" x="864" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{opacity:.95;enable-background:new}.st0,.st1{fill:#fff}</style><g id="Check"><g id="_x30_09_1_"><path id="_x39_5" class="st0" d="M48 22c14.4 0 26 11.6 26 26S62.4 74 48 74 22 62.4 22 48s11.6-26 26-26"/><path class="st1" d="M48 75c-14.9 0-27-12.1-27-27s12.1-27 27-27 27 12.1 27 27-12.1 27-27 27zm0-51c-13.8 0-24 10.2-24 24s10.2 24 24 24 24-10.2 24-24-10.2-24-24-24z"/></g></g></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_010" x="960" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M47.993 21.509c-14.635 0-26.5 11.865-26.5 26.498 0 14.638 11.865 26.502 26.5 26.502 14.636 0 26.501-11.864 26.501-26.502 0-14.633-11.865-26.498-26.501-26.498zm-6.08 40.85l-9.984-9.873 2.823-2.789 7.161 7.078L57.06 41.796l2.823 2.792-17.97 17.771z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_011" x="1056" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 21c-14.911 0-27 12.089-27 26.998C21 62.911 33.089 75 48 75c14.912 0 27-12.089 27-27.002C75 33.089 62.912 21 48 21zm-6.083 41.359l-10.073-9.963 2.849-2.813 7.225 7.142 15.283-15.112 2.848 2.817-18.132 17.929z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_012" x="1152" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 20.5c-15.188 0-27.5 12.313-27.5 27.498C20.5 63.188 32.813 75.5 48 75.5c15.188 0 27.5-12.313 27.5-27.502C75.5 32.813 63.188 20.5 48 20.5zm-6.09 41.859L31.39 51.956l2.975-2.938 7.544 7.457 15.959-15.782 2.975 2.942L41.91 62.359z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_013" x="1248" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 20c-15.464 0-28 12.537-28 27.998C20 63.464 32.536 76 48 76s28-12.536 28-28.002C76 32.537 63.464 20 48 20zm-6.085 42.359l-11.29-11.166 3.193-3.153 8.097 8.004 17.128-16.937 3.191 3.158-20.319 20.094z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_014" x="1344" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 19.5c-15.74 0-28.5 12.76-28.5 28.498C19.5 63.74 32.26 76.5 48 76.5s28.5-12.76 28.5-28.502C76.5 32.26 63.74 19.5 48 19.5zm-6.109 42.859L29.552 50.157l3.49-3.448 8.849 8.748 18.72-18.511 3.488 3.451-22.208 21.962z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_015" x="1440" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 19c-16.017 0-29 12.984-29 28.998C19 64.018 31.983 77 48 77c16.018 0 29-12.982 29-29.002C77 31.984 64.018 19 48 19zm-6.085 43.359L28.706 49.297l3.736-3.69 9.473 9.364 20.04-19.816 3.734 3.694-23.774 23.51z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_016" x="1536" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 18.5c-16.293 0-29.5 13.208-29.5 29.498C18.5 64.293 31.707 77.5 48 77.5s29.5-13.207 29.5-29.502C77.5 31.708 64.293 18.5 48 18.5zm-6.104 43.859L28.063 48.68l3.913-3.866 9.921 9.808 20.988-20.753 3.912 3.869-24.901 24.621z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_017" x="1632" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 18c-16.569 0-30 13.431-30 29.998C18 64.568 31.431 78 48 78c16.568 0 30-13.432 30-30.002C78 31.431 64.568 18 48 18zm-6.096 44.359L27.52 48.134l4.068-4.02 10.316 10.198 21.825-21.58 4.066 4.023-25.891 25.604z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_018" x="1728" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17.5c-16.846 0-30.5 13.655-30.5 30.498C17.5 64.846 31.154 78.5 48 78.5s30.5-13.654 30.5-30.502C78.5 31.155 64.846 17.5 48 17.5zm-6.106 44.859L27.141 47.77l4.172-4.123 10.58 10.46 22.382-22.133 4.172 4.126-26.553 26.259z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_019" x="1824" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.09 45.359L26.881 47.497l4.25-4.2L41.91 53.953l22.803-22.548 4.25 4.204-27.053 26.75z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_020" x="1920" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.09 45.359L26.881 47.497l4.25-4.2L41.91 53.953l22.803-22.548 4.25 4.204-27.053 26.75z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_021" x="2016" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.079 45.359L27.038 47.64l4.209-4.159 10.674 10.553 22.583-22.331 4.209 4.164-26.792 26.492z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_022" x="2112" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.072 45.359L27.1 47.695l4.194-4.144 10.634 10.514 22.498-22.247 4.193 4.148-26.691 26.393z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_023" x="2208" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.08 45.359L27.209 47.811 31.37 43.7l10.55 10.431L64.24 32.06l4.16 4.115-26.48 26.184z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_024" x="2304" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.174 45.359L27.209 47.905l4.134-4.084 10.482 10.363L64 32.255l4.134 4.089-26.308 26.015z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_025" x="2400" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M48 17c-17.122 0-31 13.878-31 30.998C17 65.122 30.878 79 48 79s31-13.878 31-31.002C79 30.878 65.122 17 48 17zm-6.087 45.359L27.428 48.035l4.097-4.047 10.388 10.27 21.976-21.731 4.098 4.052-26.074 25.78z"/></svg><svg width="96" height="96" viewBox="0 0 96 96" id="icon_sem_checkedtextview_check_to_on_mtrl_026" x="2496" xmlns="http://www.w3.org/2000/svg"><path fill="#FFF" d="M47.999 17C30.879 17 17 30.877 17 48c0 17.124 13.879 31 30.999 31C65.122 79 79 65.124 79 48c0-17.123-13.878-31-31.001-31zm-6.094 45.359L27.599 48.214l4.046-4L41.906 54.36 63.61 32.896l4.048 4.001-25.753 25.462z"/></svg></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_000.svg
new file mode 100644 (file)
index 0000000..fdea996
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_00" class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z
+                M48,3C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_001.svg
new file mode 100644 (file)
index 0000000..2393785
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_01" class="st0" d="M48,61c-16.5,0-30-13.5-30-30C18,14.5,31.5,1,48,1s30,13.5,30,30C78,47.5,64.5,61,48,61z M48,4
+               C32.6,4,21,15.6,21,31c0,15.4,11.6,27,27,27s27-11.6,27-27C75,15.6,63.4,4,48,4z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_002.svg
new file mode 100644 (file)
index 0000000..1769f8b
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_02" class="st0" d="M48,60c-16,0-29-13-29-29C19,15,32,2,48,2c16,0,29,13,29,29C77,47,64,60,48,60z M48,5
+               C33.1,5,22,16.1,22,31c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,16.1,62.9,5,48,5z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_003.svg
new file mode 100644 (file)
index 0000000..546fb5a
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_03" class="st0" d="M48,59c-15.4,0-28-12.6-28-28C20,15.6,32.6,3,48,3s28,12.6,28,28C76,46.4,63.4,59,48,59z M48,6
+               C33.7,6,23,16.7,23,31c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,16.7,62.3,6,48,6z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_004.svg
new file mode 100644 (file)
index 0000000..0be12f5
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_04" class="st0" d="M48,58c-14.9,0-27-12.1-27-27C21,16.1,33.1,4,48,4c14.9,0,27,12.1,27,27C75,45.9,62.9,58,48,58z
+                M48,7C34.2,7,24,17.2,24,31c0,13.8,10.2,24,24,24s24-10.2,24-24C72,17.2,61.8,7,48,7z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_005.svg
new file mode 100644 (file)
index 0000000..9ffc0fc
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_05" class="st0" d="M48,57c-14.3,0-26-11.7-26-26C22,16.7,33.7,5,48,5c14.3,0,26,11.7,26,26C74,45.3,62.3,57,48,57z
+                M48,8c-13.2,0-23,9.8-23,23c0,13.2,9.8,23,23,23c13.2,0,23-9.8,23-23C71,17.8,61.2,8,48,8z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_006.svg
new file mode 100644 (file)
index 0000000..a827265
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_06" class="st0" d="M48,57c-14.3,0-26-11.7-26-26C22,16.7,33.7,5,48,5c14.3,0,26,11.7,26,26C74,45.3,62.3,57,48,57z
+                M48,8c-13.2,0-23,9.8-23,23c0,13.2,9.8,23,23,23c13.2,0,23-9.8,23-23C71,17.8,61.2,8,48,8z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_007.svg
new file mode 100644 (file)
index 0000000..6fb4af1
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_07_2_">
+               <path class="st0" d="M48,57.5c-14.6,0-26.5-11.9-26.5-26.5C21.5,16.4,33.4,4.5,48,4.5c14.6,0,26.5,11.9,26.5,26.5
+                       C74.5,45.6,62.6,57.5,48,57.5z M48,7.5c-13.5,0-23.5,10-23.5,23.5c0,13.5,10,23.5,23.5,23.5c13.5,0,23.5-10,23.5-23.5
+                       C71.5,17.5,61.5,7.5,48,7.5z"/>
+               <circle class="st0" cx="48" cy="31" r="2"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_008.svg
new file mode 100644 (file)
index 0000000..634997b
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_08">
+               <path class="st0" d="M48,58c-14.9,0-27-12.1-27-27C21,16.1,33.1,4,48,4c14.9,0,27,12.1,27,27C75,45.9,62.9,58,48,58z M48,7
+                       C34.2,7,24,17.2,24,31c0,13.8,10.2,24,24,24s24-10.2,24-24C72,17.2,61.8,7,48,7z"/>
+               <circle class="st0" cx="48" cy="31" r="4"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_009.svg
new file mode 100644 (file)
index 0000000..7842a47
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_09">
+               <path class="st0" d="M48,58.5c-15.2,0-27.5-12.3-27.5-27.5C20.5,15.8,32.8,3.5,48,3.5c15.2,0,27.5,12.3,27.5,27.5
+                       C75.5,46.2,63.2,58.5,48,58.5z M48,6.5C33.9,6.5,23.5,16.9,23.5,31c0,14.1,10.4,24.5,24.5,24.5S72.5,45.1,72.5,31
+                       C72.5,16.9,62.1,6.5,48,6.5z"/>
+               <circle class="st0" cx="48" cy="31" r="6"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_010.svg
new file mode 100644 (file)
index 0000000..dff1c33
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_10">
+               <path class="st0" d="M48,59c-15.4,0-28-12.6-28-28C20,15.6,32.6,3,48,3s28,12.6,28,28C76,46.4,63.4,59,48,59z M48,6
+                       C33.7,6,23,16.7,23,31c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,16.7,62.3,6,48,6z"/>
+               <circle class="st0" cx="48" cy="31" r="8"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_011.svg
new file mode 100644 (file)
index 0000000..cf9e55e
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_11">
+               <path class="st0" d="M48,59.5c-15.7,0-28.5-12.8-28.5-28.5C19.5,15.3,32.3,2.5,48,2.5S76.5,15.3,76.5,31
+                       C76.5,46.7,63.7,59.5,48,59.5z M48,5.5C33.4,5.5,22.5,16.4,22.5,31c0,14.6,10.9,25.5,25.5,25.5c14.6,0,25.5-10.9,25.5-25.5
+                       C73.5,16.4,62.6,5.5,48,5.5z"/>
+               <circle class="st0" cx="48" cy="31" r="10"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_012.svg
new file mode 100644 (file)
index 0000000..59ce2b1
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_12">
+               <path class="st0" d="M48,60c-16,0-29-13-29-29C19,15,32,2,48,2c16,0,29,13,29,29C77,47,64,60,48,60z M48,5C33.1,5,22,16.1,22,31
+                       c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,16.1,62.9,5,48,5z"/>
+               <path class="st0" d="M60,31c0,6.6-5.4,12-12,12c-6.6,0-12-5.4-12-12c0-6.6,5.4-12,12-12C54.6,19,60,24.4,60,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_013.svg
new file mode 100644 (file)
index 0000000..c5edb25
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_13">
+               <path class="st0" d="M48,60.5c-16.3,0-29.5-13.2-29.5-29.5C18.5,14.7,31.7,1.5,48,1.5c16.3,0,29.5,13.2,29.5,29.5
+                       C77.5,47.3,64.3,60.5,48,60.5z M48,4.5C32.8,4.5,21.5,15.8,21.5,31c0,15.2,11.3,26.5,26.5,26.5c15.2,0,26.5-11.3,26.5-26.5
+                       C74.5,15.8,63.2,4.5,48,4.5z"/>
+               <path class="st0" d="M62,31c0,7.7-6.3,14-14,14c-7.7,0-14-6.3-14-14s6.3-14,14-14C55.7,17,62,23.3,62,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_014.svg
new file mode 100644 (file)
index 0000000..a4376fb
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_14">
+               <path class="st0" d="M48,61c-16.5,0-30-13.5-30-30C18,14.5,31.5,1,48,1s30,13.5,30,30C78,47.5,64.5,61,48,61z M48,4
+                       C32.6,4,21,15.6,21,31c0,15.4,11.6,27,27,27s27-11.6,27-27C75,15.6,63.4,4,48,4z"/>
+               <path class="st0" d="M64,31c0,8.8-7.2,16-16,16c-8.8,0-16-7.2-16-16c0-8.8,7.2-16,16-16C56.8,15,64,22.2,64,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_015.svg
new file mode 100644 (file)
index 0000000..5e5d247
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_15">
+               <path class="st0" d="M48,61.5c-16.8,0-30.5-13.7-30.5-30.5C17.5,14.2,31.2,0.5,48,0.5c16.8,0,30.5,13.7,30.5,30.5
+                       C78.5,47.8,64.8,61.5,48,61.5z M48,3.5C32.3,3.5,20.5,15.3,20.5,31c0,15.7,11.8,27.5,27.5,27.5S75.5,46.7,75.5,31
+                       C75.5,15.3,63.7,3.5,48,3.5z"/>
+               <path class="st0" d="M66,31c0,9.9-8.1,18-18,18c-9.9,0-18-8.1-18-18c0-9.9,8.1-18,18-18C57.9,13,66,21.1,66,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_016.svg
new file mode 100644 (file)
index 0000000..24edcda
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_16">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M68,31c0,11-9,20-20,20c-11.1,0-20-9-20-20c0-11,8.9-20,20-20C59,11,68,20,68,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_017.svg
new file mode 100644 (file)
index 0000000..7277061
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_17">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M67.6,31c0,10.8-8.8,19.6-19.6,19.6c-10.8,0-19.6-8.8-19.6-19.6c0-10.8,8.8-19.6,19.6-19.6
+                       C58.8,11.4,67.6,20.2,67.6,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_018.svg
new file mode 100644 (file)
index 0000000..5678539
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_18">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M67.2,31c0,10.6-8.6,19.2-19.2,19.2c-10.6,0-19.2-8.6-19.2-19.2c0-10.6,8.6-19.2,19.2-19.2
+                       C58.6,11.7,67.2,20.4,67.2,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_019.svg
new file mode 100644 (file)
index 0000000..2da187b
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_19">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M66.9,31c0,10.4-8.4,18.9-18.9,18.9c-10.4,0-18.9-8.4-18.9-18.9c0-10.4,8.4-18.9,18.9-18.9
+                       C58.4,12.1,66.9,20.6,66.9,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_020.svg
new file mode 100644 (file)
index 0000000..3751068
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_20">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M66.5,31c0,10.2-8.3,18.5-18.5,18.5c-10.2,0-18.5-8.3-18.5-18.5c0-10.2,8.3-18.5,18.5-18.5
+                       C58.2,12.5,66.5,20.8,66.5,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_021.svg
new file mode 100644 (file)
index 0000000..8f4f548
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_21">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M66.1,31c0,10-8.1,18.1-18.1,18.1C38,49.1,29.9,41,29.9,31c0-10,8.1-18.1,18.1-18.1C58,12.9,66.1,21,66.1,31z
+                       "/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_022.svg
new file mode 100644 (file)
index 0000000..eabda7c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_22">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32.6,3,20,15.6,20,31c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,15.6,63.4,3,48,3z"/>
+               <path class="st0" d="M65.7,31c0,9.8-7.9,17.8-17.8,17.8c-9.8,0-17.8-7.9-17.8-17.8c0-9.8,7.9-17.8,17.8-17.8
+                       C57.8,13.2,65.7,21.2,65.7,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_023.svg
new file mode 100644 (file)
index 0000000..bdd327c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_23">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32.6,3,20,15.6,20,31c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,15.6,63.4,3,48,3z"/>
+               <path class="st0" d="M65.4,31c0,9.6-7.8,17.4-17.4,17.4c-9.6,0-17.4-7.8-17.4-17.4c0-9.6,7.8-17.4,17.4-17.4
+                       C57.6,13.6,65.4,21.4,65.4,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_024.svg
new file mode 100644 (file)
index 0000000..f1e5d37
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_24">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32.6,3,20,15.6,20,31c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,15.6,63.4,3,48,3z"/>
+               <path class="st0" d="M65.2,31c0,9.5-7.7,17.2-17.2,17.2c-9.5,0-17.2-7.7-17.2-17.2c0-9.5,7.7-17.2,17.2-17.2
+                       C57.5,13.7,65.2,21.5,65.2,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_025.svg
new file mode 100644 (file)
index 0000000..f0627c1
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_25">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32.6,3,20,15.6,20,31c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,15.6,63.4,3,48,3z"/>
+               <path class="st0" d="M65.1,31c0,9.5-7.7,17.1-17.1,17.1c-9.5,0-17.1-7.7-17.1-17.1c0-9.5,7.7-17.1,17.1-17.1
+                       C57.5,13.9,65.1,21.5,65.1,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/96x62/sem_btn_radio_to_on_mtrl_026.svg
new file mode 100644 (file)
index 0000000..8b680a9
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 62" style="enable-background:new 0 0 96 62;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_26">
+               <path class="st0" d="M48,62c-17.1,0-31-13.9-31-31C17,13.9,30.9,0,48,0c17.1,0,31,13.9,31,31C79,48.1,65.1,62,48,62z M48,3
+                       C32,3,20,15,20,31c0,16,12,28,28,28c16,0,28-12,28-28C76,15,64,3,48,3z"/>
+               <path class="st0" d="M65,31c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17c0-9.4,7.6-17,17-17C57.4,14,65,21.6,65,31z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_000.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_000.svg
new file mode 100644 (file)
index 0000000..81c3804
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_00" class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z
+                M48,20c-16,0-28,12-28,28c0,16,12,28,28,28c16,0,28-12,28-28C76,32,64,20,48,20z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_001.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_001.svg
new file mode 100644 (file)
index 0000000..eedb6bc
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_01" class="st0" d="M48,78c-16.5,0-30-13.5-30-30c0-16.5,13.5-30,30-30s30,13.5,30,30C78,64.5,64.5,78,48,78z M48,21
+               c-15.4,0-27,11.6-27,27c0,15.4,11.6,27,27,27s27-11.6,27-27C75,32.6,63.4,21,48,21z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_002.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_002.svg
new file mode 100644 (file)
index 0000000..65a2f45
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_02" class="st0" d="M48,77c-16,0-29-13-29-29c0-16,13-29,29-29c16,0,29,13,29,29C77,64,64,77,48,77z M48,22
+               c-14.9,0-26,11.1-26,26c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,33.1,62.9,22,48,22z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_003.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_003.svg
new file mode 100644 (file)
index 0000000..ababc5e
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_03" class="st0" d="M48,76c-15.4,0-28-12.6-28-28c0-15.4,12.6-28,28-28s28,12.6,28,28C76,63.4,63.4,76,48,76z M48,23
+               c-14.3,0-25,10.7-25,25c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,33.7,62.3,23,48,23z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_004.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_004.svg
new file mode 100644 (file)
index 0000000..8b0b9ca
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_04" class="st0" d="M48,75c-14.9,0-27-12.1-27-27c0-14.9,12.1-27,27-27c14.9,0,27,12.1,27,27C75,62.9,62.9,75,48,75z
+                M48,24c-13.8,0-24,10.2-24,24c0,13.8,10.2,24,24,24s24-10.2,24-24C72,34.2,61.8,24,48,24z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_005.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_005.svg
new file mode 100644 (file)
index 0000000..6561850
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_05" class="st0" d="M48,74c-14.3,0-26-11.7-26-26c0-14.3,11.7-26,26-26c14.3,0,26,11.7,26,26C74,62.3,62.3,74,48,74z
+                M48,25c-13.2,0-23,9.8-23,23c0,13.2,9.8,23,23,23c13.2,0,23-9.8,23-23C71,34.8,61.2,25,48,25z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_006.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_006.svg
new file mode 100644 (file)
index 0000000..77becb2
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <path id="_x30_06" class="st0" d="M48,74c-14.3,0-26-11.7-26-26c0-14.3,11.7-26,26-26c14.3,0,26,11.7,26,26C74,62.3,62.3,74,48,74z
+                M48,25c-13.2,0-23,9.8-23,23c0,13.2,9.8,23,23,23c13.2,0,23-9.8,23-23C71,34.8,61.2,25,48,25z"/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_007.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_007.svg
new file mode 100644 (file)
index 0000000..f6e2b70
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_07_2_">
+               <path class="st0" d="M48,74.5c-14.6,0-26.5-11.9-26.5-26.5c0-14.6,11.9-26.5,26.5-26.5c14.6,0,26.5,11.9,26.5,26.5
+                       C74.5,62.6,62.6,74.5,48,74.5z M48,24.5c-13.5,0-23.5,10-23.5,23.5c0,13.5,10,23.5,23.5,23.5c13.5,0,23.5-10,23.5-23.5
+                       C71.5,34.5,61.5,24.5,48,24.5z"/>
+               <circle class="st0" cx="48" cy="48" r="2"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_008.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_008.svg
new file mode 100644 (file)
index 0000000..9180257
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_08">
+               <path class="st0" d="M48,75c-14.9,0-27-12.1-27-27c0-14.9,12.1-27,27-27c14.9,0,27,12.1,27,27C75,62.9,62.9,75,48,75z M48,24
+                       c-13.8,0-24,10.2-24,24c0,13.8,10.2,24,24,24s24-10.2,24-24C72,34.2,61.8,24,48,24z"/>
+               <circle class="st0" cx="48" cy="48" r="4"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_009.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_009.svg
new file mode 100644 (file)
index 0000000..5999420
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_09">
+               <path class="st0" d="M48,75.5c-15.2,0-27.5-12.3-27.5-27.5c0-15.2,12.3-27.5,27.5-27.5c15.2,0,27.5,12.3,27.5,27.5
+                       C75.5,63.2,63.2,75.5,48,75.5z M48,23.5c-14.1,0-24.5,10.4-24.5,24.5c0,14.1,10.4,24.5,24.5,24.5S72.5,62.1,72.5,48
+                       C72.5,33.9,62.1,23.5,48,23.5z"/>
+               <circle class="st0" cx="48" cy="48" r="6"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_010.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_010.svg
new file mode 100644 (file)
index 0000000..8b5146e
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_10">
+               <path class="st0" d="M48,76c-15.4,0-28-12.6-28-28c0-15.4,12.6-28,28-28s28,12.6,28,28C76,63.4,63.4,76,48,76z M48,23
+                       c-14.3,0-25,10.7-25,25c0,14.3,10.7,25,25,25c14.3,0,25-10.7,25-25C73,33.7,62.3,23,48,23z"/>
+               <circle class="st0" cx="48" cy="48" r="8"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_011.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_011.svg
new file mode 100644 (file)
index 0000000..fbe560d
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_11">
+               <path class="st0" d="M48,76.5c-15.7,0-28.5-12.8-28.5-28.5c0-15.7,12.8-28.5,28.5-28.5S76.5,32.3,76.5,48
+                       C76.5,63.7,63.7,76.5,48,76.5z M48,22.5c-14.6,0-25.5,10.9-25.5,25.5c0,14.6,10.9,25.5,25.5,25.5c14.6,0,25.5-10.9,25.5-25.5
+                       C73.5,33.4,62.6,22.5,48,22.5z"/>
+               <circle class="st0" cx="48" cy="48" r="10"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_012.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_012.svg
new file mode 100644 (file)
index 0000000..1098932
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_12">
+               <path class="st0" d="M48,77c-16,0-29-13-29-29c0-16,13-29,29-29c16,0,29,13,29,29C77,64,64,77,48,77z M48,22
+                       c-14.9,0-26,11.1-26,26c0,14.9,11.1,26,26,26c14.9,0,26-11.1,26-26C74,33.1,62.9,22,48,22z"/>
+               <path class="st0" d="M60,48c0,6.6-5.4,12-12,12c-6.6,0-12-5.4-12-12c0-6.6,5.4-12,12-12C54.6,36,60,41.4,60,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_013.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_013.svg
new file mode 100644 (file)
index 0000000..6c497df
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_13">
+               <path class="st0" d="M48,77.5c-16.3,0-29.5-13.2-29.5-29.5c0-16.3,13.2-29.5,29.5-29.5c16.3,0,29.5,13.2,29.5,29.5
+                       C77.5,64.3,64.3,77.5,48,77.5z M48,21.5c-15.2,0-26.5,11.3-26.5,26.5c0,15.2,11.3,26.5,26.5,26.5c15.2,0,26.5-11.3,26.5-26.5
+                       C74.5,32.8,63.2,21.5,48,21.5z"/>
+               <path class="st0" d="M62,48c0,7.7-6.3,14-14,14c-7.7,0-14-6.3-14-14s6.3-14,14-14C55.7,34,62,40.3,62,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_014.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_014.svg
new file mode 100644 (file)
index 0000000..1f71fd7
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_14">
+               <path class="st0" d="M48,78c-16.5,0-30-13.5-30-30c0-16.5,13.5-30,30-30s30,13.5,30,30C78,64.5,64.5,78,48,78z M48,21
+                       c-15.4,0-27,11.6-27,27c0,15.4,11.6,27,27,27s27-11.6,27-27C75,32.6,63.4,21,48,21z"/>
+               <path class="st0" d="M64,48c0,8.8-7.2,16-16,16c-8.8,0-16-7.2-16-16c0-8.8,7.2-16,16-16C56.8,32,64,39.2,64,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_015.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_015.svg
new file mode 100644 (file)
index 0000000..66a948e
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_15">
+               <path class="st0" d="M48,78.5c-16.8,0-30.5-13.7-30.5-30.5c0-16.8,13.7-30.5,30.5-30.5c16.8,0,30.5,13.7,30.5,30.5
+                       C78.5,64.8,64.8,78.5,48,78.5z M48,20.5c-15.7,0-27.5,11.8-27.5,27.5c0,15.7,11.8,27.5,27.5,27.5S75.5,63.7,75.5,48
+                       C75.5,32.3,63.7,20.5,48,20.5z"/>
+               <path class="st0" d="M66,48c0,9.9-8.1,18-18,18c-9.9,0-18-8.1-18-18c0-9.9,8.1-18,18-18C57.9,30,66,38.1,66,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_016.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_016.svg
new file mode 100644 (file)
index 0000000..ef9847b
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_16">
+               <path class="st0" d="M68,48c0,11-9,20-20,20c-11.1,0-20-9-20-20c0-11,8.9-20,20-20C59,28,68,37,68,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_017.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_017.svg
new file mode 100644 (file)
index 0000000..9e81377
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_17">
+               <path class="st0" d="M67.6,48c0,10.8-8.8,19.6-19.6,19.6c-10.8,0-19.6-8.8-19.6-19.6c0-10.8,8.8-19.6,19.6-19.6
+                       C58.8,28.4,67.6,37.2,67.6,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_018.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_018.svg
new file mode 100644 (file)
index 0000000..2056b2c
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_18">
+               <path class="st0" d="M67.2,48c0,10.6-8.6,19.2-19.2,19.2c-10.6,0-19.2-8.6-19.2-19.2c0-10.6,8.6-19.2,19.2-19.2
+                       C58.6,28.7,67.2,37.4,67.2,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_019.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_019.svg
new file mode 100644 (file)
index 0000000..897e7cc
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_19">
+               <path class="st0" d="M66.9,48c0,10.4-8.4,18.9-18.9,18.9c-10.4,0-18.9-8.4-18.9-18.9c0-10.4,8.4-18.9,18.9-18.9
+                       C58.4,29.1,66.9,37.6,66.9,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_020.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_020.svg
new file mode 100644 (file)
index 0000000..c37c017
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_20">
+               <path class="st0" d="M66.5,48c0,10.2-8.3,18.5-18.5,18.5c-10.2,0-18.5-8.3-18.5-18.5c0-10.2,8.3-18.5,18.5-18.5
+                       C58.2,29.5,66.5,37.8,66.5,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_021.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_021.svg
new file mode 100644 (file)
index 0000000..05d9d56
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_21">
+               <path class="st0" d="M66.1,48c0,10-8.1,18.1-18.1,18.1C38,66.1,29.9,58,29.9,48c0-10,8.1-18.1,18.1-18.1C58,29.9,66.1,38,66.1,48z
+                       "/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_022.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_022.svg
new file mode 100644 (file)
index 0000000..f984c11
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_22">
+               <path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+                       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+               <path class="st0" d="M65.7,48c0,9.8-7.9,17.8-17.8,17.8c-9.8,0-17.8-7.9-17.8-17.8c0-9.8,7.9-17.8,17.8-17.8
+                       C57.8,30.2,65.7,38.2,65.7,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_023.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_023.svg
new file mode 100644 (file)
index 0000000..075772f
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_23">
+               <path class="st0" d="M65.4,48c0,9.6-7.8,17.4-17.4,17.4c-9.6,0-17.4-7.8-17.4-17.4c0-9.6,7.8-17.4,17.4-17.4
+                       C57.6,30.6,65.4,38.4,65.4,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_024.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_024.svg
new file mode 100644 (file)
index 0000000..94dbc43
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_24">
+               <path class="st0" d="M65.2,48c0,9.5-7.7,17.2-17.2,17.2c-9.5,0-17.2-7.7-17.2-17.2c0-9.5,7.7-17.2,17.2-17.2
+                       C57.5,30.7,65.2,38.5,65.2,48z"/>
+       </g>
+</g>
+<path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_025.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_025.svg
new file mode 100644 (file)
index 0000000..f0e9d49
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_25">
+               <path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+                       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+               <path class="st0" d="M65.1,48c0,9.5-7.7,17.1-17.1,17.1c-9.5,0-17.1-7.7-17.1-17.1c0-9.5,7.7-17.1,17.1-17.1
+                       C57.5,30.9,65.1,38.5,65.1,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_026.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sem_btn_radio_to_on_mtrl_026.svg
new file mode 100644 (file)
index 0000000..1a6e41c
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 96 96" style="enable-background:new 0 0 96 96;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<g id="Radio">
+       <g id="_x30_26">
+               <path class="st0" d="M48,79c-17.1,0-31-13.9-31-31c0-17.1,13.9-31,31-31c17.1,0,31,13.9,31,31C79,65.1,65.1,79,48,79z M48,20
+                       c-15.4,0-28,12.6-28,28c0,15.4,12.6,28,28,28c15.4,0,28-12.6,28-28C76,32.6,63.4,20,48,20z"/>
+               <path class="st0" d="M65,48c0,9.4-7.6,17-17,17c-9.4,0-17-7.6-17-17c0-9.4,7.6-17,17-17C57.4,31,65,38.6,65,48z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg
new file mode 100644 (file)
index 0000000..ec21dc3
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="2592" height="96" viewBox="0 0 2592 96" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_000" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_00" class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-16 0-28 12-28 28s12 28 28 28 28-12 28-28-12-28-28-28z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_001" x="96" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_01" class="st0" d="M48 78c-16.5 0-30-13.5-30-30s13.5-30 30-30 30 13.5 30 30-13.5 30-30 30zm0-57c-15.4 0-27 11.6-27 27s11.6 27 27 27 27-11.6 27-27-11.6-27-27-27z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_002" x="192" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_02" class="st0" d="M48 77c-16 0-29-13-29-29s13-29 29-29 29 13 29 29-13 29-29 29zm0-55c-14.9 0-26 11.1-26 26s11.1 26 26 26 26-11.1 26-26-11.1-26-26-26z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_003" x="288" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_03" class="st0" d="M48 76c-15.4 0-28-12.6-28-28s12.6-28 28-28 28 12.6 28 28-12.6 28-28 28zm0-53c-14.3 0-25 10.7-25 25s10.7 25 25 25 25-10.7 25-25-10.7-25-25-25z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_004" x="384" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_04" class="st0" d="M48 75c-14.9 0-27-12.1-27-27s12.1-27 27-27 27 12.1 27 27-12.1 27-27 27zm0-51c-13.8 0-24 10.2-24 24s10.2 24 24 24 24-10.2 24-24-10.2-24-24-24z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_005" x="480" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_05" class="st0" d="M48 74c-14.3 0-26-11.7-26-26s11.7-26 26-26 26 11.7 26 26-11.7 26-26 26zm0-49c-13.2 0-23 9.8-23 23s9.8 23 23 23 23-9.8 23-23-9.8-23-23-23z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_006" x="576" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path id="_x30_06" class="st0" d="M48 74c-14.3 0-26-11.7-26-26s11.7-26 26-26 26 11.7 26 26-11.7 26-26 26zm0-49c-13.2 0-23 9.8-23 23s9.8 23 23 23 23-9.8 23-23-9.8-23-23-23z"/></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_007" x="672" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_07_2_"><path class="st0" d="M48 74.5c-14.6 0-26.5-11.9-26.5-26.5S33.4 21.5 48 21.5 74.5 33.4 74.5 48 62.6 74.5 48 74.5zm0-50c-13.5 0-23.5 10-23.5 23.5s10 23.5 23.5 23.5 23.5-10 23.5-23.5-10-23.5-23.5-23.5z"/><circle class="st0" cx="48" cy="48" r="2"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_008" x="768" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_08"><path class="st0" d="M48 75c-14.9 0-27-12.1-27-27s12.1-27 27-27 27 12.1 27 27-12.1 27-27 27zm0-51c-13.8 0-24 10.2-24 24s10.2 24 24 24 24-10.2 24-24-10.2-24-24-24z"/><circle class="st0" cx="48" cy="48" r="4"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_009" x="864" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_09"><path class="st0" d="M48 75.5c-15.2 0-27.5-12.3-27.5-27.5S32.8 20.5 48 20.5 75.5 32.8 75.5 48 63.2 75.5 48 75.5zm0-52c-14.1 0-24.5 10.4-24.5 24.5S33.9 72.5 48 72.5 72.5 62.1 72.5 48 62.1 23.5 48 23.5z"/><circle class="st0" cx="48" cy="48" r="6"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_010" x="960" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_10"><path class="st0" d="M48 76c-15.4 0-28-12.6-28-28s12.6-28 28-28 28 12.6 28 28-12.6 28-28 28zm0-53c-14.3 0-25 10.7-25 25s10.7 25 25 25 25-10.7 25-25-10.7-25-25-25z"/><circle class="st0" cx="48" cy="48" r="8"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_011" x="1056" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_11"><path class="st0" d="M48 76.5c-15.7 0-28.5-12.8-28.5-28.5S32.3 19.5 48 19.5 76.5 32.3 76.5 48 63.7 76.5 48 76.5zm0-54c-14.6 0-25.5 10.9-25.5 25.5S33.4 73.5 48 73.5 73.5 62.6 73.5 48 62.6 22.5 48 22.5z"/><circle class="st0" cx="48" cy="48" r="10"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_012" x="1152" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_12"><path class="st0" d="M48 77c-16 0-29-13-29-29s13-29 29-29 29 13 29 29-13 29-29 29zm0-55c-14.9 0-26 11.1-26 26s11.1 26 26 26 26-11.1 26-26-11.1-26-26-26z"/><path class="st0" d="M60 48c0 6.6-5.4 12-12 12s-12-5.4-12-12 5.4-12 12-12 12 5.4 12 12z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_013" x="1248" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_13"><path class="st0" d="M48 77.5c-16.3 0-29.5-13.2-29.5-29.5S31.7 18.5 48 18.5 77.5 31.7 77.5 48 64.3 77.5 48 77.5zm0-56c-15.2 0-26.5 11.3-26.5 26.5S32.8 74.5 48 74.5 74.5 63.2 74.5 48 63.2 21.5 48 21.5z"/><path class="st0" d="M62 48c0 7.7-6.3 14-14 14s-14-6.3-14-14 6.3-14 14-14 14 6.3 14 14z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_014" x="1344" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_14"><path class="st0" d="M48 78c-16.5 0-30-13.5-30-30s13.5-30 30-30 30 13.5 30 30-13.5 30-30 30zm0-57c-15.4 0-27 11.6-27 27s11.6 27 27 27 27-11.6 27-27-11.6-27-27-27z"/><path class="st0" d="M64 48c0 8.8-7.2 16-16 16s-16-7.2-16-16 7.2-16 16-16 16 7.2 16 16z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_015" x="1440" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_15"><path class="st0" d="M48 78.5c-16.8 0-30.5-13.7-30.5-30.5S31.2 17.5 48 17.5 78.5 31.2 78.5 48 64.8 78.5 48 78.5zm0-58c-15.7 0-27.5 11.8-27.5 27.5S32.3 75.5 48 75.5 75.5 63.7 75.5 48 63.7 20.5 48 20.5z"/><path class="st0" d="M66 48c0 9.9-8.1 18-18 18s-18-8.1-18-18 8.1-18 18-18 18 8.1 18 18z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_016" x="1536" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M68 48c0 11-9 20-20 20-11.1 0-20-9-20-20s8.9-20 20-20c11 0 20 9 20 20z" id="_x30_16"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_017" x="1632" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M67.6 48c0 10.8-8.8 19.6-19.6 19.6S28.4 58.8 28.4 48 37.2 28.4 48 28.4 67.6 37.2 67.6 48z" id="_x30_17"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_018" x="1728" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M67.2 48c0 10.6-8.6 19.2-19.2 19.2S28.8 58.6 28.8 48 37.4 28.8 48 28.8c10.6-.1 19.2 8.6 19.2 19.2z" id="_x30_18"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_019" x="1824" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M66.9 48c0 10.4-8.4 18.9-18.9 18.9-10.4 0-18.9-8.4-18.9-18.9 0-10.4 8.4-18.9 18.9-18.9 10.4 0 18.9 8.5 18.9 18.9z" id="_x30_19"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_020" x="1920" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M66.5 48c0 10.2-8.3 18.5-18.5 18.5S29.5 58.2 29.5 48 37.8 29.5 48 29.5 66.5 37.8 66.5 48z" id="_x30_20"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_021" x="2016" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M66.1 48c0 10-8.1 18.1-18.1 18.1-10 0-18.1-8.1-18.1-18.1 0-10 8.1-18.1 18.1-18.1 10 0 18.1 8.1 18.1 18.1z" id="_x30_21"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_022" x="2112" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_22"><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/><path class="st0" d="M65.7 48c0 9.8-7.9 17.8-17.8 17.8-9.8 0-17.8-7.9-17.8-17.8 0-9.8 7.9-17.8 17.8-17.8s17.8 8 17.8 17.8z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_023" x="2208" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M65.4 48c0 9.6-7.8 17.4-17.4 17.4-9.6 0-17.4-7.8-17.4-17.4 0-9.6 7.8-17.4 17.4-17.4 9.6 0 17.4 7.8 17.4 17.4z" id="_x30_23"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_024" x="2304" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><path class="st0" d="M65.2 48c0 9.5-7.7 17.2-17.2 17.2S30.8 57.5 30.8 48 38.5 30.8 48 30.8c9.5-.1 17.2 7.7 17.2 17.2z" id="_x30_24"/></g><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_025" x="2400" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_25"><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/><path class="st0" d="M65.1 48c0 9.5-7.7 17.1-17.1 17.1-9.5 0-17.1-7.7-17.1-17.1 0-9.5 7.7-17.1 17.1-17.1 9.5 0 17.1 7.6 17.1 17.1z"/></g></g></svg><svg version="1.1" id="icon_sem_btn_radio_to_on_mtrl_026" x="2496" viewBox="0 0 96 96" xml:space="preserve" width="96" height="96" xmlns="http://www.w3.org/2000/svg"><style>.st0{fill:#fff}</style><g id="Radio"><g id="_x30_26"><path class="st0" d="M48 79c-17.1 0-31-13.9-31-31s13.9-31 31-31 31 13.9 31 31-13.9 31-31 31zm0-59c-15.4 0-28 12.6-28 28s12.6 28 28 28 28-12.6 28-28-12.6-28-28-28z"/><path class="st0" d="M65 48c0 9.4-7.6 17-17 17s-17-7.6-17-17 7.6-17 17-17 17 7.6 17 17z"/></g></g></svg></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/gallery_btn_check_bg_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/gallery_btn_check_bg_mtrl.svg
new file mode 100644 (file)
index 0000000..fce19cf
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<path fill="#777777" fill-opacity="0.6588" d="M47.999,16.25C30.493,16.25,16.25,30.493,16.25,48\r
+       c0,17.507,14.243,31.75,31.749,31.75C65.507,79.75,79.75,65.507,79.75,48C79.75,30.493,65.507,16.25,47.999,16.25z M47.999,79\r
+       C30.88,79,17,65.122,17,48s13.88-31,30.999-31C65.123,17,79,30.877,79,48S65.123,79,47.999,79z"/>\r
+<path fill="#231F20" fill-opacity="0.3176" d="M48,17c-17.112,0-31,13.888-31,31c0,17.112,13.888,31,31,31c17.112,0,31-13.888,31-31\r
+       C79,30.888,65.112,17,48,17z"/>\r
+<path fill="#797979" fill-opacity="0.6471" d="M63.611,32.895L41.905,54.358l-10.26-10.146l-4.046,4.001l14.307,14.146\r
+       l25.751-25.463L63.611,32.895z M28.666,48.214l2.979-2.947l10.26,10.146L63.611,33.95l2.979,2.947L41.905,61.305L28.666,48.214z"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg
new file mode 100644 (file)
index 0000000..854e16c
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<path fill="#797979" fill-opacity="0.498" d="M47.999,16.25C30.492,16.25,16.25,30.493,16.25,48c0,17.508,14.242,31.75,31.749,31.75\r
+       C65.507,79.75,79.75,65.508,79.75,48C79.75,30.493,65.507,16.25,47.999,16.25z M47.999,79C30.881,79,17,65.123,17,48\r
+       s13.881-31,30.999-31C65.123,17,79,30.877,79,48S65.123,79,47.999,79z"/>\r
+<path fill="#231F20" fill-opacity="0.3176" d="M48,17c-17.112,0-31,13.888-31,31c0,17.112,13.888,31,31,31c17.112,0,31-13.888,31-31\r
+       C79,30.888,65.112,17,48,17z"/>\r
+<path fill="#797979" fill-opacity="0.498" d="M48,20c-15.464,0-28,12.536-28,28c0,15.465,12.536,28,28,28s28-12.535,28-28\r
+       C76,32.536,63.464,20,48,20z M48,75.25c-15.026,0-27.25-12.225-27.25-27.25c0-15.026,12.224-27.25,27.25-27.25\r
+       c15.025,0,27.25,12.224,27.25,27.25C75.25,63.025,63.025,75.25,48,75.25z"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_chips_icon_add_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_chips_icon_add_mtrl.svg
new file mode 100644 (file)
index 0000000..ef498c6
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="60px" height="60px" viewBox="0 0 60 60" enable-background="new 0 0 60 60" xml:space="preserve">\r
+<rect x="11.627" y="27.85" fill="#231F20" width="36" height="5"/>\r
+<rect x="27.141" y="12.131" fill="#231F20" width="5" height="36"/>\r
+<rect fill="none" width="60" height="60"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_chips_icon_delete_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_chips_icon_delete_mtrl.svg
new file mode 100644 (file)
index 0000000..64ea5d9
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="60px" height="60px" viewBox="0 0 60 60" enable-background="new 0 0 60 60" xml:space="preserve">\r
+<rect x="11.627" y="27.85" fill="#231F20" width="36" height="5"/>\r
+<rect fill="none" width="60" height="60"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_expander_close_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_expander_close_mtrl.svg
new file mode 100644 (file)
index 0000000..4a48058
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="70.53 64.5 48 40.78 25.47 64.5 21 59.92 48 31.5 75 59.92 70.53 64.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_expander_open_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_expander_open_mtrl.svg
new file mode 100644 (file)
index 0000000..f6597b9
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="70.53 31.5 48 55.22 25.47 31.5 21 36.08 48 64.5 75 36.08 70.53 31.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_add_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_add_mtrl.svg
new file mode 100644 (file)
index 0000000..bfa2535
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<polygon points="71.25,45 51,45 51,24.75 45,24.75 45,45 24.75,45 24.75,51.001 45,51.001 45,71.25 51,71.25 51,51.001 \r
+       71.25,51.001 "/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_delete_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_delete_mtrl.svg
new file mode 100644 (file)
index 0000000..ee3a127
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\r
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">\r
+<rect x="24.75" y="45" width="46.5" height="6.001"/>\r
+</svg>\r
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_reorder.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/3_Controllers/tw_list_icon_reorder.svg
new file mode 100644 (file)
index 0000000..58ffad3
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve">
+<path d="M60.992,41.771L47.969,28.696L34.998,41.769l-3.158-3.14l16.123-16.246l16.184,16.244L60.992,41.771L60.992,41.771z"/>
+<path d="M48.024,73.615L31.795,57.379l3.149-3.149l13.074,13.081L61.04,54.231l3.153,3.145L48.024,73.615L48.024,73.615z"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/4_Dialogs/tw_numberpicker_next_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/4_Dialogs/tw_numberpicker_next_mtrl.svg
new file mode 100644 (file)
index 0000000..34762a3
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="108px" height="108px" viewBox="0 0 108 108" enable-background="new 0 0 108 108" xml:space="preserve">
+<g>
+       <polygon points="52.993,72.433 50.696,70.144 66.883,53.999 50.695,37.856 52.993,35.567 71.477,53.999    "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/4_Dialogs/tw_numberpicker_prev_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/4_Dialogs/tw_numberpicker_prev_mtrl.svg
new file mode 100644 (file)
index 0000000..22f62bc
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 16.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        width="108px" height="108px" viewBox="0 0 108 108" enable-background="new 0 0 108 108" xml:space="preserve">
+<g>
+       <polygon points="53.307,72.433 55.604,70.144 39.417,53.999 55.605,37.856 53.308,35.567 34.823,53.999    "/>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_expander_close_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_expander_close_mtrl.svg
new file mode 100644 (file)
index 0000000..4a48058
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="70.53 64.5 48 40.78 25.47 64.5 21 59.92 48 31.5 75 59.92 70.53 64.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_expander_open_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_expander_open_mtrl.svg
new file mode 100644 (file)
index 0000000..f6597b9
--- /dev/null
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96"><defs><style>.cls-1{fill:#fff;fill-rule:evenodd;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="70.53 31.5 48 55.22 25.47 31.5 21 36.08 48 64.5 75 36.08 70.53 31.5"/></g></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_connections.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_connections.svg
new file mode 100644 (file)
index 0000000..3e97dd5
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/01_connections copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_01_x5F_connections-copy">
+       <g id="Settings_x2F_Menu-tree_x2F_connections" transform="translate(8.000000, 8.000000)">
+               <path id="Connections" d="M52,68.4c1.2,0,2.4,0.5,3.3,1.4c0.7,0.7,1.1,1.6,1.3,2.5c0,0.2,0.1,0.3,0.1,0.5c0.1,1.3-0.4,2.6-1.3,3.6
+                       c-0.9,0.9-2.1,1.4-3.3,1.4c-1.2,0-2.4-0.5-3.3-1.4c-1-1.1-1.5-2.5-1.3-4c0-0.1,0-0.2,0.1-0.3c0.2-0.9,0.6-1.7,1.2-2.3
+                       C49.5,68.8,50.7,68.4,52,68.4z M51.9,55.1c6,0,11.4,2.5,15.2,6.5l0,0l-4.8,4.8c-2.6-2.8-6.3-4.5-10.5-4.5c-4.1,0-7.7,1.7-10.3,4.4
+                       l0,0l-4.8-4.8C40.7,57.5,46,55.1,51.9,55.1z M51.9,40.6c10,0,19,4.1,25.5,10.7l0,0l-4.7,4.7c-5.3-5.4-12.6-8.8-20.7-8.8
+                       c-8.1,0-15.4,3.3-20.6,8.6l0,0l-4.7-4.7C33,44.7,42,40.6,51.9,40.6z M51.9,26.3c13.9,0,26.5,5.7,35.6,14.9l0,0L82.8,46
+                       C74.9,38,64,33,51.9,33c-12,0-22.9,4.9-30.7,12.8l0,0l-4.7-4.7C25.5,32,38.1,26.3,51.9,26.3z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_display.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_display.svg
new file mode 100644 (file)
index 0000000..262c8be
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/04_display copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_04_x5F_display-copy">
+       <g id="Common_x2F_brightness" transform="translate(6.000000, 6.000000)">
+               <path id="Brightness" d="M57.7,77.8v10.5h-7V77.8H57.7z M34.5,68.1l5,4.9l-7.3,7.5l-5-4.9L34.5,68.1z M73.5,67.9l7.3,7.5l-5,4.9
+                       l-7.3-7.5L73.5,67.9z M54.2,39c8.3,0,15.1,6.7,15.1,15s-6.7,15.1-15.1,15.1s-15-6.7-15-15.1S45.9,39,54.2,39z M88.1,51.6v7H78v-7
+                       H88.1z M30,51.6v7H19.9v-7H30z M32.5,27.7l7.3,7.5l-5,4.9l-7.3-7.5L32.5,27.7z M75.7,27.5l5,4.9l-7.3,7.5l-5-4.9L75.7,27.5z
+                        M57.7,19.7v10.5h-7V19.7H57.7z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_notifications.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_notifications.svg
new file mode 100644 (file)
index 0000000..c97ee90
--- /dev/null
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/03_notifications copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_03_x5F_notifications-copy">
+       <g id="Settings_x2F_Menu-tree_x2F_notifications" transform="translate(8.000000, 8.000000)">
+               <path id="Notifications" d="M59.4,35.9c-0.1,0.4-0.2,0.9-0.3,1.4c-0.1,0.5-0.1,0.9-0.2,1.4c0,0.4-0.1,0.8-0.1,1.3
+                       c0,9,7.3,16.4,16.4,16.4c0,0,0.1,0,0.1,0c0.5,0,0.9,0,1.4-0.1c0.5,0,0.9-0.1,1.4-0.2l0,0v4.9c0,6.8-5.5,12.3-12.3,12.3l0,0H33
+                       c-6.8,0-12.3-5.5-12.3-12.3l0,0h0V48.2c0-6.8,5.5-12.3,12.3-12.3l0,0H59.4z M75.3,29.9c5.5,0,10,4.5,10,10c0,4.6-3,8.4-7.2,9.6
+                       c-0.4,0.1-0.9,0.2-1.4,0.3c-0.4,0.1-0.9,0.1-1.4,0.1c0,0-0.1,0-0.1,0c-5.5,0-10-4.5-10-10c0-0.4,0-0.9,0.1-1.3
+                       c0.1-0.5,0.1-0.9,0.3-1.4c0.1-0.5,0.3-0.9,0.5-1.3C67.6,32.4,71.2,29.9,75.3,29.9z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_sound.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_sound.svg
new file mode 100644 (file)
index 0000000..1a23692
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/02_sound copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_02_x5F_sound-copy">
+       <g id="Common_x2F_volume_x5F_media" transform="translate(8.000000, 8.000000)">
+               <path id="Volume-_x2F_-Media" d="M50.3,28.3c1.8-1.8,3.6-1.2,3.6,1.2l0,0v44.4c0,3-1.5,3.6-3.6,1.8l0,0L35,61.9H24.5
+                       c-1.8,0-3.3-1.5-3.3-3.3l0,0V45.4c0-1.8,1.5-3.3,3.3-3.3l0,0H35L50.3,28.3z M73.4,28.9C86,41.8,86,62.5,73.4,75.4l0,0l-4.8-4.8
+                       c10.2-10.2,10.2-26.7,0-36.9l0,0L73.4,28.9z M63.8,38.5c3.6,3.6,5.7,8.4,5.7,13.8s-2.1,10.2-5.7,13.8l0,0L59,61.3
+                       c2.4-2.4,3.6-5.4,3.6-9c0-3.6-1.2-6.6-3.6-9l0,0L63.8,38.5z"/>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_wallpaper.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_icon_wallpaper.svg
new file mode 100644 (file)
index 0000000..aa75360
--- /dev/null
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 120 120" style="enable-background:new 0 0 120 120;" xml:space="preserve">
+<title>settings/main_icon/05_wallpaper copy</title>
+<desc>Created with Sketch.</desc>
+<g id="settings_x2F_main_x5F_icon_x2F_05_x5F_wallpaper-copy">
+       <g id="Homescreen_x2F_wallpaper" transform="translate(8.000000, 8.000000)">
+               <g id="Aod_x2F_style_x28_theme_x29_">
+                       <path id="style_x28_theme_x29_" d="M69,75c0,0.7-0.6,1.3-1.3,1.3H36.3c-0.7,0-1.3-0.6-1.3-1.3v-7.6c0-1.2,0.8-1.9,0.8-2l7.4-6.9
+                               c0.5-0.5,1.3-0.5,1.8,0l3.6,3.5c0.5,0.5,1.3,0.5,1.7,0l9.1-8.9c0.5-0.5,1.2-0.5,1.7,0l7.2,7.4c0,0,0.7,0.6,0.7,1.5V75z
+                                M44.7,34.6c2.6,0,4.7,2.1,4.7,4.7c0,2.6-2.1,4.7-4.7,4.7c-2.6,0-4.7-2.1-4.7-4.7C40,36.7,42.1,34.6,44.7,34.6L44.7,34.6z
+                                M70,21.9H34c-2.8,0-5,2.2-5,5v50.2c0,2.8,2.2,5,5,5h36c2.8,0,5-2.3,5-5V26.9C75,24.1,72.8,21.9,70,21.9L70,21.9z"/>
+               </g>
+       </g>
+</g>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_subheader_dot.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/6_Lists/tw_list_subheader_dot.svg
new file mode 100644 (file)
index 0000000..1437ed0
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 24.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+        viewBox="0 0 4.5 1.5" style="enable-background:new 0 0 4.5 1.5;" xml:space="preserve">
+<style type="text/css">
+       .st0{fill:#FFFFFF;}
+</style>
+<circle class="st0" cx="0.8" cy="0.8" r="0.8"/>
+</svg>
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/9_Progress/tw_ic_progress_download_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/9_Progress/tw_ic_progress_download_mtrl.svg
new file mode 100644 (file)
index 0000000..73461dc
--- /dev/null
@@ -0,0 +1 @@
+<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m8.54775 1v8.80025h-5.54775l8.876 8.80125 8.87625-8.80125h-5.548v-8.80025zm-5.54775 22h17.75v-2.2h-17.75z" fill="#fff" fill-rule="evenodd"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/9_Progress/tw_ic_progress_refresh_mtrl.svg b/d2d_app/client/lib/tau/mobile/theme/default/images/9_Progress/tw_ic_progress_refresh_mtrl.svg
new file mode 100644 (file)
index 0000000..d6a4896
--- /dev/null
@@ -0,0 +1 @@
+<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m11.665659 2c-4.41911626 0-8.18833218 2.76607387-9.665659 6.65535226l2.33639931 1.35379614c.97768058-3.10798561 3.88911043-5.36285907 7.32925969-5.36285907 4.24159 0 7.6801955 3.42783858 7.6801955 7.65672027 0 4.2283686-3.4386055 7.6567202-7.6801955 7.6567202-1.84652991 0-3.54049016-.6502223-4.86524735-1.7326436l2.7297871-3.255985-7.41364893.6840801.68206084 7.3448187 2.26873352-2.7060534c1.7770631 1.4333106 4.13610343 2.3118161 6.59831482 2.3118161 5.7075963 0 10.334341-4.6126026 10.334341-10.3027531 0-5.690407-4.6267447-10.3030096-10.334341-10.3030096" fill="#fff" fill-rule="evenodd"/></svg>
\ No newline at end of file
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_001.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_001.jpg
new file mode 100644 (file)
index 0000000..011f4c9
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_001.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_002.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_002.jpg
new file mode 100644 (file)
index 0000000..531b7a3
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_002.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_003.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_003.jpg
new file mode 100644 (file)
index 0000000..4ce60ca
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_003.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_004.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_004.jpg
new file mode 100644 (file)
index 0000000..80513f6
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_004.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_005.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_005.jpg
new file mode 100644 (file)
index 0000000..c636bb0
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_005.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_006.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_006.jpg
new file mode 100644 (file)
index 0000000..67e6caa
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_006.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_007.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_007.jpg
new file mode 100644 (file)
index 0000000..c7fa86f
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_007.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_008.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_008.jpg
new file mode 100644 (file)
index 0000000..ea8f184
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_008.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_009.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_009.jpg
new file mode 100644 (file)
index 0000000..6f215e2
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_009.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_010.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_010.jpg
new file mode 100644 (file)
index 0000000..55c89cc
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_010.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_011.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_011.jpg
new file mode 100644 (file)
index 0000000..04b6fc0
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_011.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_012.jpg b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_012.jpg
new file mode 100644 (file)
index 0000000..85433dc
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/Thumbnail/thumbnail_012.jpg differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/images/controls/00_button_pause.png b/d2d_app/client/lib/tau/mobile/theme/default/images/controls/00_button_pause.png
new file mode 100644 (file)
index 0000000..e32a1fb
Binary files /dev/null and b/d2d_app/client/lib/tau/mobile/theme/default/images/controls/00_button_pause.png differ
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/tau.css b/d2d_app/client/lib/tau/mobile/theme/default/tau.css
new file mode 100644 (file)
index 0000000..10a50fa
--- /dev/null
@@ -0,0 +1,11672 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/********************************
+ * Tizen Changeable Less Header *
+ *******************************/
+/****************************
+ * Tizen nine-patch images  *
+ ****************************/
+/****************************
+ * Tizen Common Less Header *
+ ****************************/
+:root {
+  --text-secondary-color: #909090;
+  --primary-color: #0381fe;
+  --control-background: #e6e6e6;
+  --textual-background: #FCFCFC;
+  --color-white: #fafafa;
+  --surface: #FCFCFC;
+  --accent-badge: #F56A0D;
+  --on-background: #858585;
+  --border-surface: #e6e6e6;
+  --button-background: rgba(0, 0, 0, 0);
+  --button-background-flat: transparent;
+  --button-text-font-size: 17px;
+  --button-contained-text-font-size: 17px;
+  --button-contained-list-text-font-size: 15px;
+  --btn-add-color: #00b149;
+  --btn-delete-color: #ff3d00;
+  --checkbox-image-checked: rgba(0, 0, 0, 0.3);
+  --slider-bg-color: rgba(3, 129, 254, 0.3);
+  --slider-bg-disabled-color: rgba(102, 102, 102, 0.15);
+  --slider-value-color: #0381fe;
+  --slider-handler-color: #0381fe;
+  --btn-toast-background: rgba(71, 71, 71, 0.9);
+  --btn-toast-text-color: #0381fe;
+  --toast-background: rgba(102, 102, 102, 0.95);
+  --toast-text-color: #FFFFFF;
+  --progress-circle-second-color: #06b485;
+  --on-off-switch-off-button-border: #8f8f8f;
+  --on-off-switch-on-disabled-track-background: rgba(143, 143, 143, 0.4);
+  --on-off-switch-off-track-background: transparent;
+  --on-off-switch-off-disabled-track-border: rgba(143, 143, 143, 0.4);
+}
+body,
+body.ui-theme-light,
+body.ui-theme-default {
+  --primary-color: #0381fe;
+  --primary-dark-color: #0072de;
+  --primary-color-20p: rgba(3, 129, 254, 0.2);
+  --primary-color-30p: rgba(3, 129, 254, 0.3);
+  --control-active-color: #3e91ff;
+  --control-active-disabled-color: rgba(62, 145, 255, 0.4);
+  --control-inactive-color: #8f8f8f;
+  --text-color: #252525;
+  --text-secondary-color: #909090;
+  --color-white: #fafafa;
+  --color-black: #000000;
+  --ripple-color: rgba(0, 0, 0, 0.1);
+  --overlay: rgba(0, 0, 0, 0.45);
+  --background-color: #F2F2F2;
+  --background-area-color: #fcfcfc;
+  --expandable-text-color: #666666;
+  --popup-background: #fcfcfc;
+  --popup-text: #505050;
+  --popup-text-secondary-color: #8f8f8f;
+  --popup-footer-divider-color: #e6e6e6;
+  --popup-scroll-divider-color: #d4d4d4;
+  --icon-color: #3b3b3b;
+  --appbar-main-text-color: #252525;
+  --appbar-subtitle-color: #636363;
+  --appbar-miltiline-title-color: #252525;
+  --tab-text-color: #858585;
+  --tab-text-color-dim: rgba(133, 133, 133, 0.4);
+  --bottom-bar-color: #F2F2F2;
+  --button-icon-color: #252525;
+  --bottom-button-icon-color: #454545;
+  --sub-tab-bg-color: #F2F2F2;
+  --sub-tab-text-color: #858585;
+  --sub-tab-active-text-color: #252525;
+  --sub-tab-border-color: rgba(113, 113, 113, 0.8);
+  --progress-bar-color: #0381fe;
+  --progress-bar-bg-color: rgba(3, 129, 254, 0.3);
+  --button-text-color-disabled: rgba(3, 129, 254, 0.4);
+  --checkbox-favorite-color: #f5ab00;
+  --ripple-button-flat-color: rgba(0, 0, 0, 0.1);
+  --slider-handler-disabled-color: #d2d2d2;
+  --slider-scale-dot: #9c9c9c;
+  --slider-level-bar-bg-color: rgba(151, 151, 151, 0.3);
+  --button-background-contained: rgba(0, 0, 0, 0.06);
+  --on-off-switch-off-disabled-button-border: #d0d0d0;
+  --on-off-switch-on-disabled-button-border: #d0d0d0;
+  --on-off-switch-on-disabled-button-background: #fafafa;
+  --on-off-switch-divider-color: #c4c4c4;
+  --master-on-off-off-color: #fafafa;
+  --master-on-off-on-color: rgba(62, 145, 255, 0.8);
+  --chip-background-color: #e5e5e5;
+  --chip-border-color: rgba(37, 37, 37, 0.2);
+  --chip-btn-background-color: #f2f2f2;
+  --chip-btn-border-color: rgba(37, 37, 37, 0.3);
+  --text-input-invalid-color: #b00020;
+  --dropdown-menu-options-border: 0.25px solid #cccccc;
+  --dropdown-menu-options-background: #fcfcfc;
+  --dropdown-menu-options-color: #000000;
+  --dropdown-menu-options-color-dim: rgba(0, 0, 0, 0.4);
+  --content-area-line-color: #d6d6d6;
+  --list-item-selected-color: rgba(3, 129, 254, 0.08);
+  --divider-color: #e6e6e6;
+  --divider-opacity: 100%;
+  --subheader-divider-color: #979797;
+  --grid-border-color: rgba(0, 0, 0, 0.12);
+  --grid-label-color: #252525;
+  --grid-label-secondary-color: #666666;
+  --expander-color: #747474;
+  --reorder-color: #747474;
+  --holder-reoder-background: #fcfcfc;
+  --holder-reoder-border: #0072de;
+  --spin-item-opacity: 0.1;
+  --grid-selection-color: rgba(0, 0, 0, 0.3);
+  --calendar-weekend-day-color: #c95151;
+  --calendar-weekend-color: #d77e7e;
+  --calendar-text-color: #454545;
+  --calendar-arrow-color: #8e8e8e;
+  --calendar-select-text-color: #fafafa;
+  --date-picker-header-text-color: #454545;
+  --text-input-disabled: #bebebe;
+  --text-input-label-inactive: #8c8c8c;
+  --text-input-underline-inactive: #8c8c8c;
+  --text-input-underline-active: var(--primary-color);
+  --icon-control-color: var(--color-white);
+  --progress-background-color: #cccccc;
+  --on-off-switch-track-off: #8f8f8f;
+  --more-options-background-color: var(--popup-background);
+  --more-options-background-stroke: #cccccc;
+  --more-options-pressed-color: rgba(0, 0, 0, 0.1);
+  --button-text-contained-dim-color: rgba(37, 37, 37, 0.4);
+}
+body.ui-theme-dark {
+  --primary-color: #0381fe;
+  --primary-dark-color: #3e91ff;
+  --primary-color-20p: rgba(3, 129, 254, 0.2);
+  --primary-color-30p: rgba(3, 129, 254, 0.3);
+  --control-active-color: #3e91ff;
+  --control-active-disabled-color: rgba(62, 145, 255, 0.4);
+  --control-inactive-color: #8f8f8f;
+  --text-color: #fafafa;
+  --text-secondary-color: #999999;
+  --color-white: #fafafa;
+  --color-black: #080808;
+  --ripple-color: rgba(255, 255, 255, 0.2);
+  --overlay: rgba(0, 0, 0, 0.65);
+  --background-color: #080808;
+  --background-area-color: #252525;
+  --expandable-text-color: #9c9c9c;
+  --popup-background: #252525;
+  --popup-text: #e5e5e5;
+  --popup-text-secondary-color: #999999;
+  --popup-footer-divider-color: rgba(230, 230, 230, 0.2);
+  --popup-scroll-divider-color: rgba(212, 212, 212, 0.18);
+  --icon-color: #d9d9d9;
+  --appbar-main-text-color: #fafafa;
+  --appbar-subtitle-color: #9c9c9c;
+  --appbar-miltiline-title-color: #e5e5e5;
+  --tab-text-color: #a8a9a9;
+  --tab-text-color-dim: rgba(168, 169, 169, 0.4);
+  --bottom-bar-color: #010101;
+  --button-icon-color: #fafafa;
+  --bottom-button-icon-color: #cccccc;
+  --sub-tab-bg-color: #010101;
+  --sub-tab-text-color: #999999;
+  --sub-tab-active-text-color: #FFFFFF;
+  --sub-tab-border-color: rgba(255, 255, 255, 0.6);
+  --progress-bar-color: #0381fe;
+  --progress-bar-bg-color: rgba(3, 129, 254, 0.3);
+  --button-text-color-disabled: rgba(3, 129, 254, 0.4);
+  --checkbox-favorite-color: #f5ab00;
+  --ripple-button-flat-color: rgba(255, 255, 255, 0.2);
+  --slider-handler-disabled-color: #545454;
+  --slider-scale-dot: #808080;
+  --slider-level-bar-bg-color: rgba(151, 151, 151, 0.3);
+  --button-background-contained: rgba(250, 250, 250, 0.17);
+  --on-off-switch-off-disabled-button-border: #3b3b3b;
+  --on-off-switch-on-disabled-button-border: #3b3b3b;
+  --on-off-switch-on-disabled-button-background: #858585;
+  --on-off-switch-divider-color: rgba(212, 212, 212, 0.15);
+  --master-on-off-off-color: rgba(250, 250, 250, 0.17);
+  --master-on-off-on-color: rgba(62, 145, 255, 0.4);
+  --chip-background-color: #252525;
+  --chip-border-color: rgba(250, 250, 250, 0.2);
+  --chip-btn-background-color: #f2f2f2;
+  --chip-btn-border-color: rgba(37, 37, 37, 0.3);
+  --text-input-invalid-color: #ff6666;
+  --dropdown-menu-options-border: 0.75px solid #525252;
+  --dropdown-menu-options-background: #3d3d3d;
+  --dropdown-menu-options-color: #fafafa;
+  --dropdown-menu-options-color-dim: rgba(250, 250, 250, 0.4);
+  --content-area-line-color: #d6d6d6;
+  --list-item-selected-color: rgba(250, 250, 250, 0.1);
+  --divider-color: #d4d4d4;
+  --divider-opacity: 15%;
+  --subheader-divider-color: #fafafa;
+  --grid-border-color: rgba(250, 250, 250, 0.25);
+  --grid-label-color: #fafafa;
+  --grid-label-secondary-color: #999999;
+  --expander-color: #808080;
+  --reorder-color: #808080;
+  --holder-reoder-background: #252525;
+  --holder-reoder-border: #3e91ff;
+  --spin-item-opacity: 0.2;
+  --grid-selection-color: rgba(0, 0, 0, 0.3);
+  --calendar-weekend-day-color: #c95151;
+  --calendar-weekend-color: #993d3d;
+  --calendar-text-color: #cccccc;
+  --calendar-arrow-color: #737373;
+  --calendar-select-text-color: #000000;
+  --date-picker-header-text-color: #cccccc;
+  --surface: #3d3d3d;
+  --text-input-disabled: #454545;
+  --text-input-label-inactive: #737373;
+  --text-input-underline-inactive: #737373;
+  --text-input-underline-active: var(--primary-color);
+  --icon-control-color: var(--surface);
+  --progress-background-color: #252525;
+  --more-options-background-color: #3d3d3d;
+  --more-options-background-stroke: #525252;
+  --more-options-pressed-color: rgba(255, 255, 255, 0.2);
+  --button-text-contained-dim-color: rgba(250, 250, 250, 0.4);
+}
+@font-face {
+  font-family: Roboto-Light;
+  src: url(fonts/Roboto-Light.ttf);
+}
+@font-face {
+  font-family: Roboto-Regular;
+  src: url(fonts/Roboto-Regular.ttf);
+}
+@font-face {
+  font-family: Roboto-Medium;
+  src: url(fonts/Roboto-Medium.ttf);
+}
+.tau-info-theme {
+  position: absolute;
+  top: -999px;
+  left: -999px;
+}
+.ui-appbar,
+header {
+  position: relative;
+  width: 100%;
+  box-sizing: border-box;
+  background: var(--background-color);
+  overflow: hidden;
+  border: none;
+  height: 56px;
+  margin-bottom: 12px;
+  font-family: Roboto-Regular;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-appbar:not(.ui-appbar-dragging),
+header:not(.ui-appbar-dragging) {
+  transition: height 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
+}
+.ui-appbar:not(.ui-appbar-dragging) .ui-appbar-controls-container,
+header:not(.ui-appbar-dragging) .ui-appbar-controls-container,
+.ui-appbar:not(.ui-appbar-dragging) .ui-appbar-expanded-title-container,
+header:not(.ui-appbar-dragging) .ui-appbar-expanded-title-container {
+  padding-top: 0px;
+  transition: opacity 100ms cubic-bezier(0.25, 0.46, 0.45, 0.94);
+}
+.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast,
+header:not(.ui-appbar-dragging).ui-appbar-animation-fast {
+  transition-duration: 10ms;
+}
+.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-controls-container,
+header:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-controls-container,
+.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-expanded-title-container,
+header:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-expanded-title-container {
+  transition-duration: 10ms;
+}
+.ui-appbar .ui-btn,
+header .ui-btn {
+  padding: 0;
+}
+.ui-appbar .ui-btn.ui-btn-flat,
+header .ui-btn.ui-btn-flat {
+  font-size: 18px;
+  font-family: Roboto-Medium;
+  color: var(--appbar-main-text-color);
+}
+.ui-appbar .ui-btn.ui-btn-flat::before,
+header .ui-btn.ui-btn-flat::before {
+  height: 48px;
+  border-radius: 24px;
+}
+.ui-appbar .ui-btn.ui-btn-icon,
+header .ui-btn.ui-btn-icon {
+  background-color: transparent;
+  position: relative;
+  width: 24px;
+  height: 24px;
+  min-height: 24px;
+  margin-right: 8px;
+}
+.ui-appbar .ui-btn.ui-btn-icon::before,
+header .ui-btn.ui-btn-icon::before {
+  width: 48px;
+  height: 48px;
+}
+.ui-appbar .ui-btn.ui-btn-icon::after,
+header .ui-btn.ui-btn-icon::after {
+  width: 24px;
+  height: 24px;
+}
+.ui-appbar .ui-btn.ui-btn-icon-back::after,
+header .ui-btn.ui-btn-icon-back::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_back_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_back_mtrl.svg");
+}
+.ui-appbar .ui-btn.ui-btn-icon-more::after,
+header .ui-btn.ui-btn-icon-more::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_more_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_more_mtrl.svg");
+}
+.ui-appbar .ui-btn.ui-btn-icon-search::after,
+header .ui-btn.ui-btn-icon-search::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_search_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_search_mtrl.svg");
+}
+.ui-appbar .ui-btn.ui-btn-icon-add::after,
+header .ui-btn.ui-btn-icon-add::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_add_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_add_mtrl.svg");
+}
+.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat,
+header .ui-btn.ui-btn-icon.ui-btn-flat {
+  min-height: 24px;
+  display: block;
+  margin-top: auto;
+  margin-bottom: auto;
+}
+.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat::after,
+header .ui-btn.ui-btn-icon.ui-btn-flat::after {
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  width: 24px;
+  height: 24px;
+}
+.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat::before,
+header .ui-btn.ui-btn-icon.ui-btn-flat::before {
+  background-color: transparent;
+  width: 48px;
+  height: 48px;
+}
+.ui-appbar .ui-btn.ui-btn-icon.ui-btn-icon-back,
+header .ui-btn.ui-btn-icon.ui-btn-icon-back {
+  margin-left: 20px;
+  margin-right: 12px;
+}
+.ui-appbar .ui-appbar-controls-container,
+header .ui-appbar-controls-container {
+  -webkit-flex: 0 0 56px;
+      -ms-flex: 0 0 56px;
+          flex: 0 0 56px;
+  width: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-align-items: flex-start;
+      -ms-flex-align: start;
+          align-items: flex-start;
+  position: absolute;
+  bottom: 0;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-left-icons-container,
+header .ui-appbar-controls-container .ui-appbar-left-icons-container {
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  min-width: 24px;
+  margin-top: auto;
+  margin-bottom: auto;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container,
+header .ui-appbar-controls-container .ui-appbar-title-container {
+  height: 56px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  margin: auto 0;
+  overflow: hidden;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: flex-start;
+      -ms-flex-align: start;
+          align-items: flex-start;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container .ui-appbar-title,
+header .ui-appbar-controls-container .ui-appbar-title-container .ui-appbar-title {
+  max-width: 100%;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  font-size: 19px;
+  color: var(--appbar-main-text-color);
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-subtitle .ui-appbar-subtitle,
+header .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-subtitle .ui-appbar-subtitle {
+  font-size: 13px;
+  color: var(--appbar-subtitle-color);
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-multiline .ui-appbar-title,
+header .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-multiline .ui-appbar-title {
+  font-size: 17px;
+  color: var(--appbar-miltiline-title-color);
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container,
+header .ui-appbar-controls-container .ui-appbar-action-buttons-container {
+  height: 100%;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  margin-left: auto;
+  min-width: 24px;
+  margin-top: auto;
+  margin-bottom: auto;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-justify-content: flex-end;
+      -ms-flex-pack: end;
+          justify-content: flex-end;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn,
+header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn {
+  margin-right: 12px;
+  margin-left: 12px;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn:last-child,
+header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn:last-child {
+  margin-right: 20px;
+  margin-left: 15px;
+}
+.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn + .ui-btn-icon,
+header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn + .ui-btn-icon {
+  margin-left: 3px;
+}
+.ui-appbar .ui-appbar-expanded-title-container,
+header .ui-appbar-expanded-title-container {
+  -webkit-flex: 1 1 auto;
+      -ms-flex: 1 1 auto;
+          flex: 1 1 auto;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  opacity: 0;
+  height: 0;
+}
+.ui-appbar .ui-appbar-expanded-title-container .ui-appbar-title,
+header .ui-appbar-expanded-title-container .ui-appbar-title {
+  line-height: 54px;
+  font-size: 38px;
+  font-family: Roboto-Light;
+  margin-left: 24px;
+  margin-right: 24px;
+  text-align: center;
+}
+.ui-appbar .ui-appbar-expanded-title-container .ui-appbar-subtitle,
+header .ui-appbar-expanded-title-container .ui-appbar-subtitle {
+  line-height: 20px;
+  font-size: 15px;
+  text-align: center;
+}
+.ui-appbar h1,
+header h1,
+.ui-appbar h2,
+header h2,
+.ui-appbar h3,
+header h3,
+.ui-appbar h4,
+header h4,
+.ui-appbar h5,
+header h5,
+.ui-appbar h6,
+header h6 {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  outline: 0;
+  font-weight: inherit;
+  font-style: inherit;
+  font-size: 100%;
+  font-family: inherit;
+  vertical-align: baseline;
+}
+.ui-appbar.ui-appbar-expanded,
+header.ui-appbar-expanded {
+  height: calc(39.67% -  12px);
+}
+.ui-appbar.ui-appbar-expanded .ui-appbar-expanded-title-container,
+header.ui-appbar-expanded .ui-appbar-expanded-title-container {
+  opacity: 1;
+}
+.ui-appbar.ui-appbar-dragging .ui-appbar-expanded-title-container,
+header.ui-appbar-dragging .ui-appbar-expanded-title-container {
+  overflow: hidden;
+}
+.ui-appbar .ui-label-select-all,
+header .ui-label-select-all {
+  font-family: Roboto-Regular;
+  font-size: 12px;
+  width: 32px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  padding-top: 10px;
+  line-height: 14px;
+  margin-left: 18px;
+  margin-right: 18px;
+}
+.ui-appbar .ui-label-select-all input[type="checkbox"].ui-checkbox,
+header .ui-label-select-all input[type="checkbox"].ui-checkbox {
+  margin: 0 0 -3px 0;
+}
+.ui-appbar .ui-appbar-container,
+header .ui-appbar-container {
+  height: 70px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-order: 10;
+      -ms-flex-order: 10;
+          order: 10;
+  background-color: var(--background-area-color);
+  border-radius: 26px;
+  overflow: hidden;
+  box-sizing: border-box;
+  box-shadow: 0 0 0 0.25px var(--content-area-line-color) inset;
+}
+.ui-appbar .ui-appbar-container > :first-child,
+header .ui-appbar-container > :first-child {
+  margin-left: 24px;
+}
+.ui-appbar .ui-appbar-container .ui-title,
+header .ui-appbar-container .ui-title {
+  font-size: 18px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-appbar .ui-appbar-container .ui-icon,
+header .ui-appbar-container .ui-icon {
+  width: 21px;
+  height: 21px;
+  overflow: hidden;
+  margin-right: 22px;
+}
+.ui-appbar .ui-appbar-container .ui-icon img,
+header .ui-appbar-container .ui-icon img {
+  width: 100%;
+}
+.ui-appbar .ui-appbar-container .ui-btn.ui-btn-icon.ui-btn-icon-only,
+header .ui-appbar-container .ui-btn.ui-btn-icon.ui-btn-icon-only {
+  height: 48px;
+  max-width: 48px;
+}
+@media all and (min-height: 580px) and (orientation: landscape) {
+  .ui-appbar.ui-appbar-expanded {
+    height: calc(30% -  12px);
+  }
+}
+@media all and (min-height: 960px) {
+  .ui-appbar.ui-appbar-expanded {
+    height: calc(25% -  12px);
+  }
+}
+.ui-card {
+  border-radius: 26px;
+  overflow: hidden;
+  box-sizing: border-box;
+  margin-bottom: 10px;
+}
+.ui-card.ui-card-service {
+  background-color: var(--background-area-color);
+  border-radius: 26px;
+  overflow: hidden;
+  box-sizing: border-box;
+  box-shadow: 0 0 0 0.25px var(--content-area-line-color) inset;
+}
+.ui-card.ui-card-service *::-webkit-scrollbar {
+  display: none;
+}
+.ui-card.ui-card-service .ui-subheader-text {
+  color: #7b7b7b;
+}
+.ui-card.ui-card-service .ui-content-subheader {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-card.ui-card-service .ui-content-subheader::after {
+  content: "";
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  width: calc(100% - 20px);
+  border-bottom: 1px solid var(--subheader-divider-color);
+  height: 0;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  margin-right: 20px;
+  margin-left: 10px;
+}
+.ui-card.ui-card-service .ui-content-thumbnail {
+  width: 100%;
+}
+.ui-card.ui-card-service .ui-content .ui-title.ui-title-medium {
+  font-size: 18px;
+  font-family: Roboto-Medium;
+}
+.ui-card.ui-card-service .ui-content.ui-scrollview-clip {
+  border-radius: 0;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-icon {
+  width: 58px;
+  height: 58px;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-icon img {
+  width: 58px;
+  height: 58px;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-text {
+  padding: 25px 0 23px;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-text-title {
+  font-size: 16px;
+}
+.ui-card.ui-card-service .ui-listview li .ui-li-text-sub {
+  font-size: 12px;
+}
+.ui-card .ui-header {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  height: 46px;
+  padding: 0 20px;
+}
+.ui-card .ui-header .ui-title {
+  margin-top: 24px;
+  margin-bottom: 3px;
+  font-size: 15px;
+  color: var(--text-color);
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  display: inline-block;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-card .ui-header .ui-icon {
+  margin-right: 10px;
+  margin-top: 20px;
+  width: 26px;
+  height: 26px;
+  -webkit-order: 0;
+      -ms-flex-order: 0;
+          order: 0;
+  display: inline-block;
+}
+.ui-card .ui-header .ui-icon img {
+  width: 100%;
+  height: 100%;
+}
+.ui-card .ui-header .ui-controls {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  margin-top: 20px;
+  height: 26px;
+}
+.ui-card .ui-header .ui-controls .ui-btn {
+  width: 26px;
+  height: 26px;
+  background-color: transparent;
+  min-height: 26px;
+  padding: 0;
+  display: inline-block;
+}
+.ui-card .ui-header .ui-controls .ui-btn ~ .ui-btn {
+  margin-left: 14px;
+}
+.ui-card .ui-header .ui-controls .ui-btn::before {
+  height: 26px;
+}
+.ui-card .ui-header .ui-controls .ui-btn::after {
+  background-color: var(--background-area-color);
+  height: 26px;
+  width: 26px;
+}
+.ui-card .ui-content,
+.ui-card .ui-content.ui-scrollview-clip {
+  padding: 10px 20px;
+}
+.ui-card .ui-content.ui-tabs,
+.ui-card .ui-content.ui-scrollview-clip.ui-tabs {
+  padding: 0;
+}
+.ui-card .ui-content .ui-section-changer .ui-content,
+.ui-card .ui-content.ui-scrollview-clip .ui-section-changer .ui-content {
+  padding: 0;
+}
+.ui-card .ui-content .ui-title,
+.ui-card .ui-content.ui-scrollview-clip .ui-title {
+  font-size: 16px;
+}
+.ui-card .ui-content .ui-description,
+.ui-card .ui-content.ui-scrollview-clip .ui-description {
+  font-size: 14px;
+}
+.ui-card .ui-content video,
+.ui-card .ui-content.ui-scrollview-clip video {
+  border-radius: 26px;
+}
+.ui-card .ui-content .ui-btn,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn {
+  width: 86px;
+  padding: 0;
+}
+.ui-card .ui-content .ui-btn .ui-btn-content,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content {
+  width: 86px;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-card .ui-content .ui-btn .ui-btn-content img,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content img {
+  border-radius: 15px;
+  width: 80px;
+  height: 80px;
+  margin-bottom: 8px;
+}
+.ui-card .ui-content .ui-btn .ui-btn-content .ui-title,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content .ui-title {
+  font-size: 14px;
+  color: var(--text-color);
+  line-height: 16px;
+}
+.ui-card .ui-content .ui-btn .ui-btn-content .ui-subtitle,
+.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content .ui-subtitle {
+  font-size: 12px;
+  color: var(--text-secondary-color);
+  line-height: 14px;
+}
+.ui-card .ui-container-item img {
+  border-radius: 16px;
+  width: 188px;
+  height: 126px;
+  margin-bottom: 17px;
+}
+.ui-card .ui-container-item .ui-title {
+  font-family: Roboto-Medium;
+  color: var(--text-color);
+  font-size: 16px;
+  line-height: 19px;
+  text-align: left;
+  white-space: normal;
+  margin-bottom: 6px;
+}
+.ui-card .ui-container-item .ui-subtitle {
+  font-family: Roboto-Regular;
+  color: var(--text-secondary-color);
+  font-size: 14px;
+  line-height: 16px;
+  text-align: left;
+  white-space: normal;
+}
+.ui-card .ui-footer {
+  height: 63px;
+  -webkit-justify-content: flex-end;
+      -ms-flex-pack: end;
+          justify-content: flex-end;
+  padding: 0 20px;
+}
+.ui-card .ui-footer .ui-btn {
+  display: inline-block;
+  width: auto;
+  height: 43px;
+  color: var(--color-white);
+  font-size: 14px;
+  background-color: var(--primary-dark-color);
+}
+.ui-card .ui-sub-tab {
+  background-color: transparent;
+}
+.ui-card.ui-card-ads {
+  background-color: var(--background-area-color);
+  min-height: 200px;
+}
+.ui-card.ui-card-ads .ui-content {
+  padding: 0;
+  border-radius: 0;
+}
+.ui-card.ui-card-ads .ui-content .ui-scrollview-view {
+  overflow: hidden;
+}
+.ui-card.ui-card-ads .ui-content video,
+.ui-card.ui-card-ads .ui-content img {
+  border-radius: 0;
+  width: 100%;
+}
+.ui-card.ui-card-ads .ui-content .ui-title {
+  font-family: Roboto-Medium;
+  color: var(--text-color);
+  font-size: 16px;
+  white-space: normal;
+  margin: 0 20px;
+}
+.ui-card.ui-card-ads .ui-content .ui-title:last-child {
+  margin-top: 15px;
+}
+.ui-card.ui-card-ads .ui-content .ui-subtitle {
+  font-family: Roboto-Regular;
+  color: var(--text-secondary-color);
+  font-size: 14px;
+  white-space: normal;
+  margin: 0 20px;
+}
+.ui-card.ui-card-ads .ui-content .ui-banner {
+  position: relative;
+  width: 100%;
+  height: 150px;
+  overflow: hidden;
+}
+.ui-card.ui-card-ads .ui-content .ui-banner img {
+  width: 100%;
+  position: absolute;
+}
+.ui-card.ui-card-ads .ui-footer .ui-title {
+  font-family: Roboto-Medium;
+  color: var(--text-color);
+  font-size: 16px;
+  white-space: normal;
+  margin: 0 20px 0 0;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: left;
+}
+.LESSui-footer {
+  box-sizing: border-box;
+  padding: 12px 24px;
+  text-align: center;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+}
+.LESSui-footer .ui-btn:not(.ui-btn-contained) {
+  height: 52px;
+  line-height: 52px;
+  margin: 0 auto;
+  max-width: 248px;
+}
+.LESSui-footer .ui-btn.ui-btn-contained:not(.ui-btn-inline) {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained) {
+  background-color: var(--button-background);
+}
+.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-btn-active::before {
+  background-color: var(--ripple-color);
+}
+.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-state-disabled {
+  background-color: var(--button-background);
+}
+.LESSui-footer .ui-btn ~ .ui-btn {
+  margin-left: 16px;
+}
+.LESSui-footer .ui-btn.ui-btn-contained ~ .ui-btn.ui-btn-contained {
+  margin-left: 8px;
+}
+.LESSui-footer.ui-grid-col-1 .ui-btn.ui-inline,
+.LESSui-footer.ui-grid-col-2 .ui-btn.ui-inline,
+.LESSui-footer.ui-grid-col-3 .ui-btn.ui-inline {
+  display: block;
+  width: 100%;
+}
+.LESSui-footer.ui-bottom-button {
+  height: 56px;
+  padding-left: 24px;
+  padding-right: 24px;
+}
+.ui-footer {
+  width: 100%;
+  box-sizing: border-box;
+  padding: 12px 24px;
+  text-align: center;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+}
+.ui-footer .ui-btn:not(.ui-btn-contained) {
+  height: 52px;
+  line-height: 52px;
+  margin: 0 auto;
+  max-width: 248px;
+}
+.ui-footer .ui-btn.ui-btn-contained:not(.ui-btn-inline) {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained) {
+  background-color: var(--button-background);
+}
+.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-btn-active::before {
+  background-color: var(--ripple-color);
+}
+.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-state-disabled {
+  background-color: var(--button-background);
+}
+.ui-footer .ui-btn ~ .ui-btn {
+  margin-left: 16px;
+}
+.ui-footer .ui-btn.ui-btn-contained ~ .ui-btn.ui-btn-contained {
+  margin-left: 8px;
+}
+.ui-footer.ui-grid-col-1 .ui-btn.ui-inline,
+.ui-footer.ui-grid-col-2 .ui-btn.ui-inline,
+.ui-footer.ui-grid-col-3 .ui-btn.ui-inline {
+  display: block;
+  width: 100%;
+}
+.ui-footer.ui-bottom-button {
+  height: 56px;
+  padding-left: 24px;
+  padding-right: 24px;
+}
+.ui-page:not(.ui-page-flex) .ui-footer {
+  position: fixed;
+  bottom: 0;
+}
+.ui-page.ui-page-flex .ui-footer {
+  overflow: visible;
+}
+.ui-page-container,
+.ui-page-container body {
+  height: 100%;
+  font-size: 22px;
+}
+@media all and (max-width: 359px) {
+  .ui-page-container,
+  .ui-page-container body {
+    font-size: 19px;
+  }
+}
+.ui-page-container fieldset,
+.ui-page {
+  padding: 0;
+  margin: 0;
+}
+.ui-page-container a img,
+.ui-page-container fieldset {
+  border: 0;
+}
+.ui-page-container {
+  margin: 0;
+  overflow-x: hidden;
+  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+[data-role=page],
+[data-role=dialog],
+.ui-page {
+  top: 0;
+  left: 0;
+  width: 100%;
+  position: absolute;
+  display: none;
+  border: 0;
+}
+[data-role=page].ui-page-build,
+[data-role=dialog].ui-page-build,
+.ui-page.ui-page-build {
+  display: block;
+  visibility: hidden;
+}
+[data-role=page].ui-pre-in,
+[data-role=dialog].ui-pre-in,
+.ui-page.ui-pre-in {
+  z-index: 100;
+}
+[data-role=page].ui-pre-in,
+[data-role=dialog].ui-pre-in,
+.ui-page.ui-pre-in,
+[data-role=page].ui-page-active,
+[data-role=dialog].ui-page-active,
+.ui-page.ui-page-active {
+  display: block;
+  overflow: hidden;
+}
+[data-role=page].ui-pre-in.ui-page-flex,
+[data-role=dialog].ui-pre-in.ui-page-flex,
+.ui-page.ui-pre-in.ui-page-flex,
+[data-role=page].ui-page-active.ui-page-flex,
+[data-role=dialog].ui-page-active.ui-page-flex,
+.ui-page.ui-page-active.ui-page-flex {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-align-content: stretch;
+      -ms-flex-line-pack: stretch;
+          align-content: stretch;
+}
+[data-role=page].ui-pre-in.ui-page-flex .ui-header,
+[data-role=dialog].ui-pre-in.ui-page-flex .ui-header,
+.ui-page.ui-pre-in.ui-page-flex .ui-header,
+[data-role=page].ui-page-active.ui-page-flex .ui-header,
+[data-role=dialog].ui-page-active.ui-page-flex .ui-header,
+.ui-page.ui-page-active.ui-page-flex .ui-header {
+  position: relative;
+}
+[data-role=page].ui-pre-in.ui-page-flex .ui-content,
+[data-role=dialog].ui-pre-in.ui-page-flex .ui-content,
+.ui-page.ui-pre-in.ui-page-flex .ui-content,
+[data-role=page].ui-page-active.ui-page-flex .ui-content,
+[data-role=dialog].ui-page-active.ui-page-flex .ui-content,
+.ui-page.ui-page-active.ui-page-flex .ui-content {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-page-container,
+.ui-page-container .ui-page {
+  color: var(--text-color);
+  background-image: none;
+  background-color: var(--background-color);
+}
+.ui-page-container.ui-page-light,
+.ui-page-container .ui-page.ui-page-light {
+  background-image: none;
+}
+.ui-page.ui-mobile-touch-overflow,
+.ui-mobile-touch-overflow.ui-native-fixed .ui-content {
+  overflow: auto;
+  height: 100%;
+  -webkit-overflow-scrolling: touch;
+}
+.ui-page.ui-mobile-touch-overflow,
+.ui-page.ui-mobile-touch-overflow * {
+  transform: rotateY(0);
+  -ms-transform: rotateY(0);
+  -moz-transform: rotateY(0);
+  -webkit-transform: rotateY(0);
+  -o-transform: rotateY(0);
+}
+.ui-page.ui-mobile-pre-transition {
+  display: block;
+}
+.ui-blocker {
+  width: 100%;
+  height: 100%;
+  z-index: 2147483647;
+}
+.ui-mobile-rendering > * {
+  visibility: hidden;
+}
+.ui-bar,
+.ui-body {
+  position: relative;
+  padding: .4em 15px;
+  overflow: hidden;
+  display: block;
+  clear: both;
+}
+.ui-bar {
+  font-size: 16px;
+  margin: 0;
+}
+.ui-bar h1,
+.ui-bar h2,
+.ui-bar h3,
+.ui-bar h4,
+.ui-bar h5,
+.ui-bar h6 {
+  margin: 0;
+  padding: 0;
+  font-size: 16px;
+  display: inline-block;
+}
+.ui-content {
+  border-width: 0;
+  overflow-y: visible;
+  overflow-x: hidden;
+  -webkit-flex-shrink: 1;
+      -ms-flex-negative: 1;
+          flex-shrink: 1;
+  border-radius: 26px;
+}
+.ui-content.ui-content-padding,
+.ui-content.ui-content-padding.ui-scrollview-clip {
+  padding-left: 12px;
+  padding-right: 12px;
+}
+.ui-content.ui-content-under-popup {
+  pointer-events: none;
+}
+.ui-content .ui-content-area {
+  background-color: var(--background-area-color);
+  border-radius: 26px;
+  overflow: hidden;
+  box-sizing: border-box;
+  box-shadow: 0 0 0 0.25px var(--content-area-line-color) inset;
+  margin: auto auto 16px auto;
+}
+@media (min-width: 673px) and (min-height: 411px) {
+  .ui-content .ui-content-area {
+    width: 90%;
+  }
+}
+@media (min-width: 960px) {
+  .ui-content .ui-content-area {
+    width: 75%;
+  }
+}
+.ui-content .ui-content-area-disabled-top-rounding {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+  -webkit-mask-box-image-width: 0 26px 26px;
+          mask-border-width: 0 26px 26px;
+}
+.ui-content .ui-content-area ~ .ui-content-subheader {
+  margin-top: -16px;
+}
+.ui-content .ui-content-subheader {
+  color: var(--text-secondary-color);
+  font-family: Roboto-Medium;
+  font-size: 14px;
+  padding-bottom: 7px;
+  padding-top: 13px;
+  margin-left: 24px;
+  line-height: 16px;
+}
+body.ui-theme-dark .ui-content-area {
+  box-shadow: unset;
+}
+.ui-page-fullscreen .ui-content {
+  padding: 0;
+}
+.ui-mobile-touch-overflow.ui-native-fixed .ui-content {
+  padding-top: 2.5em;
+  padding-bottom: 3em;
+  top: 0;
+  bottom: 0;
+  height: auto;
+  position: absolute;
+}
+.ui-mobile-touch-overflow.ui-native-fullscreen .ui-content {
+  padding-top: 0;
+  padding-bottom: 0;
+}
+.ui-native-bars-hidden {
+  display: none;
+}
+.ui-screen-hidden {
+  display: none;
+}
+.ui-icon {
+  width: 18px;
+  height: 18px;
+}
+.ui-fullscreen img {
+  max-width: 100%;
+}
+.ui-nojs {
+  position: absolute;
+  left: -9999px;
+}
+.scrolling-scrollbar {
+  position: absolute;
+  pointer-events: none;
+}
+.scrolling-scrollbar .scrolling-scrollthumb {
+  background-color: #71cbd9;
+  position: absolute;
+}
+.scrolling-scrollbar.scrolling-direction-y {
+  right: 11px;
+  width: 10px;
+}
+.scrolling-scrollbar.scrolling-direction-y .scrolling-scrollthumb {
+  width: 10px;
+  min-height: 44px;
+  top: 0;
+  left: 50%;
+  margin-left: -5px;
+}
+.scrolling-scrollbar.scrolling-direction-x {
+  bottom: 11px;
+  height: 10px;
+}
+.scrolling-scrollbar.scrolling-direction-x .scrolling-scrollthumb {
+  height: 10px;
+  min-width: 37px;
+  left: 0;
+  top: 50%;
+  margin-top: -5px;
+}
+input[type="checkbox"].ui-checkbox:not(.ui-toggle-switch) {
+  position: relative;
+  height: 32px;
+  width: 32px;
+  box-sizing: border-box;
+  outline: none;
+  -webkit-appearance: none;
+  margin: 0 18px;
+}
+@-webkit-keyframes checkbox-in {
+  from {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+  to {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+}
+@keyframes checkbox-in {
+  from {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+  to {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+}
+@-webkit-keyframes checkbox-out {
+  from {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+  to {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+}
+@keyframes checkbox-out {
+  from {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+  to {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+}
+input[type="checkbox"].ui-checkbox::before {
+  content: "";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 32px;
+  height: 32px;
+  background-color: var(--ripple-color);
+  border-radius: 100%;
+  opacity: 0;
+}
+input[type="checkbox"].ui-checkbox::after {
+  content: "";
+  position: absolute;
+  bottom: 0;
+  opacity: 0.8;
+  background-color: var(--control-inactive-color);
+  -webkit-animation-duration: 250ms;
+          animation-duration: 250ms;
+  -webkit-animation-fill-mode: both;
+          animation-fill-mode: both;
+  -webkit-animation-timing-function: steps(26);
+          animation-timing-function: steps(26);
+  width: 100%;
+  height: 100%;
+  -webkit-mask-image: url("images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg");
+          mask-image: url("images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg");
+  -webkit-mask-size: auto 100%;
+          mask-size: auto 100%;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  -webkit-mask-position: 0 0;
+          mask-position: 0 0;
+}
+input[type="checkbox"].ui-checkbox.ui-checkbox-backward-animation::after {
+  -webkit-animation-name: checkbox-out;
+          animation-name: checkbox-out;
+}
+input[type="checkbox"].ui-checkbox:checked::after {
+  background-color: var(--control-active-color);
+  -webkit-animation-name: checkbox-in;
+          animation-name: checkbox-in;
+}
+input[type="checkbox"].ui-checkbox:active::before {
+  opacity: 1;
+}
+input[type="checkbox"].ui-checkbox:disabled {
+  opacity: 0.4;
+}
+input[type="checkbox"].ui-checkbox.ui-checkbox-focus {
+  outline: 2px solid var(--primary-color);
+}
+@-webkit-keyframes radio-in {
+  from {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+  to {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+}
+@keyframes radio-in {
+  from {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+  to {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+}
+@-webkit-keyframes radio-out {
+  from {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+  to {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+}
+@keyframes radio-out {
+  from {
+    -webkit-mask-position: 100% 0;
+            mask-position: 100% 0;
+  }
+  to {
+    -webkit-mask-position: 0 0;
+            mask-position: 0 0;
+  }
+}
+input[type="radio"].ui-radio {
+  position: relative;
+  height: 32px;
+  width: 32px;
+  box-sizing: border-box;
+  outline: none;
+  -webkit-appearance: none;
+  margin: 0 18px;
+}
+input[type="radio"].ui-radio::before {
+  content: "";
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 32px;
+  height: 32px;
+  background-color: var(--ripple-color);
+  border-radius: 100%;
+  opacity: 0;
+}
+input[type="radio"].ui-radio::after {
+  content: "";
+  position: absolute;
+  bottom: 0;
+  opacity: 0.8;
+  background-color: var(--control-inactive-color);
+  -webkit-animation-fill-mode: forwards;
+          animation-fill-mode: forwards;
+  -webkit-animation-duration: 250ms;
+          animation-duration: 250ms;
+  -webkit-animation-timing-function: steps(26);
+          animation-timing-function: steps(26);
+  width: 100%;
+  height: 100%;
+  -webkit-mask-image: url("images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg");
+          mask-image: url("images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg");
+  -webkit-mask-size: auto 100%;
+          mask-size: auto 100%;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  -webkit-mask-position: 0 0;
+          mask-position: 0 0;
+}
+input[type="radio"].ui-radio.ui-radio-backward-animation::after {
+  -webkit-animation-name: radio-out;
+          animation-name: radio-out;
+}
+input[type="radio"].ui-radio:checked::after {
+  background-color: var(--control-active-color);
+  -webkit-animation-name: radio-in;
+          animation-name: radio-in;
+}
+input[type="radio"].ui-radio:active::before {
+  opacity: 1;
+}
+input[type="radio"].ui-radio:disabled {
+  opacity: 0.4;
+}
+@-webkit-keyframes EXPAND {
+  0% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+  50% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1.3);
+    -ms-transform: translate(-50%, -50%) scale(1.3);
+    transform: translate(-50%, -50%) scale(1.3);
+  }
+  100% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(1.3);
+    -ms-transform: translate(-50%, -50%) scale(1.3);
+    transform: translate(-50%, -50%) scale(1.3);
+  }
+}
+@keyframes EXPAND {
+  0% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+  50% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1.3);
+    -ms-transform: translate(-50%, -50%) scale(1.3);
+    transform: translate(-50%, -50%) scale(1.3);
+  }
+  100% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(1.3);
+    -ms-transform: translate(-50%, -50%) scale(1.3);
+    transform: translate(-50%, -50%) scale(1.3);
+  }
+}
+.ui-text-input-container {
+  width: 100%;
+}
+textarea.ui-text-input {
+  resize: none;
+  overflow: hidden;
+  white-space: normal;
+  transition: height 200ms linear;
+}
+.ui-group-index + .ui-li-static input.ui-text-input,
+.ui-group-index + .ui-li-static textarea.ui-text-input {
+  padding: 0 13px 0 5px;
+}
+.ui-group-index + .ui-li-static input.ui-text-input + .ui-text-input-textline,
+.ui-group-index + .ui-li-static textarea.ui-text-input + .ui-text-input-textline {
+  margin: 5.5px 8px 10px 0px;
+}
+.ui-group-index + .ui-li-static input.ui-text-input ~ .ui-text-input-clear,
+.ui-group-index + .ui-li-static textarea.ui-text-input ~ .ui-text-input-clear {
+  right: 0;
+}
+.ui-group-index + .ui-li-static input.ui-text-input:focus.ui-text-input-clear-active,
+.ui-group-index + .ui-li-static textarea.ui-text-input:focus.ui-text-input-clear-active {
+  padding-right: 40px;
+}
+.ui-li-static input.ui-text-input + .ui-text-input-textline,
+.ui-li-static textarea.ui-text-input + .ui-text-input-textline {
+  position: absolute;
+  width: calc(100% -  32px);
+}
+.ui-li-static input.ui-text-input + .ui-text-input-textline + .ui-text-input-error-message,
+.ui-li-static textarea.ui-text-input + .ui-text-input-textline + .ui-text-input-error-message {
+  margin: 8px 0 0 0;
+}
+.ui-li-flex input.ui-text-input,
+.ui-li-flex textarea.ui-text-input {
+  padding: 0 5px;
+}
+.ui-li-flex input.ui-text-input + .ui-text-input-textline,
+.ui-li-flex textarea.ui-text-input + .ui-text-input-textline {
+  margin: 5.5px 0 -6px 0;
+}
+.ui-li-flex input.ui-text-input ~ .ui-text-input-clear,
+.ui-li-flex textarea.ui-text-input ~ .ui-text-input-clear {
+  top: 0;
+  margin-top: -35px;
+  margin-bottom: -6px;
+  right: 0;
+}
+.ui-popup textarea.ui-text-input {
+  min-height: 27px;
+  padding: 0;
+}
+.ui-popup textarea.ui-text-input + .ui-text-input-textline {
+  margin-left: 0;
+  margin-right: 0;
+  margin-bottom: 5.5px;
+}
+input.ui-text-input,
+textarea.ui-text-input {
+  border: 0;
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  box-sizing: border-box;
+  display: block;
+  width: 100%;
+  line-height: 26px;
+  font-family: Roboto-Regular;
+  -webkit-text-fill-color: transparent;
+  font-size: 19px;
+  background-color: transparent;
+  border: none;
+  caret-color: var(--primary-color);
+  margin: 8px 0 8px 0;
+}
+input.ui-text-input.ui-text-input-disabled,
+textarea.ui-text-input.ui-text-input-disabled,
+input.ui-text-input:disabled,
+textarea.ui-text-input:disabled {
+  text-shadow: 0 0 0 var(--text-input-disabled);
+}
+input.ui-text-input.ui-text-input-disabled::-webkit-input-placeholder,
+textarea.ui-text-input.ui-text-input-disabled::-webkit-input-placeholder,
+input.ui-text-input:disabled::-webkit-input-placeholder,
+textarea.ui-text-input:disabled::-webkit-input-placeholder {
+  text-shadow: 0 0 0 var(--text-input-disabled);
+}
+input.ui-text-input:not([disabled]),
+textarea.ui-text-input:not([disabled]) {
+  text-shadow: 0 0 0 var(--text-color);
+}
+input.ui-text-input:not([disabled])::-webkit-input-placeholder,
+textarea.ui-text-input:not([disabled])::-webkit-input-placeholder {
+  text-shadow: 0 0 0 var(--text-input-underline-inactive);
+}
+input.ui-text-input + .ui-text-input-textline,
+textarea.ui-text-input + .ui-text-input-textline {
+  height: 1px;
+  background: var(--text-input-underline-inactive);
+  box-sizing: border-box;
+  display: block;
+}
+input.ui-text-input + .ui-text-input-textline + .ui-text-input-error-message,
+textarea.ui-text-input + .ui-text-input-textline + .ui-text-input-error-message {
+  display: none;
+  color: var(--text-input-invalid-color);
+  font-size: 12px;
+}
+input.ui-text-input:focus,
+textarea.ui-text-input:focus {
+  outline: none;
+}
+input.ui-text-input:focus.ui-text-input-clear-active,
+textarea.ui-text-input:focus.ui-text-input-clear-active {
+  padding-right: 11px;
+}
+input.ui-text-input:focus + .ui-text-input-textline,
+textarea.ui-text-input:focus + .ui-text-input-textline {
+  height: 2px;
+  background: var(--primary-color);
+}
+input.ui-text-input:invalid + .ui-text-input-textline,
+textarea.ui-text-input:invalid + .ui-text-input-textline {
+  background: var(--text-input-invalid-color);
+}
+input.ui-text-input:invalid + .ui-text-input-textline + .ui-text-input-error-message,
+textarea.ui-text-input:invalid + .ui-text-input-textline + .ui-text-input-error-message {
+  display: block;
+}
+input.ui-text-input ~ .ui-text-input-clear,
+textarea.ui-text-input ~ .ui-text-input-clear {
+  display: block;
+  float: right;
+  top: -33.5px;
+  box-sizing: border-box;
+  margin-right: -8.5px;
+  margin-left: 8.5px;
+  position: relative;
+  width: 40px;
+  height: 40px;
+}
+input.ui-text-input ~ .ui-text-input-clear.ui-btn.ui-btn-icon.ui-btn-nobg::after,
+textarea.ui-text-input ~ .ui-text-input-clear.ui-btn.ui-btn-icon.ui-btn-nobg::after {
+  -webkit-mask-image: url("images/controls/core_button_icon_clear.png");
+          mask-image: url("images/controls/core_button_icon_clear.png");
+  width: 40px;
+  height: 40px;
+}
+input.ui-text-input ~ .ui-text-input-clear-hidden,
+textarea.ui-text-input ~ .ui-text-input-clear-hidden {
+  visibility: hidden;
+}
+input.ui-text-input.ui-text-input-widget-focused,
+textarea.ui-text-input.ui-text-input-widget-focused {
+  background-color: var(--textual-background);
+}
+/*special case of buttons and text-inputs:
+- wrapper is added
+- animation for buttons on white background
+*/
+.ui-textinput-box-with-right-button {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-wrap: nowrap;
+  -ms-flex-wrap: nowrap;
+  -o-flex-wrap: nowrap;
+  flex-wrap: nowrap;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  height: 40px;
+}
+.ui-textinput-box-with-right-button > * {
+  height: 33.5px;
+  margin-top: 3.5px;
+  -webkit-flex-grow: 1;
+      -ms-flex-positive: 1;
+          flex-grow: 1;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item),
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item),
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg {
+  max-width: 64px;
+  min-width: 40px;
+  -ms-flex-basis: auto;
+  -o-flex-basis: auto;
+  -webkit-flex-basis: auto;
+      -ms-flex-preferred-size: auto;
+          flex-basis: auto;
+  -webkit-order: 1;
+  -moz-order: 1;
+  -ms-order: 1;
+  -o-order: 1;
+  -ms-flex-order: 1;
+      order: 1;
+  width: auto;
+  box-sizing: content-box;
+  margin: 0 10px 0 0;
+  height: 40px;
+  min-height: 40px;
+  max-height: 40px;
+  padding: 0 6px;
+  background-color: transparent;
+  overflow-x: visible;
+  overflow-y: visible;
+  color: #52c7d9;
+  -webkit-mask-box-image-source: none;
+  -webkit-align-self: flex-start;
+  -ms-align-self: flex-start;
+  -o-align-self: flex-start;
+  -ms-flex-item-align: start;
+      align-self: flex-start;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::after,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::after,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg::after,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg::after {
+  background-color: #52c7d9;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg::before,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg::before {
+  background-color: var(--ripple-color);
+  opacity: 0;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active::before,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active::before,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-active::before,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-active::before {
+  -webkit-animation: EXPAND 200ms;
+  animation: EXPAND 200ms;
+  -webkit-animation-fill-mode: both;
+  animation-fill-mode: both;
+  opacity: 0;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon {
+  padding: 0 8.5px;
+  margin-right: 0;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::before,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::before,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon::before,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon::before {
+  border-radius: 20px;
+  width: 40px;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::after,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::after,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon::after,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon::after {
+  -webkit-mask-size: 40px, 40px;
+  -moz-mask-size: 40px, 40px;
+  -ms-mask-size: 40px, 40px;
+  -o-mask-size: 40px, 40px;
+  mask-size: 40px, 40px;
+  -webkit-mask-repeat: none;
+  -moz-mask-repeat: none;
+  -ms-mask-repeat: none;
+  -o-mask-repeat: none;
+  mask-repeat: none;
+  -webkit-mask-position: center center;
+  -moz-mask-position: center center;
+  -ms-mask-position: center center;
+  -o-mask-position: center center;
+  mask-position: center center;
+}
+.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-text-light::before,
+.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-text-light::before,
+.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-text-light::before,
+.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-text-light::before {
+  border-radius: 5px;
+  width: 58px;
+  height: 32.5px;
+}
+.ui-textinput-box-with-right-button input.ui-text-input ~ .ui-text-input-clear {
+  right: 5px;
+  left: 5px;
+}
+.ui-textinput-box-with-right-button input.ui-text-input:focus.ui-text-input-clear-active {
+  padding-right: 20px;
+  margin-right: -15px;
+}
+.ui-listview li.ui-textinput-box-with-right-button {
+  padding-right: 0;
+}
+.ui-controlgroup .ui-radio > .ui-btn {
+  background: var(--background-color);
+}
+.ui-controlgroup .ui-btn-inner.ui-corner-left {
+  border-radius: 0;
+  background-clip: padding-box;
+}
+.ui-controlgroup .ui-btn-inner.ui-corner-right.ui-controlgroup-last {
+  border-radius: 0;
+  background-clip: padding-box;
+}
+.ui-controlgroup .ui-radio-on .ui-btn-inner {
+  color: #3b7796;
+}
+.ui-controlgroup .ui-radio-off .ui-btn-inner {
+  color: #c7c7c7;
+}
+.ui-controlgroup.ui-controlgroup-horizontal .ui-radio-on .ui-btn-inner {
+  color: #fafafa;
+}
+.ui-page {
+  border-top: none;
+  background: var(--background-color);
+  color: var(--text-color);
+  font-weight: normal;
+  font-family: Roboto-Regular;
+}
+.ui-page .ui-link-inherit {
+  color: #fff;
+}
+.ui-page .ui-link {
+  color: #2489CE;
+  font-weight: bold;
+}
+.ui-page .ui-link:hover {
+  color: #2489CE;
+}
+.ui-page .ui-link:active {
+  color: #2489CE;
+}
+.ui-page .ui-link:visited {
+  color: #2489CE;
+}
+a.ui-link-inherit {
+  text-decoration: none !important;
+}
+.ui-btn-active {
+  color: var(--primary-color);
+  cursor: pointer;
+  text-decoration: none;
+  background: var(--on-background);
+  outline: none;
+}
+.ui-btn-active a.ui-link-inherit {
+  color: var(--primary-color);
+}
+.ui-corner-tl {
+  border-top-left-radius: 0.3em;
+}
+.ui-corner-tr {
+  border-top-right-radius: 0.3em;
+}
+.ui-corner-bl {
+  border-bottom-left-radius: 0.3em;
+}
+.ui-corner-br {
+  border-bottom-right-radius: 0.3em;
+}
+.ui-corner-top {
+  border-top-left-radius: 0.3em;
+  border-top-right-radius: 0.3em;
+}
+.ui-corner-bottom {
+  border-bottom-left-radius: 0.3em;
+  border-bottom-right-radius: 0.3em;
+}
+.ui-corner-right {
+  border-top-right-radius: 0.3em;
+  border-bottom-right-radius: 0.3em;
+}
+.ui-corner-left {
+  border-top-left-radius: 0.3em;
+  border-bottom-left-radius: 0.3em;
+}
+.ui-corner-none {
+  border-radius: 0;
+}
+.ui-btn .ui-icon.ui-icon-naviframe-edit,
+.ui-btn .ui-icon.ui-icon-naviframe-plus,
+.ui-btn .ui-icon.ui-icon-naviframe-delete,
+.ui-btn .ui-icon.ui-icon-naviframe-search,
+.ui-btn .ui-icon.ui-icon-naviframe-selectall,
+.ui-btn .ui-icon.ui-icon-naviframe-drawer {
+  -webkit-mask-size: 100%;
+  -moz-mask-size: 100%;
+  -ms-mask-size: 100%;
+  -o-mask-size: 100%;
+  mask-size: 100%;
+}
+.ui-popup.ui-ctxpopup {
+  width: auto;
+  padding: 0;
+  background-color: transparent;
+  margin-top: 0;
+  max-width: 100%;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content {
+  width: auto;
+  padding: 0;
+  overflow: hidden;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content > ul {
+  overflow: auto;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content > ul::-webkit-scrollbar {
+  height: 4px;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content > ul::-webkit-scrollbar-thumb {
+  background-color: var(--primary-color);
+  border-radius: 1.5px;
+  border-bottom: 1px solid #fff;
+}
+.ui-popup.ui-ctxpopup .ui-popup-content > ul::-webkit-scrollbar-button {
+  width: 2px;
+  height: 4px;
+  background-color: transparent;
+}
+.ui-popup.ui-ctxpopup .ui-popup-wrapper {
+  background-color: var(--more-options-background-color);
+  border: 1px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+  overflow: auto;
+  margin-left: 16px;
+  margin-right: 16px;
+  width: auto;
+}
+.ui-popup.ui-ctxpopup :focus {
+  outline: none;
+}
+.ui-popup.ui-ctxpopup.slideup.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: slideupfadeinfrombottom 250ms;
+          animation: slideupfadeinfrombottom 250ms;
+}
+.ui-popup.ui-ctxpopup.slideup.out {
+  -webkit-transform: translate3d(0, 5%, 0);
+  -ms-transform: translate3d(0, 5%, 0);
+  transform: translate3d(0, 5%, 0);
+  -webkit-animation: slideupfadeouttobottom 200ms;
+          animation: slideupfadeouttobottom 200ms;
+}
+.ui-popup.ui-ctxpopup .ui-listview {
+  margin: 0;
+  border: none;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-popup.ui-ctxpopup .ui-listview li {
+  -webkit-flex: 1 0 auto;
+  -moz-flex: 1 0 auto;
+  -ms-flex: 1 0 auto;
+  -o-flex: 1 0 auto;
+  flex: 1 0 auto;
+}
+.ui-popup.ui-ctxpopup .ui-listview .ui-li-anchor a {
+  font-size: 15px;
+  line-height: 20.5px;
+  padding: 0 16px;
+  min-height: 36px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview {
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview .ui-li-anchor a {
+  height: 40px;
+  -webkit-flex-direction: row;
+  -moz-flex-direction: row;
+  -ms-flex-direction: row;
+  -o-flex-direction: row;
+  flex-direction: row;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  -webkit-justify-content: flex-start;
+  -moz-justify-content: flex-start;
+  -ms-justify-content: flex-start;
+  -o-justify-content: flex-start;
+  -ms-flex-pack: start;
+      justify-content: flex-start;
+  text-align: left;
+  padding-top: 0;
+  padding-bottom: 0;
+}
+.ui-popup.ui-ctxpopup .ui-listview li {
+  color: var(--text-color);
+  font-size: 15px;
+  border-top: 0;
+  border-bottom: 0;
+  border-right: 0;
+  border-left: 1px solid var(--more-options-background-color);
+}
+.ui-popup.ui-ctxpopup .ui-listview li:first-of-type {
+  border-left-width: 0;
+}
+.ui-popup.ui-ctxpopup .ui-listview li.ui-li-anchor > a {
+  box-sizing: border-box;
+  padding-top: 7.5px;
+  padding-bottom: 7.5px;
+}
+.ui-popup.ui-ctxpopup .ui-listview li.ui-li-anchor.ui-li-active {
+  background-color: var(--more-options-pressed-color);
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-basic .ui-li-anchor {
+  padding: 0 16px;
+  height: 36px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-basic .ui-li-anchor > a {
+  padding: 0;
+  margin: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor {
+  padding: 0;
+  height: 40px;
+  width: 53px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor > a {
+  padding: 0;
+  margin: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor > a > span {
+  padding: 0;
+  margin: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor {
+  padding: 0 16px;
+  height: 59px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor > a {
+  padding: 0;
+  margin: 0;
+  font-size: 13px;
+  line-height: 20px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor > a > span {
+  padding: 0;
+  margin: 0 0 2px 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li {
+  border-top: 1px solid var(--more-options-background-color);
+  border-bottom: 0;
+  border-right: 0;
+  border-left: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li:first-of-type {
+  border-top-width: 0;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li.ui-li-anchor {
+  padding: 0 12px;
+  height: 40px;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li.ui-li-anchor > a {
+  margin: 0;
+  padding: 0;
+  overflow: visible;
+}
+.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-icon {
+  display: inline-block;
+  vertical-align: middle;
+  margin-top: 0;
+  margin-bottom: 0;
+  margin-right: 10px;
+  margin-left: -2px;
+}
+.ui-popup.ui-ctxpopup .ui-icon {
+  width: 20px;
+  height: 20px;
+  display: block;
+  vertical-align: middle;
+  margin: 2px auto;
+}
+.ui-text-ellipsis {
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  -o-text-overflow: ellipsis;
+  overflow: hidden !important;
+}
+/* Popup Toast and smallpopup will be integrated */
+/* Popup Toast */
+.ui-popup.ui-popup-toast {
+  background-color: transparent;
+  margin: 0 auto;
+  position: relative;
+  bottom: 0;
+  width: 100%;
+}
+.ui-popup.ui-popup-toast .ui-popup-content {
+  margin: auto;
+  margin-bottom: 64px;
+  width: -webkit-fit-content;
+  width: fit-content;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: space-between;
+      -ms-flex-pack: justify;
+          justify-content: space-between;
+  border-radius: 22px;
+  background-color: var(--toast-background);
+  padding: 12px 20px;
+  line-height: 20px;
+  color: var(--toast-text-color);
+  font-size: 16px;
+  font-family: Roboto-Regular;
+}
+@media all and (max-width: 479px) {
+  .ui-popup.ui-popup-toast .ui-popup-content {
+    max-width: 84%;
+  }
+  .ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button {
+    width: 84%;
+  }
+}
+@media all and (min-width: 480px) and (max-width: 959px) {
+  .ui-popup.ui-popup-toast .ui-popup-content {
+    max-width: 68%;
+  }
+  .ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button {
+    width: 68%;
+  }
+}
+@media all and (min-width: 960px) and (max-width: 1919px) {
+  .ui-popup.ui-popup-toast .ui-popup-content {
+    max-width: 37.5%;
+  }
+  .ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button {
+    width: 37.5%;
+  }
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button {
+  text-align: left;
+  min-height: 44px;
+  padding: 0px 20px;
+  background-color: var(--btn-toast-background);
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn {
+  padding: 4px 0 4px 20px;
+  margin: 0;
+  width: -webkit-fit-content;
+  width: fit-content;
+  color: var(--btn-toast-text-color);
+  font-size: 18px;
+  font-family: Roboto-Medium;
+  background-color: transparent;
+  line-height: 36px;
+  overflow: visible;
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item) {
+  background-color: transparent;
+  border: none;
+  border-radius: 0;
+  padding-right: 20px;
+  margin-right: -20px;
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before {
+  background-color: var(--ripple-color);
+}
+.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active {
+  background-color: transparent;
+}
+.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content {
+  display: block;
+  padding: 12px 20px;
+}
+.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content.ui-popup-toast-has-button {
+  padding-top: 9px;
+  padding-bottom: 4px;
+}
+.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content.ui-popup-toast-has-button .ui-btn {
+  margin-left: auto;
+  padding-top: 5px;
+  padding-bottom: 0;
+}
+/* smallpopup */
+@-webkit-keyframes ui-smallpopup-show {
+  from {
+    display: none;
+    opacity: 0;
+    -webkit-transform: scaleY(0);
+    -ms-transform: scaleY(0);
+    transform: scaleY(0);
+  }
+  to {
+    display: block;
+    opacity: 1;
+    -webkit-transform: scaleY(1);
+    -ms-transform: scaleY(1);
+    transform: scaleY(1);
+  }
+}
+@keyframes ui-smallpopup-show {
+  from {
+    display: none;
+    opacity: 0;
+    -webkit-transform: scaleY(0);
+    -ms-transform: scaleY(0);
+    transform: scaleY(0);
+  }
+  to {
+    display: block;
+    opacity: 1;
+    -webkit-transform: scaleY(1);
+    -ms-transform: scaleY(1);
+    transform: scaleY(1);
+  }
+}
+.ui-smallpopup {
+  position: fixed;
+  display: none;
+  margin-bottom: 32px;
+  max-width: 236px;
+  z-index: 1100;
+  vertical-align: middle;
+  font-size: 16px;
+  word-break: break-all;
+}
+.ui-smallpopup::before {
+  position: absolute;
+  content: '';
+  width: 100%;
+  height: 100%;
+}
+.ui-smallpopup.fix {
+  display: block;
+}
+.ui-smallpopup.show {
+  display: block;
+  -webkit-animation: ui-smallpopup-show 500ms 1 ease;
+  animation: ui-smallpopup-show 500ms 1 ease;
+}
+.ui-smallpopup.hide {
+  display: none;
+}
+.ui-smallpopup-text-bg {
+  position: relative;
+  padding: 3.5px 12px 5px 12px;
+  line-height: 18.5px;
+  margin: 0;
+  color: var(--toast-text-color);
+  font-size: 16px;
+}
+.ui-popup {
+  display: none;
+  position: absolute;
+  left: 0;
+  margin-bottom: 16px;
+  margin-top: 32px;
+  z-index: 1201 !important;
+  background-color: var(--popup-background);
+  border-radius: 26px;
+}
+@media (max-width: 479px) {
+  .ui-popup {
+    width: 100%;
+  }
+}
+@media (min-width: 480px) and (max-width: 672px) {
+  .ui-popup {
+    width: 63%;
+  }
+}
+@media (min-width: 673px) and (max-width: 985px) {
+  .ui-popup {
+    width: 55%;
+  }
+}
+@media (min-width: 986px) {
+  .ui-popup {
+    width: 35%;
+  }
+}
+.ui-popup .ui-popup-wrapper {
+  width: 100%;
+}
+.ui-popup.ui-popup-active {
+  display: block;
+}
+.ui-popup.in {
+  display: block;
+}
+.ui-popup.ui-build {
+  display: block;
+  visibility: hidden;
+}
+.ui-popup .ui-popup-header {
+  width: 100%;
+  text-align: left;
+  background-color: var(--popup-background);
+  position: -webkit-sticky;
+  position: sticky;
+  font-size: 20px;
+  color: var(--text-color);
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  font-family: Roboto-Medium;
+}
+.ui-popup .ui-popup-header::after {
+  content: "";
+  position: absolute;
+  left: 24px;
+  width: calc(100% - 48px);
+  height: 0.75px;
+  stroke-width: 0.5;
+  visibility: hidden;
+  background-color: var(--popup-scroll-divider-color);
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-header::after {
+    top: 68px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-header::after {
+    top: 45px;
+  }
+}
+.ui-popup .ui-popup-header.topDivider::after {
+  visibility: visible;
+}
+.ui-popup .ui-popup-header.ui-popup-header-has-subtitle {
+  padding: 9.75px 16px;
+  line-height: 28.5px;
+  font-size: 20px;
+  color: T1212;
+}
+.ui-popup .ui-popup-header .ui-popup-subtitle {
+  line-height: 19px;
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-header {
+    padding: 26px 24px 19px 24px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-header {
+    padding: 14px 24px 8px 24px;
+  }
+}
+.ui-popup .ui-popup-content {
+  width: 100%;
+  background-color: var(--popup-background);
+  color: var(--popup-text);
+  text-align: left;
+  font-size: 16px;
+  overflow: auto;
+  -webkit-overflow-scrolling: touch;
+  -moz-overflow-scrolling: touch;
+  -o-overflow-scrolling: touch;
+  -ms-overflow-scrolling: touch;
+  overflow-scrolling: touch;
+  line-height: 23px;
+}
+.ui-popup .ui-popup-content img {
+  display: block;
+  margin: 0 auto;
+  padding-bottom: 12px;
+}
+.ui-popup .ui-popup-content.ui-date-picker-calendar {
+  padding-left: 16px;
+  padding-right: 16px;
+}
+.ui-popup .ui-popup-content .ui-popup-body-text {
+  margin-top: 8px;
+}
+.ui-popup .ui-popup-content .ui-popup-body-checkbox {
+  margin-top: 8px;
+  height: 32px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-popup .ui-popup-content .ui-popup-body-checkbox input[type="Checkbox"] {
+  margin: 0 12px 0 -4px;
+}
+.ui-popup .ui-popup-content .ui-popup-body-checkbox span {
+  margin-top: 5px;
+}
+.ui-popup .ui-popup-content ul .ui-li-has-checkbox .ui-li-text span {
+  font-size: 18px;
+}
+.ui-popup .ui-popup-content ul .ui-li-has-checkbox input {
+  margin-left: 18px;
+  margin-right: 18px;
+}
+.ui-popup .ui-popup-content .ui-popup-container-text {
+  width: 100%;
+  height: 19px;
+  line-height: 19px;
+  color: var(--popup-text-color);
+  font-size: 14px;
+  font-family: Roboto-Regular;
+}
+.ui-popup .ui-popup-content .ui-popup-container-text .text-left {
+  float: left;
+}
+.ui-popup .ui-popup-content .ui-popup-container-text .text-right {
+  float: right;
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-content {
+    padding: 0 24px 0 24px;
+    margin-bottom: 24px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-content {
+    padding: 0 24px 0 24px;
+    margin-bottom: 11px;
+  }
+}
+.ui-popup .ui-popup-content.ui-popup-has-time-picker,
+.ui-popup .ui-popup-content.ui-popup-has-date-picker {
+  padding-left: unset;
+  padding-right: unset;
+}
+.ui-popup .ui-popup-footer {
+  background-color: var(--popup-background);
+  position: -webkit-sticky;
+  position: sticky;
+  box-sizing: border-box;
+  padding: 12px 24px;
+  text-align: center;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+  width: 100%;
+}
+.ui-popup .ui-popup-footer::before {
+  content: "";
+  position: absolute;
+  left: 24px;
+  width: calc(100% - 48px);
+  height: 0.75px;
+  stroke-width: 0.5;
+  visibility: hidden;
+  background-color: var(--popup-scroll-divider-color);
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-footer::before {
+    bottom: 80px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-footer::before {
+    bottom: 50px;
+  }
+}
+.ui-popup .ui-popup-footer.bottomDivider::before {
+  visibility: visible;
+}
+.ui-popup .ui-popup-footer .ui-btn {
+  height: 36px;
+  margin: 0 auto;
+  max-width: 248px;
+}
+.ui-popup .ui-popup-footer .ui-btn.ui-btn-flat {
+  font-size: 16px;
+}
+.ui-popup .ui-popup-footer div.ui-li-divider::after {
+  content: "";
+  position: absolute;
+  width: 1px;
+  height: 16px;
+  top: 10px;
+  background-color: var(--popup-footer-divider-color);
+}
+.ui-popup .ui-popup-footer .ui-popup-stack .ui-btn {
+  margin-bottom: 16px;
+}
+.ui-popup .ui-popup-footer .ui-popup-stack .ui-btn:nth-last-child(1) {
+  margin-bottom: 0;
+}
+.ui-popup .ui-popup-footer .ui-li-action {
+  width: 50%;
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-footer {
+    padding: 0px 24px 20px 24px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-footer {
+    padding: 0px 24px 4px 24px;
+  }
+}
+.ui-popup .ui-listview {
+  margin-left: -24px;
+}
+@media (orientation: portrait) {
+  .ui-popup .ui-popup-notitle {
+    margin-top: 26px;
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup .ui-popup-notitle {
+    margin-top: 14px;
+  }
+}
+.ui-popup .ui-popup-2level-description {
+  height: auto;
+  margin-top: 8px;
+  margin-left: 8px;
+  color: var(--popup-text-secondary-color);
+}
+.ui-popup .ui-popup-2level-description span {
+  padding-right: 12px;
+}
+.ui-popup .ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a {
+  margin-top: 14px;
+  margin-bottom: 14px;
+}
+.ui-popup .ui-popup-header,
+.ui-popup .ui-popup-content,
+.ui-popup .ui-popup-footer {
+  box-sizing: border-box;
+}
+.ui-popup.ui-popup-listview {
+  background-image: url("images/page/core_theme_bg_01.png");
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  overflow: hidden;
+  background-color: transparent;
+}
+.ui-popup.ui-popup-listview .ui-popup-header {
+  padding-top: 8px;
+  padding-bottom: 8px;
+}
+.ui-popup.ui-popup-listview .ui-popup-content {
+  padding: 0;
+  background-color: transparent;
+  position: relative;
+}
+.ui-popup.ui-popup-listview .ui-listview {
+  position: relative;
+  overflow: hidden;
+  -webkit-transform: translate3d(0, 0, 0);
+          transform: translate3d(0, 0, 0);
+}
+.ui-popup.ui-popup-listview .ui-listview::before {
+  content: "";
+  background-color: var(--overlay);
+  width: 100%;
+  height: 100%;
+  display: block;
+  position: absolute;
+  top: 0;
+  z-index: 1;
+  pointer-events: none;
+}
+.ui-popup.ui-popup-moremenu {
+  max-height: 420px;
+  overflow: hidden;
+}
+@media (orientation: landscape) {
+  .ui-popup.ui-popup-moremenu {
+    max-height: 300px;
+    width: 360px;
+  }
+}
+.ui-popup-overlay {
+  display: none;
+  background-color: var(--overlay);
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 1200;
+}
+.ui-popup-overlay.ui-popup-overlay-shown {
+  display: block;
+}
+.ui-popup.ui-popup-activity .ui-popup-content {
+  text-align: right;
+}
+@media (orientation: landscape) {
+  .ui-popup.ui-popup-activity .ui-popup-content {
+    width: 100%;
+  }
+}
+@-webkit-keyframes popup-activity {
+  from {
+    -webkit-transform: rotate(0deg);
+    -ms-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  to {
+    -webkit-transform: rotate(360deg);
+    -ms-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+@keyframes popup-activity {
+  from {
+    -webkit-transform: rotate(0deg);
+    -ms-transform: rotate(0deg);
+    transform: rotate(0deg);
+  }
+  to {
+    -webkit-transform: rotate(360deg);
+    -ms-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+@media (orientation: landscape) {
+  .ui-popup.ui-popup-activity {
+    width: 100%;
+  }
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-small .ui-popup-content {
+  text-align: right;
+  height: 39px;
+  padding: 8px 16px;
+  font-size: 20px;
+  color: T120L1;
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-small .ui-popup-content::after {
+  content: "";
+  width: 22px;
+  height: 22px;
+  margin-left: 16px;
+  background-color: W157E1;
+  -webkit-mask-image: url("images/core_activity_indicator_a.svg"), url("images/core_activity_indicator_b.svg"), url("images/core_activity_indicator_c.svg");
+          mask-image: url("images/core_activity_indicator_a.svg"), url("images/core_activity_indicator_b.svg"), url("images/core_activity_indicator_c.svg");
+  -webkit-mask-size: 100% 100%, 100% 100%, 100% 100%;
+          mask-size: 100% 100%, 100% 100%, 100% 100%;
+  float: right;
+  -webkit-animation-name: popup-activity;
+          animation-name: popup-activity;
+  -webkit-animation-duration: 1s;
+          animation-duration: 1s;
+  -webkit-animation-timing-function: linear;
+          animation-timing-function: linear;
+  -webkit-animation-iteration-count: infinite;
+          animation-iteration-count: infinite;
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-medium .ui-popup-content {
+  text-align: left;
+  height: 60px;
+  padding: 16px 16px;
+  font-size: 20px;
+  color: T120L2;
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-medium .ui-popup-content::before {
+  content: "";
+  width: 28px;
+  height: 28px;
+  margin-right: 16px;
+  background-color: W157E1;
+  float: left;
+  -webkit-mask-image: url("images/core_activity_indicator_a.svg"), url("images/core_activity_indicator_b.svg"), url("images/core_activity_indicator_c.svg");
+          mask-image: url("images/core_activity_indicator_a.svg"), url("images/core_activity_indicator_b.svg"), url("images/core_activity_indicator_c.svg");
+  -webkit-mask-size: 100% 100%, 100% 100%, 100% 100%;
+          mask-size: 100% 100%, 100% 100%, 100% 100%;
+  -webkit-animation-name: popup-activity;
+          animation-name: popup-activity;
+  -webkit-animation-duration: 1s;
+          animation-duration: 1s;
+  -webkit-animation-timing-function: linear;
+          animation-timing-function: linear;
+  -webkit-animation-iteration-count: infinite;
+          animation-iteration-count: infinite;
+}
+.ui-popup.ui-popup-activity.ui-popup-activity-large .ui-popup-content {
+  text-align: center;
+  height: 0;
+  background-color: W157E1;
+  -webkit-mask-image: url("images/core_activity_indicator_c.svg");
+          mask-image: url("images/core_activity_indicator_c.svg");
+  -webkit-mask-size: 100% 100%;
+          mask-size: 100% 100%;
+}
+.ui-popup:not(.ui-ctxpopup).slideup.out {
+  -webkit-animation: popupslideouttobottom 400ms ease-out;
+  animation: popupslideouttobottom 400ms ease-out;
+}
+.ui-popup:not(.ui-ctxpopup).slideup.in {
+  -webkit-animation: popupslideinfrombottom 400ms ease-out;
+  animation: popupslideinfrombottom 400ms ease-out;
+}
+.ui-popup.slideup.in:not(.ui-ctxpopup) .ui-popup-wrapper {
+  -webkit-transform: translateY(100%);
+  -ms-transform: translateY(100%);
+  transform: translateY(100%);
+  -webkit-animation: popupwrapperslideinfrombottom 350ms ease-out 50ms;
+  animation: popupwrapperslideinfrombottom 350ms ease-out 50ms;
+}
+.ui-popup.slideup.out:not(.ui-ctxpopup) .ui-popup-wrapper {
+  -webkit-transform: translateY(25px);
+  -ms-transform: translateY(25px);
+  transform: translateY(25px);
+  -webkit-animation: popupwrapperslideouttobottom 4000ms ease-out;
+  animation: popupwrapperslideouttobottom 4000ms ease-out;
+}
+.ui-popup-overlay.slideup.in:not(.ui-ctxpopup-overlay) {
+  -webkit-animation: popupoverlayfadein 400ms ease-out;
+  animation: popupoverlayfadein 400ms ease-out;
+}
+.ui-popup-overlay.slideup.out:not(.ui-ctxpopup-overlay) {
+  -webkit-animation: popupoverlayfadeout 400ms ease-out;
+  animation: popupoverlayfadeout 400ms ease-out;
+}
+@-webkit-keyframes popupslideouttobottom {
+  from {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+  to {
+    -webkit-transform: translateY(100%);
+    -ms-transform: translateY(100%);
+    transform: translateY(100%);
+  }
+}
+@keyframes popupslideouttobottom {
+  from {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+  to {
+    -webkit-transform: translateY(100%);
+    -ms-transform: translateY(100%);
+    transform: translateY(100%);
+  }
+}
+@-webkit-keyframes popupslideinfrombottom {
+  from {
+    -webkit-transform: translateY(100%);
+    -ms-transform: translateY(100%);
+    transform: translateY(100%);
+  }
+  to {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+}
+@keyframes popupslideinfrombottom {
+  from {
+    -webkit-transform: translateY(100%);
+    -ms-transform: translateY(100%);
+    transform: translateY(100%);
+  }
+  to {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+}
+@-webkit-keyframes popupwrapperslideinfrombottom {
+  from {
+    -webkit-transform: translateY(25px);
+    -ms-transform: translateY(25px);
+    transform: translateY(25px);
+  }
+  to {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+}
+@keyframes popupwrapperslideinfrombottom {
+  from {
+    -webkit-transform: translateY(25px);
+    -ms-transform: translateY(25px);
+    transform: translateY(25px);
+  }
+  to {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+}
+@-webkit-keyframes popupwrapperslideouttobottom {
+  from {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+  to {
+    -webkit-transform: translateY(25px);
+    -ms-transform: translateY(25px);
+    transform: translateY(25px);
+  }
+}
+@keyframes popupwrapperslideouttobottom {
+  from {
+    -webkit-transform: translateY(0%);
+    -ms-transform: translateY(0%);
+    transform: translateY(0%);
+  }
+  to {
+    -webkit-transform: translateY(25px);
+    -ms-transform: translateY(25px);
+    transform: translateY(25px);
+  }
+}
+@-webkit-keyframes popupoverlayfadein {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@keyframes popupoverlayfadein {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes popupoverlayfadeout {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+@keyframes popupoverlayfadeout {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+.ui-scrollview-clip {
+  display: block;
+  position: relative;
+  z-index: 100;
+  overflow-x: hidden;
+  overflow-y: visible;
+}
+.ui-scrollview-clip[data-scroll="x"] {
+  -webkit-scroll-snap-type: x mandatory;
+      -ms-scroll-snap-type: x mandatory;
+          scroll-snap-type: x mandatory;
+}
+.ui-scrollview-clip[data-scroll="x"] .ui-scrollview-view {
+  overflow: initial;
+}
+.ui-scrollview-view {
+  overflow: hidden;
+  min-height: 100%;
+  min-width: 100%;
+  box-sizing: border-box;
+}
+.ui-scrolllistview .ui-li-divider {
+  z-index: 10;
+}
+.ui-scrollbar {
+  position: absolute;
+  overflow: hidden;
+  opacity: 0;
+}
+.ui-scrollbar-visible {
+  opacity: 1;
+}
+.ui-scrollbar-y {
+  top: 0;
+  right: 1px;
+  bottom: 0;
+  width: 4px;
+}
+.ui-scrollbar-x {
+  right: 1px;
+  bottom: 1px;
+  left: 1px;
+  height: 4px;
+}
+.ui-scrollbar-track {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.ui-scrollbar-thumb {
+  position: absolute;
+  top: 0;
+  left: 0;
+  background-color: var(--primary-color);
+}
+.ui-scrollbar-y .ui-scrollbar-thumb {
+  width: 2.5px;
+  height: 100%;
+  border-radius: 1px;
+  -o-box-shadow: 0.5px 0.5px 2px #080808;
+  -ms-box-shadow: 0.5px 0.5px 2px #080808;
+  box-shadow: 0.5px 0.5px 2px #080808;
+}
+.ui-scrollbar-x .ui-scrollbar-thumb {
+  width: 100%;
+  height: 2.5px;
+  border-radius: 1px;
+}
+.ui-scroll-jump-top-bg {
+  position: absolute;
+  top: 4.5px;
+  right: 6.5px;
+  width: 18.5px;
+  height: 18.5px;
+}
+.ui-scroll-jump-left-bg {
+  position: absolute;
+  bottom: 4.5px;
+  left: 6.5px;
+  width: 18.5px;
+  height: 18.5px;
+}
+.ui-overflow-indicator-top,
+.ui-overflow-indicator-bottom {
+  position: absolute;
+  display: none;
+  width: 100%;
+  height: 14.5px;
+  opacity: 1;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+}
+.ui-overflow-indicator-top {
+  top: 0;
+}
+.ui-overflow-indicator-bottom {
+  bottom: 0;
+}
+.ui-overflow-effect-bottom {
+  position: absolute;
+  display: none;
+  bottom: 0;
+  width: 100%;
+}
+.ui-overflow-top {
+  opacity: 1;
+}
+.ui-overflow-top.ui-overflow-top-hide {
+  height: 0 !important;
+}
+.ui-overflow-bottom {
+  opacity: 1;
+}
+.ui-overflow-bottom.ui-overflow-bottom-hide {
+  height: 0 !important;
+}
+/*
+ * padding here set to zero - otherwise the list scrolls underneith the top heading and can be seen above it
+ */
+.ui-content.ui-scrollview-clip {
+  padding: 0;
+}
+.ui-content.ui-scrollview-clip > div.ui-scrollview-view {
+  margin: 0;
+}
+/*
+ * this seems to effect how far the top divider is place wrt to the scrollview
+ * without this, it is placed too high, so it is clipped in half
+ */
+.ui-content.ui-scrollview-clip > .ui-listview.ui-scrollview-view {
+  margin: 0;
+}
+/*
+ * Section for scroll handler to hide native scrollbar
+ */
+.ui-content.ui-scrollview-clip.ui-hide-scrollbar::-webkit-scrollbar {
+  display: none;
+}
+.ui-slider {
+  position: relative;
+  box-sizing: border-box;
+  height: 32px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: space-around;
+      -ms-flex-pack: distribute;
+          justify-content: space-around;
+}
+.ui-slider .ui-slider-bar {
+  background-color: var(--slider-bg-color);
+  height: 3px;
+  border-radius: 1.5px;
+  overflow: hidden;
+}
+.ui-slider .ui-slider-bar .ui-slider-value {
+  height: 100%;
+  background-color: var(--slider-handler-color);
+}
+.ui-slider:focus {
+  outline: none;
+}
+.ui-slider .ui-slider-handler-track {
+  position: absolute;
+  width: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-slider .ui-slider-handler-track .ui-slider-before-space {
+  height: 1px;
+}
+.ui-slider .ui-slider-handler-track .ui-slider-after-space {
+  height: 1px;
+}
+.ui-slider .ui-slider-handler {
+  width: 17px;
+  height: 17px;
+  min-width: 17px;
+  min-height: 17px;
+  background-color: var(--slider-value-color);
+  position: relative;
+  border-radius: 50%;
+  pointer-events: none;
+  z-index: 9;
+}
+.ui-slider .ui-slider-handler::before {
+  content: "";
+  width: 32px;
+  height: 32px;
+  opacity: 0;
+  position: absolute;
+  left: -5px;
+  top: -5px;
+  border-radius: 100%;
+  background-color: var(--ripple-color);
+}
+.ui-slider.ui-slider-active .ui-slider-handler {
+  min-width: 22px;
+  min-height: 22px;
+}
+.ui-slider.ui-slider-active .ui-slider-handler::before {
+  opacity: 1;
+}
+.ui-slider.ui-disabled .ui-slider-bar {
+  background-color: var(--slider-bg-disabled-color);
+}
+.ui-slider.ui-disabled .ui-slider-bar .ui-slider-value {
+  background-color: var(--slider-handler-disabled-color);
+}
+.ui-slider.ui-disabled .ui-slider-handler {
+  background-color: var(--slider-handler-disabled-color);
+}
+.ui-slider.ui-slider-level-bar {
+  margin-left: 5px;
+  margin-right: 5px;
+  height: 32px;
+}
+.ui-slider.ui-slider-level-bar .ui-slider-bar {
+  background-color: var(--slider-level-bar-bg-color);
+}
+.ui-slider.ui-slider-level-bar .ui-slider-bar .ui-slider-value {
+  display: none;
+}
+.ui-slider.ui-slider-level-bar .ui-slider-bar::before {
+  display: none;
+  border-image: none;
+}
+.ui-slider.ui-slider-level-bar input {
+  width: 100%;
+}
+.ui-slider.ui-slider-level-bar .ui-slider-scale {
+  position: absolute;
+  width: 100%;
+  height: 7px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: space-between;
+      -ms-flex-pack: justify;
+          justify-content: space-between;
+  pointer-events: none;
+}
+.ui-slider.ui-slider-level-bar .ui-slider-scale .ui-slider-scale-dot {
+  width: 7px;
+  height: 7px;
+  border-radius: 100%;
+  background-color: var(--slider-scale-dot);
+}
+.ui-slider.ui-slider-level-bar .ui-slider-handler-track {
+  width: calc(100% +  10px);
+  left: -5px;
+}
+.ui-slider-label {
+  font-size: 12px;
+  color: var(--text-secondary-color);
+}
+.ui-slider-label-min {
+  position: absolute;
+  left: 0;
+  bottom: -2px;
+}
+.ui-slider-label-max {
+  position: absolute;
+  right: 0;
+  bottom: -2px;
+}
+.ui-slider.ui-slider-has-labels {
+  height: 50px;
+}
+input[data-tau-built="Slider"] {
+  opacity: 0;
+  display: block;
+  width: 100%;
+  position: absolute;
+  margin: 0;
+}
+/*new button type like*/
+tau-toggleswitch {
+  display: block;
+}
+.ui-toggle-container {
+  position: relative;
+  width: 36px;
+  height: 36px;
+}
+.ui-toggle-container .ui-switch-handler {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  top: 0;
+  left: 0;
+  background-color: transparent;
+  pointer-events: none;
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
+  -webkit-perspective: 1000px;
+          perspective: 1000px;
+}
+.ui-toggle-container .ui-switch-handler:before,
+.ui-toggle-container .ui-switch-handler:after {
+  content: "";
+  position: absolute;
+  height: 100%;
+  width: 100%;
+  -webkit-mask-position: center center;
+          mask-position: center center;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+}
+.ui-toggle-container .ui-switch-handler:before {
+  background-color: W015L1i;
+  -webkit-mask-image: url("images/controls/core_toggle_icon_off.svg");
+          mask-image: url("images/controls/core_toggle_icon_off.svg");
+  -webkit-transform: scale(1);
+      -ms-transform: scale(1);
+          transform: scale(1);
+  transition: 250ms ease-out 50ms;
+}
+.ui-toggle-container .ui-switch-handler:after {
+  background-color: W015L1i;
+  -webkit-mask-image: url("images/controls/core_toggle_icon_on.svg");
+          mask-image: url("images/controls/core_toggle_icon_on.svg");
+  -webkit-transform: scale(0);
+      -ms-transform: scale(0);
+          transform: scale(0);
+  transition: 100ms ease-out;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch {
+  width: 36px;
+  height: 36px;
+  border-radius: 50%;
+  background-color: W015L1E1;
+  /*@color_toggle_bg;*/
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  outline: 0;
+  margin: 0;
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
+  -webkit-perspective: 1000px;
+          perspective: 1000px;
+  transition: background-color 150ms;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch::before {
+  content: none;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch:checked {
+  background-color: var(--color-white);
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch:checked ~ .ui-switch-handler::before {
+  -webkit-transform: scale(0);
+      -ms-transform: scale(0);
+          transform: scale(0);
+  transition: 100ms ease-out;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch:checked ~ .ui-switch-handler::after {
+  -webkit-transform: scale(1);
+      -ms-transform: scale(1);
+          transform: scale(1);
+  transition: 250ms ease-out 50ms;
+}
+.ui-toggle-container input[type="checkbox"].ui-toggle-switch:disabled {
+  background-color: W015L1D;
+}
+.ui-toggle-switch-focus {
+  outline: 2px solid var(--primary-color);
+}
+@-webkit-keyframes move-to-off {
+  to {
+    -webkit-transform: translateX(0);
+            transform: translateX(0);
+  }
+}
+@keyframes move-to-off {
+  to {
+    -webkit-transform: translateX(0);
+            transform: translateX(0);
+  }
+}
+@-webkit-keyframes move-to-on {
+  to {
+    -webkit-transform: translateX(17px);
+            transform: translateX(17px);
+  }
+}
+@keyframes move-to-on {
+  to {
+    -webkit-transform: translateX(17px);
+            transform: translateX(17px);
+  }
+}
+.ui-on-off-switch-container {
+  position: relative;
+  display: inline-block;
+  width: 43px;
+  height: 27px;
+  max-width: 43px;
+  max-height: 27px;
+  min-width: 43px;
+  min-height: 27px;
+  overflow: hidden;
+}
+.ui-on-off-switch-input {
+  position: absolute;
+  width: 37px;
+  height: 18.5px;
+  border-radius: 9.25px;
+  -webkit-appearance: none;
+  display: block;
+  margin: 4.25px 3px;
+  border: 1px solid var(--on-off-switch-off-button-border);
+  background-color: var(--on-off-switch-off-track-background);
+  outline: none;
+  box-sizing: border-box;
+}
+.ui-on-off-switch-input:active ~ .ui-on-off-switch-button::before {
+  opacity: 1;
+}
+.ui-on-off-switch-input:disabled {
+  border-color: var(--on-off-switch-off-disabled-track-border);
+}
+.ui-on-off-switch-input:disabled ~ .ui-on-off-switch-button {
+  border-color: var(--on-off-switch-off-disabled-button-border);
+  background-color: var(--on-off-switch-on-disabled-button-background);
+}
+.ui-on-off-switch-button {
+  width: 22px;
+  height: 22px;
+  border-radius: 100%;
+  margin: 2.5px 2px;
+  box-sizing: border-box;
+  border: 1px solid var(--on-off-switch-off-button-border);
+  background-color: var(--color-white);
+  position: absolute;
+  top: 0;
+  left: 0;
+  pointer-events: none;
+  z-index: 1;
+  transition: -webkit-transform cubic-bezier(0.6, 0.6, 0.8, 1.49) 250ms;
+  transition: transform cubic-bezier(0.6, 0.6, 0.8, 1.49) 250ms;
+  transition: transform cubic-bezier(0.6, 0.6, 0.8, 1.49) 250ms, -webkit-transform cubic-bezier(0.6, 0.6, 0.8, 1.49) 250ms;
+  -webkit-transform: translate3d(0, 0, 0);
+          transform: translate3d(0, 0, 0);
+}
+.ui-on-off-switch-button::before {
+  content: "";
+  width: 27px;
+  height: 27px;
+  opacity: 0;
+  position: absolute;
+  left: -3px;
+  top: -3px;
+  border-radius: 100%;
+  background-color: var(--ripple-color);
+}
+.ui-on-off-switch-button-on-drag {
+  transition: none;
+}
+.ui-on-off-switch-button-on-drag::before {
+  opacity: 1;
+}
+.ui-on-off-switch-button-move-to-off {
+  -webkit-animation: move-to-off 100ms ease-in-out 0s 1 normal both;
+          animation: move-to-off 100ms ease-in-out 0s 1 normal both;
+  transition: none;
+}
+.ui-on-off-switch-button-move-to-on {
+  -webkit-animation: move-to-on 100ms ease-in-out 0s 1 normal both;
+          animation: move-to-on 100ms ease-in-out 0s 1 normal both;
+  transition: none;
+}
+.ui-on-off-switch-input:checked {
+  background-color: var(--primary-color);
+  border-color: var(--primary-color);
+  width: 37px;
+  height: 18.5px;
+  margin: 4.25px 3px;
+}
+.ui-on-off-switch-input:checked:disabled {
+  background-color: var(--on-off-switch-on-disabled-track-background);
+  border-color: transparent;
+}
+.ui-on-off-switch-input:checked:disabled ~ .ui-on-off-switch-button {
+  border-color: var(--on-off-switch-on-disabled-button-border);
+}
+.ui-on-off-switch-input:checked ~ .ui-on-off-switch-button {
+  border-color: var(--primary-color);
+  -webkit-transform: translate3d(17px, 0, 0);
+          transform: translate3d(17px, 0, 0);
+}
+.ui-master-on-off-switch {
+  font-family: Roboto-Regular;
+  font-size: 18px;
+  margin-left: 0;
+  margin-right: 0;
+  margin-bottom: 20px;
+  height: 64px;
+  position: relative;
+}
+.ui-master-on-off-switch .ui-on-off-label {
+  background-color: var(--master-on-off-off-color);
+  position: absolute;
+  left: 0;
+  right: 0;
+  width: 100%;
+  height: 100%;
+  border-radius: 26px;
+  box-sizing: border-box;
+  padding-left: 24px;
+  padding-right: 24px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-master-on-off-switch .ui-on-off-label::before {
+  content: "";
+  width: 100%;
+  height: 64px;
+  opacity: 0;
+  position: absolute;
+  left: 0;
+  top: 0;
+  border-radius: 26px;
+  background-color: var(--ripple-color);
+}
+.ui-master-on-off-switch .ui-on-off-label-active::before {
+  opacity: 1;
+}
+.ui-master-on-off-switch .ui-on-off-label span {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-master-on-off-switch .ui-on-off-label-on {
+  color: var(--color-white);
+  background-color: var(--master-on-off-on-color);
+}
+.ui-master-on-off-switch .ui-on-off-switch-input:active ~ .ui-on-off-switch-button::before {
+  opacity: 0;
+}
+.ui-sub-tab {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: calc(100% -  48px);
+  height: 56px;
+  margin-left: 24px;
+  margin-right: 24px;
+  background-color: var(--sub-tab-bg-color);
+}
+.ui-sub-tab a {
+  font-family: Roboto-Regular;
+  font-size: 15px;
+  line-height: 22px;
+  padding-left: 12px;
+  padding-right: 12px;
+  color: var(--sub-tab-text-color);
+  border-radius: 18px;
+  box-sizing: border-box;
+  border: 0 solid var(--sub-tab-border-color);
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  position: relative;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  width: 100%;
+  min-height: 36px;
+  text-decoration: none;
+}
+.ui-sub-tab a span {
+  position: relative;
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  height: 100%;
+  overflow-x: hidden;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: flex-start;
+      -ms-flex-pack: start;
+          justify-content: flex-start;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-sub-tab a.ui-tab-active {
+  font-family: Roboto-Medium;
+  color: var(--sub-tab-active-text-color);
+  border-width: 1px;
+}
+.ui-sub-tab a.ui-sub-tab-inactive-text-overflow span {
+  display: inline-block;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-sub-tab a::before {
+  content: "";
+  width: 100%;
+  height: 100%;
+  top: 0;
+  left: 0;
+  position: absolute;
+  opacity: 0;
+  background-color: var(--ripple-color);
+  border-radius: 26px;
+}
+.ui-sub-tab a.ui-btn-active {
+  background-color: inherit;
+}
+.ui-sub-tab a.ui-btn-active::before {
+  -webkit-animation: animation_opacity_in linear 100ms,
+                                       animation_opacity_out linear 400ms 100ms;
+          animation: animation_opacity_in linear 100ms,
+                                       animation_opacity_out linear 400ms 100ms;
+}
+.ui-sub-tab ul {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  position: relative;
+  height: 100%;
+  white-space: nowrap;
+  font-size: 0;
+}
+.ui-sub-tab li {
+  text-align: center;
+  margin: auto 0;
+}
+.ui-sub-tab:not(.ui-sub-tab-static) ul li {
+  min-width: 105px;
+}
+.ui-sub-tab:not(.ui-sub-tab-static).ui-sub-tab-landscape ul li {
+  min-width: 135px;
+}
+.ui-main-tab {
+  display: none;
+  width: calc(100% -  32px);
+  height: 60px;
+  margin-left: 16px;
+  margin-right: 16px;
+  background-color: var(--bottom-bar-color);
+  position: fixed;
+  bottom: 0;
+}
+.ui-main-tab-visible {
+  display: block;
+}
+.ui-main-tab a {
+  font-family: Roboto-Regular;
+  font-size: 15px;
+  line-height: 22px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  position: relative;
+  left: 0;
+  top: 0;
+  height: 100%;
+  text-decoration: none;
+  color: var(--tab-text-color);
+  padding-left: 10px;
+  padding-right: 10px;
+}
+.ui-main-tab a > span,
+.ui-main-tab a > div {
+  position: relative;
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: flex-start;
+      -ms-flex-pack: start;
+          justify-content: flex-start;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  padding-bottom: 4px;
+  overflow: hidden;
+}
+.ui-main-tab a > span::before,
+.ui-main-tab a > div::before {
+  content: "";
+  position: absolute;
+  width: 100%;
+  height: 4px;
+  border-bottom: 2.5px dotted var(--primary-dark-color);
+  bottom: 0.75px;
+  box-sizing: border-box;
+  opacity: 0;
+}
+.ui-main-tab a.ui-tab-active {
+  color: var(--primary-dark-color);
+  font-family: Roboto-Medium;
+}
+.ui-main-tab a.ui-tab-active > span::before,
+.ui-main-tab a.ui-tab-active > div::before {
+  opacity: 1;
+}
+.ui-main-tab a:disabled {
+  color: var(--tab-text-color-dim);
+}
+.ui-main-tab a::before {
+  content: "";
+  width: 100%;
+  height: 43px;
+  top: 8.5px;
+  border-radius: 26px;
+  left: 0;
+  position: absolute;
+  opacity: 0;
+  background-color: var(--ripple-color);
+}
+.ui-main-tab a.ui-btn-active {
+  background-color: transparent;
+}
+.ui-main-tab a.ui-btn-active::before {
+  opacity: 1;
+}
+.ui-main-tab ul {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  position: relative;
+  height: 100%;
+  white-space: nowrap;
+  font-size: 0;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-main-tab li {
+  text-align: center;
+  display: block;
+  position: relative;
+  overflow: hidden;
+  height: 100%;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+}
+.ui-main-tab .ui-li-active a::before {
+  opacity: 1;
+}
+.ui-main-tab .ui-tabs-badge {
+  position: absolute;
+  border-radius: 25px;
+  min-width: 12px;
+  background-color: var(--accent-badge);
+  color: var(--color-white);
+  top: 1px;
+  right: 7px;
+  text-align: center;
+  padding: 3.5px 7.5px;
+  font-family: Roboto-Medium;
+  font-size: 11px;
+}
+.ui-marquee-content::after {
+  content: attr(title);
+  text-indent: 75px;
+  position: absolute;
+  display: none;
+}
+.ui-marquee-content.ui-visible {
+  padding-right: 75px;
+}
+.ui-marquee-content.ui-visible::after {
+  display: inline;
+}
+.ui-footer {
+  padding: 0;
+  z-index: 100;
+}
+.ui-footer .ui-bottom-bar {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  min-height: 56px;
+  background-color: var(--bottom-bar-color);
+  padding: 0 24px;
+}
+.ui-footer .ui-bottom-bar .ui-btn {
+  font-family: Roboto-Medium;
+  font-size: 18px;
+  text-align: center;
+  line-height: 18px;
+  max-width: 100%;
+  height: 56px;
+}
+.ui-footer .ui-bottom-bar .ui-btn.ui-btn ~ .ui-btn {
+  margin-left: 0;
+}
+.ui-footer .ui-bottom-bar .ui-btn.ui-btn-icon {
+  font-family: Roboto-Regular;
+  font-size: 12px;
+  line-height: normal;
+  max-width: 100%;
+}
+.ui-footer .ui-bottom-bar .ui-btn.ui-btn-icon-top ~ .ui-btn-icon-top {
+  margin-left: 10px;
+}
+.ui-footer .ui-bottom-bar .ui-btn.ui-btn-text {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-footer .ui-bottom-bar.ui-bottom-bar-icons {
+  padding: 0 10px;
+}
+.ui-footer .ui-bottom-bar.ui-hidden {
+  display: none;
+}
+@media all and (min-width: 673px) and (min-height: 411px) {
+  .ui-footer .ui-bottom-bar {
+    margin: 0 auto;
+    width: 75%;
+    min-width: 625px;
+  }
+  .ui-footer .ui-bottom-bar.ui-bottom-bar-icons {
+    min-width: 653px;
+  }
+}
+.ui-tokentextarea {
+  display: table;
+  outline: none;
+  position: relative;
+  background-color: W010;
+  margin-left: -7.5px;
+  margin-right: -7.5px;
+}
+.ui-tokentextarea .ui-tokentextarea-input-area {
+  height: 26.5px;
+}
+.ui-tokentextarea .ui-tokentextarea-input-area .ui-text-line {
+  display: none;
+}
+.ui-scrollview-view > .ui-tokentextarea {
+  margin-left: -4px;
+  margin-right: -4px;
+}
+.ui-tokentextarea .ui-tokentextarea-label {
+  display: inline-block;
+  text-align: center;
+  position: relative;
+  margin-left: 6.5px;
+  margin-right: 3px;
+  padding: 11.5px 0;
+  color: T059L2;
+  font-size: 15px;
+}
+.ui-tokentextarea .ui-tokentextarea-input.ui-input-text {
+  height: 26.5px;
+  outline: none;
+  position: relative;
+  border: 0;
+  padding: 0;
+  color: T059L1;
+  background-color: W010;
+  text-align: left;
+  font-size: 15px;
+}
+.ui-tokentextarea-input-visible {
+  display: inline-block;
+}
+.ui-tokentextarea-input-invisible {
+  display: none;
+}
+.ui-tokentextarea div {
+  display: inline-block;
+  text-align: center;
+  cursor: pointer;
+  position: relative;
+  padding: .2em .5em;
+  font-size: 15px;
+  color: T020;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  margin: 4px 1px;
+}
+.ui-tokentextarea-block {
+  -webkit-mask-box-image-repeat: repeat;
+  -moz-mask-box-image-repeat: repeat;
+  -ms-mask-box-image-repeat: repeat;
+  -o-mask-box-image-repeat: repeat;
+  mask-box-image-repeat: repeat;
+  -webkit-mask-box-image-width: auto;
+  -moz-mask-box-image-width: auto;
+  -ms-mask-box-image-width: auto;
+  -o-mask-box-image-width: auto;
+  mask-box-image-width: auto;
+  -webkit-mask-box-image-source: url('images/nine-patch/core_button_bg.png');
+  -webkit-mask-box-image-slice: 37 38 36 38 fill;
+  -moz-mask-box-image-slice: 37 38 36 38 fill;
+  -ms-mask-box-image-slice: 37 38 36 38 fill;
+  -o-mask-box-image-slice: 37 38 36 38 fill;
+  mask-box-image-slice: 37 38 36 38 fill;
+  background-color: var(--button-background);
+  background-color: W012;
+  margin-left: 7.5px;
+  margin-top: 6px;
+}
+.ui-tokentextarea-sblock {
+  -webkit-mask-box-image-repeat: repeat;
+  -moz-mask-box-image-repeat: repeat;
+  -ms-mask-box-image-repeat: repeat;
+  -o-mask-box-image-repeat: repeat;
+  mask-box-image-repeat: repeat;
+  -webkit-mask-box-image-width: auto;
+  -moz-mask-box-image-width: auto;
+  -ms-mask-box-image-width: auto;
+  -o-mask-box-image-width: auto;
+  mask-box-image-width: auto;
+  -webkit-mask-box-image-source: url('images/nine-patch/core_button_bg.png');
+  -webkit-mask-box-image-slice: 37 38 36 38 fill;
+  -moz-mask-box-image-slice: 37 38 36 38 fill;
+  -ms-mask-box-image-slice: 37 38 36 38 fill;
+  -o-mask-box-image-slice: 37 38 36 38 fill;
+  mask-box-image-slice: 37 38 36 38 fill;
+  background-color: var(--on-background);
+  background-color: W012P;
+  color: T020;
+  margin-left: 7.5px;
+  margin-top: 6px;
+}
+.ui-tokentextarea .ui-tokentextarea-desclabel {
+  display: inline-block;
+  outline: none;
+  position: relative;
+  border: 0;
+  color: T059L2;
+  text-align: left;
+  font-size: 15px;
+  margin-left: 1.5px;
+}
+.ui-tokentextarea-link-base {
+  position: absolute;
+  right: 0;
+  bottom: 2px;
+  margin-right: 4.5px;
+}
+.ui-triangle-container {
+  position: relative;
+}
+.ui-triangle-container .ui-triangle {
+  position: absolute;
+  border-style: solid;
+  border-color: transparent;
+  border-width: 10;
+}
+.ui-triangle-container .ui-triangle-top {
+  top: 0;
+  border-top-width: 0;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  margin-left: -10;
+}
+.ui-triangle-container .ui-triangle-bottom {
+  bottom: 0;
+  border-bottom-width: 0;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  margin-left: -10;
+}
+.ui-triangle-container .ui-triangle-left {
+  left: 0;
+  margin-top: -10;
+  border-left-width: 0;
+  border-left-color: transparent;
+  border-right-color: transparent;
+}
+.ui-triangle-container .ui-triangle-right {
+  right: 0;
+  margin-top: -10;
+  border-right-width: 0;
+  border-left-color: transparent;
+  border-right-color: transparent;
+}
+.ui-triangle-container-top {
+  height: 10;
+  top: 0;
+  margin-top: -10;
+}
+.ui-triangle-container-bottom {
+  height: 10;
+  bottom: 0;
+  margin-bottom: -10;
+}
+.ui-triangle-container-left {
+  width: 10;
+}
+.ui-triangle-container-right {
+  width: 10;
+}
+.ui-virtualgrid {
+  overflow: hidden;
+  position: absolute;
+}
+.ui-virtualgrid-wrapblock {
+  position: absolute;
+  left: 0;
+}
+.ui-virtualgrid-wrapblock-x {
+  float: left;
+  overflow: hidden;
+}
+.ui-virtualgrid-wrapblock-y {
+  float: left;
+  overflow: hidden;
+}
+.ui-scrollbar-thumb-x {
+  width: 1.5rem !important;
+}
+.ui-scrollbar-thumb-y {
+  height: 1.5rem !important;
+}
+.ui-virtualgrid-overflow-indicator-x-top {
+  position: absolute;
+  display: block;
+  left: 0;
+  top: 0;
+  width: 56%;
+  height: 100%;
+  opacity: 0;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  background-image: url('images/00_grid_overscrolling_left.png');
+  pointer-events: none;
+}
+.ui-virtualgrid-overflow-indicator-x-bottom {
+  position: absolute;
+  display: block;
+  right: 0;
+  bottom: 0;
+  width: 56%;
+  height: 100%;
+  opacity: 0;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  background-image: url('images/00_grid_overscrolling_right.png');
+  pointer-events: none;
+}
+.ui-virtualgrid-overflow-indicator-y-top {
+  position: absolute;
+  display: block;
+  top: 0;
+  width: 100%;
+  height: 32%;
+  opacity: 0;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  background-image: url('images/00_grid_overscrolling_top.png');
+  pointer-events: none;
+}
+.ui-virtualgrid-overflow-indicator-y-bottom {
+  position: absolute;
+  display: block;
+  bottom: 0;
+  width: 100%;
+  height: 32%;
+  opacity: 0;
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  background-image: url(images/00_grid_overscrolling_bottom.png);
+  pointer-events: none;
+}
+.ui-content.ui-virtualgrid-content {
+  padding: 0;
+}
+.ui-virtualgrid {
+  margin: 4px -4px 0 0;
+}
+.ui-virtualgrid .ui-li-static {
+  padding: 0;
+  border: none;
+  width: 100%;
+}
+.ui-virtualgrid .grid-icon {
+  width: 26.25px;
+  margin: 0 4px 4px 0;
+  display: block;
+  overflow: hidden;
+}
+.ui-virtualgrid .grid-icon.ui-btn-icon-top .ui-btn-inner.ui-btn-hastxt {
+  padding-top: 15.75px;
+}
+.ui-virtualgrid .grid-icon.ui-btn .ui-icon {
+  width: 106px;
+  height: 106px;
+  -webkit-mask-size: 106px 106px;
+  -moz-mask-size: 106px 106px;
+  -ms-mask-size: 106px 106px;
+  -o-mask-size: 106px 106px;
+  mask-size: 106px 106px;
+  margin-left: -53px;
+  background-size: 106px 106px;
+}
+.ui-virtualgrid .grid-icon:not(.ui-focus) {
+  background-color: #1b403d;
+}
+.ui-virtualgrid .grid-thumbnail {
+  width: 38px;
+  margin: 0 4px 4px 0;
+  display: block;
+  overflow: hidden;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn .ui-btn-inner {
+  margin: 0;
+  padding: 0;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn .ui-btn-inner .ui-btn-text {
+  display: block;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-info {
+  left: 2.625px;
+  right: 2.625px;
+  top: 1px;
+  position: absolute;
+  color: #c8c8c8;
+  font-size: 2.75px;
+  text-align: right;
+  z-index: 3;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic {
+  z-index: 2;
+  width: 38px;
+  height: 38px;
+  overflow: hidden;
+  background-color: #1a465f;
+  position: relative;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic img {
+  width: 25px;
+  height: 25px;
+  position: absolute;
+  top: 19px;
+  left: 19px;
+  margin: -12.5px;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic-full {
+  width: 38px;
+  height: 38px;
+  overflow: hidden;
+  position: relative;
+  z-index: 2;
+  box-sizing: border-box;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic-full img {
+  width: 38px;
+  height: 38px;
+  position: absolute;
+  top: 19px;
+  left: 19px;
+  margin: -19px;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents {
+  background: #21240d;
+  padding: 1.875px 2.5px;
+  font-size: 6.5px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  color: #d3d3d3;
+  z-index: 2;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents .grid-thumbnail-content {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  height: 3.875px;
+  line-height: 6.5px;
+  min-height: 6.5px;
+  display: block;
+}
+.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents .grid-thumbnail-subtext {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  color: #808080;
+  font-size: 2.75px;
+  margin-top: -0.75px;
+  display: block;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic {
+  border: solid #458fff;
+  border-top-width: 1px;
+  border-left-width: 1px;
+  border-right-width: 1px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic img {
+  top: 18px;
+  left: 18px;
+  margin: -12.5px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic-full {
+  border: solid #458fff;
+  border-top-width: 1px;
+  border-left-width: 1px;
+  border-right-width: 1px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic-full img {
+  top: 18px;
+  left: 18px;
+  margin: -19px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents {
+  background: #458fff;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents .grid-thumbnail-content,
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents .grid-thumbnail-subtext {
+  color: #ffffff;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-selected .ui-btn-inner {
+  border: solid #ffa955 1.25px;
+}
+.ui-virtualgrid .grid-thumbnail.ui-btn.ui-selected .ui-btn-text {
+  margin: -1.25px;
+}
+.ui-mobile-viewport-transitioning,
+.ui-mobile-viewport-transitioning .ui-page {
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+}
+.in {
+  -webkit-animation-timing-function: ease-out;
+          animation-timing-function: ease-out;
+  -webkit-animation-duration: 350ms;
+          animation-duration: 350ms;
+}
+.out {
+  -webkit-animation-timing-function: ease-in;
+          animation-timing-function: ease-in;
+  -webkit-animation-duration: 225ms;
+          animation-duration: 225ms;
+}
+@-webkit-keyframes fadein {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@keyframes fadein {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes fadeout {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+@keyframes fadeout {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+.fade.out {
+  opacity: 0;
+  -webkit-animation-duration: 125ms;
+          animation-duration: 125ms;
+  -webkit-animation-name: fadeout;
+          animation-name: fadeout;
+}
+.fade.in {
+  opacity: 1;
+  -webkit-animation-duration: 225ms;
+          animation-duration: 225ms;
+  -webkit-animation-name: fadein;
+          animation-name: fadein;
+}
+.viewport-flip {
+  position: absolute;
+  -webkit-perspective: 1000;
+  -ms-perspective: 1000;
+  -o-perspective: 1000;
+  perspective: 1000;
+}
+.flip {
+  backface-visiblity: hidden;
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+}
+.flip.out {
+  -webkit-transform: rotateY(-90 def) scale(0.9);
+          transform: rotateY(-90 def) scale(0.9);
+  -webkit-animation-name: flipouttoleft;
+          animation-name: flipouttoleft;
+  -webkit-animation-duration: 175ms;
+          animation-duration: 175ms;
+}
+.flip.out.ui-ctxpopup-container {
+  border: 2px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+}
+.flip.in {
+  -webkit-animation-name: flipintoright;
+          animation-name: flipintoright;
+  -webkit-animation-duration: 225ms;
+          animation-duration: 225ms;
+}
+.flip.in.ui-ctxpopup-container {
+  border: 2px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+}
+.ui-popup.flip.out,
+.flip.out.reverse {
+  -webkit-transform: rotateY(90deg) scale(0.9);
+          transform: rotateY(90deg) scale(0.9);
+  -webkit-animation-name: flipouttoright;
+          animation-name: flipouttoright;
+}
+.flip.in.reverse {
+  -webkit-animation-name: flipintoleft;
+          animation-name: flipintoleft;
+}
+@-webkit-keyframes flipouttoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipouttoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@-webkit-keyframes flipouttoright {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+}
+@keyframes flipouttoright {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+}
+@-webkit-keyframes flipintoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipintoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@-webkit-keyframes flipintoright {
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipintoright {
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+.flow {
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.4);
+  -webkit-transform-origin: 50% 50%;
+      -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+}
+.ui-dialog.flow {
+  box-shadow: none;
+}
+.flow.out {
+  -webkit-animation: flowouttoleft ease 350ms;
+          animation: flowouttoleft ease 350ms;
+  -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+          transform: translate3d(-100%, 0, 0) scale(0.7);
+}
+.flow.in {
+  -webkit-animation: flowinfromright ease 350ms;
+          animation: flowinfromright ease 350ms;
+  -webkit-transform: translate3d(0, 0, 0) scale(1);
+          transform: translate3d(0, 0, 0) scale(1);
+}
+.ui-popup.flow.out,
+.flow.out.reverse {
+  -webkit-transform: translate3d(100%, 0, 0);
+  -ms-transform: translate3d(100%, 0, 0);
+  transform: translate3d(100%, 0, 0);
+  -webkit-animation-name: flowouttoright;
+          animation-name: flowouttoright;
+}
+.flow.in.reverse {
+  -webkit-animation-name: flowinfromleft;
+          animation-name: flowinfromleft;
+}
+@-webkit-keyframes flowouttoleft {
+  0% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+  60%,
+  70% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+            transform: translate3d(-100%, 0, 0) scale(0.7);
+  }
+}
+@keyframes flowouttoleft {
+  0% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+  60%,
+  70% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+            transform: translate3d(-100%, 0, 0) scale(0.7);
+  }
+}
+@-webkit-keyframes flowouttoright {
+  0% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+  60%,
+  70% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(100%, 0, 0) scale(0.7);
+            transform: translate3d(100%, 0, 0) scale(0.7);
+  }
+}
+@keyframes flowouttoright {
+  0% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+  60%,
+  70% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(100%, 0, 0) scale(0.7);
+            transform: translate3d(100%, 0, 0) scale(0.7);
+  }
+}
+@-webkit-keyframes flowinfromleft {
+  0% {
+    -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+            transform: translate3d(-100%, 0, 0) scale(0.7);
+  }
+  30%,
+  40% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+}
+@keyframes flowinfromleft {
+  0% {
+    -webkit-transform: translate3d(-100%, 0, 0) scale(0.7);
+            transform: translate3d(-100%, 0, 0) scale(0.7);
+  }
+  30%,
+  40% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+}
+@-webkit-keyframes flowinfromright {
+  0% {
+    -webkit-transform: translate3d(100%, 0, 0) scale(0.7);
+            transform: translate3d(100%, 0, 0) scale(0.7);
+  }
+  30%,
+  40% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+}
+@keyframes flowinfromright {
+  0% {
+    -webkit-transform: translate3d(100%, 0, 0) scale(0.7);
+            transform: translate3d(100%, 0, 0) scale(0.7);
+  }
+  30%,
+  40% {
+    -webkit-transform: translate3d(0, 0, 0) scale(0.7);
+            transform: translate3d(0, 0, 0) scale(0.7);
+  }
+  100% {
+    -webkit-transform: translate3d(0, 0, 0) scale(1);
+            transform: translate3d(0, 0, 0) scale(1);
+  }
+}
+.pop {
+  -webkit-transform-origin: 50% 50%;
+      -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+}
+.pop.in {
+  -webkit-transform: scale(1);
+  -ms-transform: scale(1);
+  transform: scale(1);
+  opacity: 1;
+  -webkit-animation: popin 350ms;
+          animation: popin 350ms;
+}
+.pop.in.ui-ctxpopup-container {
+  border: 2px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+}
+.pop.out {
+  -webkit-animation: fadeout 100ms;
+          animation: fadeout 100ms;
+}
+.pop.out.ui-ctxpopup-container {
+  border: 2px solid var(--more-options-stroke-color);
+  border-radius: 5px;
+  box-shadow: none;
+}
+.pop.in.reverse {
+  -webkit-animation-name: fadein;
+          animation-name: fadein;
+}
+.ui-popup.pop.out,
+.pop.out.reverse {
+  -webkit-transform: scale(0.8);
+  -ms-transform: scale(0.8);
+  transform: scale(0.8);
+  -webkit-animation-name: popout;
+          animation-name: popout;
+}
+@-webkit-keyframes popin {
+  from {
+    -webkit-transform: scale(0.8);
+    -ms-transform: scale(0.8);
+    transform: scale(0.8);
+    opacity: 0;
+  }
+  to {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@keyframes popin {
+  from {
+    -webkit-transform: scale(0.8);
+    -ms-transform: scale(0.8);
+    transform: scale(0.8);
+    opacity: 0;
+  }
+  to {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@-webkit-keyframes popout {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0.8);
+    -ms-transform: scale(0.8);
+    transform: scale(0.8);
+    opacity: 0;
+  }
+}
+@keyframes popout {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0.8);
+    -ms-transform: scale(0.8);
+    transform: scale(0.8);
+    opacity: 0;
+  }
+}
+.slide.out,
+.slide.in {
+  -webkit-animation-timing-function: ease-out;
+          animation-timing-function: ease-out;
+  -webkit-animation-duration: 350ms;
+          animation-duration: 350ms;
+}
+.slide.out {
+  -webkit-transform: translate3d(-100%, 0, 0);
+  -ms-transform: translate3d(-100%, 0, 0);
+  transform: translate3d(-100%, 0, 0);
+  -webkit-animation-name: slideouttoleft;
+          animation-name: slideouttoleft;
+}
+.slide.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation-name: slideinfromright;
+          animation-name: slideinfromright;
+}
+.ui-popup.slide.out,
+.slide.out.reverse {
+  -webkit-transform: translate3d(100%, 0, 0);
+  -ms-transform: translate3d(100%, 0, 0);
+  transform: translate3d(100%, 0, 0);
+  -webkit-animation-name: slideouttoright;
+          animation-name: slideouttoright;
+}
+.slide.in.reverse {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation-name: slideinfromleft;
+          animation-name: slideinfromleft;
+}
+@-webkit-keyframes slideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes slideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes slideinfromleft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes slideinfromleft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes slideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+@keyframes slideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+@-webkit-keyframes slideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@keyframes slideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+.slidedown.out {
+  -webkit-animation: fadeout 100ms;
+          animation: fadeout 100ms;
+}
+.slidedown.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: slideinfromtop 250ms;
+          animation: slideinfromtop 250ms;
+}
+.slidedown.in.reverse {
+  -webkit-animation: fade 150ms;
+          animation: fade 150ms;
+}
+.ui-popup.slidedown.out,
+.slidedown.out.reverse {
+  -webkit-transform: translate3d(0, -100%, 0);
+  -ms-transform: translate3d(0, -100%, 0);
+  transform: translate3d(0, -100%, 0);
+  -webkit-animation: slideouttotop 200ms;
+          animation: slideouttotop 200ms;
+}
+@-webkit-keyframes slideinfromtop {
+  from {
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes slideinfromtop {
+  from {
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes slideouttotop {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+@keyframes slideouttotop {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+.slideupfade.out {
+  -webkit-animation: fadeout 100ms;
+          animation: fadeout 100ms;
+}
+.slideupfade.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: slideupfadeinfrombottom 250ms;
+          animation: slideupfadeinfrombottom 250ms;
+}
+.slideupfade.in.reverse {
+  -webkit-animation: fadein 150ms;
+          animation: fadein 150ms;
+}
+.ui-popup.slideupfade.out,
+.slideupfade.out.reverse {
+  -webkit-transform: translate3d(0, 5%, 0);
+  -ms-transform: translate3d(0, 5%, 0);
+  transform: translate3d(0, 5%, 0);
+  -webkit-animation: slideupfadeouttobottom 200ms;
+          animation: slideupfadeouttobottom 200ms;
+}
+@-webkit-keyframes slideupfadeinfrombottom {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 5%, 0);
+    -ms-transform: translate3d(0, 5%, 0);
+    transform: translate3d(0, 5%, 0);
+  }
+  to {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes slideupfadeinfrombottom {
+  from {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 5%, 0);
+    -ms-transform: translate3d(0, 5%, 0);
+    transform: translate3d(0, 5%, 0);
+  }
+  to {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes slideupfadeouttobottom {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 5%, 0);
+    -ms-transform: translate3d(0, 5%, 0);
+    transform: translate3d(0, 5%, 0);
+  }
+}
+@keyframes slideupfadeouttobottom {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 5%, 0);
+    -ms-transform: translate3d(0, 5%, 0);
+    transform: translate3d(0, 5%, 0);
+  }
+}
+.slidedownfade.out {
+  -webkit-animation: fadeout 100ms;
+          animation: fadeout 100ms;
+}
+.slidedownfade.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: slidedownfadeinfromtop 250ms;
+          animation: slidedownfadeinfromtop 250ms;
+}
+.slidedownfade.in.reverse {
+  -webkit-animation: fadein 150ms;
+          animation: fadein 150ms;
+}
+.ui-popup.slidedownfade.out,
+.slidedownfade.out.reverse {
+  -webkit-transform: translate3d(0, -5%, 0);
+  -ms-transform: translate3d(0, -5%, 0);
+  transform: translate3d(0, -5%, 0);
+  -webkit-animation: slidedownfadeouttotop 200ms;
+          animation: slidedownfadeouttotop 200ms;
+}
+@-webkit-keyframes slidedownfadeinfromtop {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -5%, 0);
+    -ms-transform: translate3d(0, -5%, 0);
+    transform: translate3d(0, -5%, 0);
+  }
+}
+@keyframes slidedownfadeinfromtop {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -5%, 0);
+    -ms-transform: translate3d(0, -5%, 0);
+    transform: translate3d(0, -5%, 0);
+  }
+}
+@-webkit-keyframes slidedownfadeouttotop {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -5%, 0);
+    -ms-transform: translate3d(0, -5%, 0);
+    transform: translate3d(0, -5%, 0);
+  }
+}
+@keyframes slidedownfadeouttotop {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -5%, 0);
+    -ms-transform: translate3d(0, -5%, 0);
+    transform: translate3d(0, -5%, 0);
+  }
+}
+.slidefade.out {
+  -webkit-transform: translate3d(-100%, 0, 0);
+  -ms-transform: translate3d(-100%, 0, 0);
+  transform: translate3d(-100%, 0, 0);
+  -webkit-animation: slideouttoleft 225ms;
+          animation: slideouttoleft 225ms;
+}
+.slidefade.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: fadein 200ms;
+          animation: fadein 200ms;
+}
+.ui-popup.slidefade.out,
+.slidefade.out.reverse {
+  -webkit-transform: translate3d(100%, 0, 0);
+  -ms-transform: translate3d(100%, 0, 0);
+  transform: translate3d(100%, 0, 0);
+  -webkit-animation: slideouttoright 200ms;
+          animation: slideouttoright 200ms;
+}
+.slidefade.in.reverse {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation: fadein 200ms;
+          animation: fadein 200ms;
+}
+.viewport-turn {
+  -webkit-perspective: 1000;
+  -ms-perspective: 1000;
+  -o-perspective: 1000;
+  perspective: 1000;
+  position: absolute;
+}
+.turn {
+  backface-visiblity: hidden;
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+}
+.turn.out {
+  -webkit-transform: rotateY(-90deg) scale(0.9);
+          transform: rotateY(-90deg) scale(0.9);
+  -webkit-animation: flipouttoleft 125ms;
+          animation: flipouttoleft 125ms;
+}
+.turn.in {
+  -webkit-animation: flipintoright 250ms;
+          animation: flipintoright 250ms;
+}
+.ui-popup.turn.out,
+.turn.out.reverse {
+  -webkit-transform: rotateY(90deg) scale(0.9);
+          transform: rotateY(90deg) scale(0.9);
+  -webkit-animation-name: flipouttoright;
+          animation-name: flipouttoright;
+}
+.turn.in.reverse {
+  -webkit-animation-name: flipintoleft;
+          animation-name: flipintoleft;
+}
+@-webkit-keyframes flipouttoleft {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+}
+@keyframes flipouttoleft {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+}
+@-webkit-keyframes flipouttoright {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+}
+@keyframes flipouttoright {
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  from {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  to {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+}
+@-webkit-keyframes flipintoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipintoleft {
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(-90deg) scale(0.9);
+            transform: rotateY(-90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@-webkit-keyframes flipintoright {
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+@keyframes flipintoright {
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+  from {
+    -webkit-transform: rotateY(90deg) scale(0.9);
+            transform: rotateY(90deg) scale(0.9);
+  }
+  to {
+    -webkit-transform: rotateY(0);
+            transform: rotateY(0);
+  }
+}
+.depth {
+  -webkit-transform-origin: 50% 50%;
+      -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+}
+.depth.out {
+  opacity: 0;
+  -webkit-animation: depthout 250ms ease;
+          animation: depthout 250ms ease;
+}
+.depth.in {
+  -webkit-transform: scale(1);
+  -ms-transform: scale(1);
+  transform: scale(1);
+  opacity: 1;
+  -webkit-animation: depthin 350ms ease;
+          animation: depthin 350ms ease;
+}
+.depth.in.reverse {
+  -webkit-animation-name: depthinreverse;
+          animation-name: depthinreverse;
+}
+.ui-popup.depth.out,
+.depth.out.reverse {
+  -webkit-transform: scale(0.9);
+  -ms-transform: scale(0.9);
+  transform: scale(0.9);
+  -webkit-animation-name: depthoutreverse;
+          animation-name: depthoutreverse;
+}
+@-webkit-keyframes depthout {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+}
+@keyframes depthout {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+}
+@-webkit-keyframes depthin {
+  0% {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+  30% {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@keyframes depthin {
+  0% {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+  30% {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@-webkit-keyframes depthinreverse {
+  0% {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+  30% {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@keyframes depthinreverse {
+  0% {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+  30% {
+    -webkit-transform: scale(1.1);
+    -ms-transform: scale(1.1);
+    transform: scale(1.1);
+    opacity: 0;
+  }
+  100% {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+}
+@-webkit-keyframes depthoutreverse {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+}
+@keyframes depthoutreverse {
+  from {
+    -webkit-transform: scale(1);
+    -ms-transform: scale(1);
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0.9);
+    -ms-transform: scale(0.9);
+    transform: scale(0.9);
+    opacity: 0;
+  }
+}
+.ui-mobile-viewport-transitioning,
+.ui-mobile-viewport-transitioning .ui-page {
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+}
+/* slide */
+.ui-page.slide.out,
+.ui-page.slide.in {
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
+  -webkit-animation-duration: 400ms;
+  animation-duration: 400ms;
+}
+.ui-page.slide.out {
+  -webkit-animation-name: pageslideouttoleft;
+  animation-name: pageslideouttoleft;
+}
+.ui-page.slide.in {
+  -webkit-animation-name: pageslideinfromright;
+  animation-name: pageslideinfromright;
+}
+.ui-page.slide.out.reverse {
+  -webkit-animation-name: pageslideouttoright;
+  animation-name: pageslideouttoright;
+  z-index: 2000;
+}
+.ui-page.slide.in.reverse {
+  -webkit-animation-name: pageslideinfromleft;
+  animation-name: pageslideinfromleft;
+}
+.ui-page.slide.in.reverse::after,
+.ui-page.slide.out:not(.reverse)::after {
+  content: "";
+  background-image: url("images/page/core_theme_bg_01.png");
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 2000;
+  opacity: 0;
+}
+.ui-page.slide.in.reverse::after {
+  -webkit-animation: pagebgslideinreverse 400ms ease-out;
+  animation: pagebgslideinreverse 400ms ease-out;
+}
+.ui-page.slide.out:not(.reverse)::after {
+  -webkit-animation: pagebgslideout 400ms ease-out;
+  animation: pagebgslideout 400ms ease-out;
+}
+@-webkit-keyframes pageslideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-25%, 0, 0);
+    -ms-transform: translate3d(-25%, 0, 0);
+    transform: translate3d(-25%, 0, 0);
+  }
+}
+@keyframes pageslideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-25%, 0, 0);
+    -ms-transform: translate3d(-25%, 0, 0);
+    transform: translate3d(-25%, 0, 0);
+  }
+}
+@-webkit-keyframes pageslideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes pageslideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes pageslideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@keyframes pageslideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@-webkit-keyframes pageslideinfromleft {
+  from {
+    -webkit-transform: translate3d(-25%, 0, 0);
+    -ms-transform: translate3d(-25%, 0, 0);
+    transform: translate3d(-25%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes pageslideinfromleft {
+  from {
+    -webkit-transform: translate3d(-25%, 0, 0);
+    -ms-transform: translate3d(-25%, 0, 0);
+    transform: translate3d(-25%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes pagebgslideinreverse {
+  from {
+    opacity: .5;
+  }
+  to {
+    opacity: 0;
+  }
+}
+@keyframes pagebgslideinreverse {
+  from {
+    opacity: .5;
+  }
+  to {
+    opacity: 0;
+  }
+}
+@-webkit-keyframes pagebgslideout {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: .5;
+  }
+}
+@keyframes pagebgslideout {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: .5;
+  }
+}
+/* slide up */
+.ui-page.slideup.out {
+  -webkit-animation-name: fadeout;
+  animation-name: fadeout;
+  -webkit-animation-duration: 250ms;
+  animation-duration: 250ms;
+}
+.ui-page.slideup.in {
+  -webkit-transform: translate3d(0, 0, 0);
+  -ms-transform: translate3d(0, 0, 0);
+  transform: translate3d(0, 0, 0);
+  -webkit-animation-name: pageslideinfrombottom;
+  animation-name: pageslideinfrombottom;
+  -webkit-animation-duration: 200ms;
+  animation-duration: 200ms;
+}
+.ui-page.slideup.in.reverse {
+  -webkit-animation-name: fadein;
+  animation-name: fadein;
+  -webkit-animation-duration: 250ms;
+  animation-duration: 250ms;
+}
+.ui-page.slideup.out.reverse {
+  -webkit-transform: translate3d(0, 100%, 0);
+  -ms-transform: translate3d(0, 100%, 0);
+  transform: translate3d(0, 100%, 0);
+  -webkit-animation-name: pageslideouttobottom;
+  animation-name: pageslideouttobottom;
+  -webkit-animation-duration: 200ms;
+  animation-duration: 200ms;
+}
+@-webkit-keyframes pageslideinfrombottom {
+  from {
+    -webkit-transform: translate3d(0, 100%, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes pageslideouttobottom {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 100%, 0);
+  }
+}
+/*** less definitions ***/
+ul.ui-virtual-list-container > ul.position_absolute {
+  position: absolute;
+}
+.ui-listview.ui-virtual-list-container .ui-li {
+  position: relative;
+}
+.ui-virtual-list-edge-effect {
+  pointer-events: none;
+  width: 100%;
+  height: 0;
+  position: absolute;
+  top: 0;
+  left: 0;
+  box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
+}
+.ui-virtual-list-edge-effect.orientation-horizontal {
+  height: 100%;
+  width: 0;
+}
+.ui-grid-a,
+.ui-grid-b,
+.ui-grid-c,
+.ui-grid-d {
+  overflow: hidden;
+}
+.ui-block-a,
+.ui-block-b,
+.ui-block-c,
+.ui-block-d,
+.ui-block-e {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  float: left;
+  min-height: 1px;
+}
+.ui-grid-solo .ui-block-a {
+  width: 100%;
+  float: none;
+}
+.ui-grid-a .ui-block-a,
+.ui-grid-a .ui-block-b {
+  width: 50%;
+}
+.ui-grid-a .ui-block-a {
+  clear: left;
+}
+.ui-grid-b .ui-block-a,
+.ui-grid-b .ui-block-b,
+.ui-grid-b .ui-block-c {
+  width: 33.333%;
+}
+.ui-grid-b .ui-block-a {
+  clear: left;
+}
+.ui-grid-c .ui-block-a,
+.ui-grid-c .ui-block-b,
+.ui-grid-c .ui-block-c,
+.ui-grid-c .ui-block-d {
+  width: 25%;
+}
+.ui-grid-c .ui-block-a {
+  clear: left;
+}
+.ui-grid-d .ui-block-a,
+.ui-grid-d .ui-block-b,
+.ui-grid-d .ui-block-c,
+.ui-grid-d .ui-block-d,
+.ui-grid-d .ui-block-e {
+  width: 20%;
+}
+.ui-grid-d .ui-block-a {
+  clear: left;
+}
+.ui-navbar {
+  overflow: hidden;
+}
+.ui-navbar ul,
+.ui-navbar-expanded ul {
+  list-style: none;
+  padding: 0;
+  margin: 0;
+  position: relative;
+  display: block;
+  border: 0;
+}
+.ui-navbar-collapsed ul {
+  float: left;
+  width: 75%;
+  margin-right: -2px;
+}
+.ui-navbar-collapsed .ui-navbar-toggle {
+  float: left;
+  width: 25%;
+}
+.ui-navbar .ui-navbar-truncate {
+  position: absolute;
+  left: -9999px;
+  top: -9999px;
+}
+.ui-navbar li .ui-btn,
+.ui-navbar .ui-navbar-toggle .ui-btn {
+  display: block;
+  text-align: center;
+  margin: 0;
+  border-right-width: 0;
+}
+.ui-navbar li .ui-btn {
+  margin-right: -1px;
+}
+.ui-navbar li .ui-btn:last-child {
+  margin-right: 0;
+}
+.ui-header .ui-navbar .ui-btn,
+.ui-footer .ui-navbar .ui-btn {
+  border-top-width: 0;
+}
+.ui-navbar .ui-btn-inner {
+  padding-left: 2px;
+  padding-right: 2px;
+}
+.ui-navbar-noicons .ui-btn-inner {
+  padding-top: .8em;
+  padding-bottom: .9em;
+}
+.ui-navbar-expanded .ui-btn {
+  margin: 0;
+  font-size: 14px;
+}
+.ui-navbar-expanded .ui-btn-inner {
+  padding-left: 5px;
+  padding-right: 5px;
+}
+.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner {
+  padding: 45px 5px 15px;
+  text-align: center;
+}
+.ui-navbar-expanded .ui-btn-icon-top .ui-icon {
+  top: 15px;
+}
+.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner {
+  padding: 15px 5px 45px;
+  text-align: center;
+}
+.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon {
+  bottom: 15px;
+}
+.ui-navbar-expanded .ui-btn-inner {
+  min-height: 2.5em;
+}
+.ui-navbar-expanded .ui-navbar-noicons .ui-btn-inner {
+  padding-top: 1.8em;
+  padding-bottom: 1.9em;
+}
+.ui-select {
+  display: block;
+  position: relative;
+}
+.ui-select select {
+  position: absolute;
+  left: -9999px;
+  top: -9999px;
+}
+.ui-select .ui-btn {
+  overflow: hidden;
+}
+.ui-select .ui-btn select {
+  cursor: pointer;
+  -webkit-appearance: button;
+  left: 0;
+  top: 0;
+  width: 100%;
+  min-height: 100%;
+  height: 3em;
+  max-height: 100%;
+  opacity: 0;
+  -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
+  filter: alpha(opacity=0);
+  z-index: 2;
+}
+.ui-select .ui-btn select.ui-select-nativeonly {
+  opacity: 1;
+  text-indent: 0;
+}
+.ui-select .ui-btn-icon-right .ui-btn-inner {
+  padding-right: 45px;
+}
+.ui-select .ui-btn-icon-right .ui-icon {
+  right: 15px;
+}
+label.ui-select {
+  font-size: 16px;
+  line-height: 1.4;
+  font-weight: normal;
+  margin: 0 0 .3em;
+  display: block;
+}
+.ui-select .ui-btn-text,
+.ui-selectmenu .ui-btn-text {
+  display: block;
+  min-height: 1em;
+}
+.ui-select .ui-btn-text {
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+.ui-selectmenu .ui-listview {
+  margin: 0;
+}
+.ui-selectmenu .ui-btn.ui-li-divider {
+  cursor: default;
+}
+.ui-selectmenu-hidden {
+  top: -9999px;
+  left: -9999px;
+  visibility: hidden;
+}
+.ui-selectmenu-screen {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 99;
+}
+.ui-selectmenu-list .ui-li .ui-icon {
+  display: none;
+}
+.ui-selectmenu-list .ui-li .ui-icon {
+  display: block;
+}
+.ui-li.ui-selectmenu-placeholder {
+  display: none;
+}
+.ui-selectmenu .ui-header .ui-title {
+  margin: .6em 46px .8em;
+}
+@media all and (min-width: 450px) {
+  label.ui-select {
+    vertical-align: top;
+    display: inline-block;
+    width: 20%;
+    margin: 0 2% 0 0;
+  }
+  .ui-select {
+    width: 60%;
+    display: inline-block;
+  }
+}
+.ui-selectmenu .ui-header h1::after {
+  content: '.';
+  visibility: hidden;
+}
+.ui-selectmenu .ui-header .ui-btn-icon_only .ui-btn-text {
+  position: absolute;
+  left: -9999px;
+}
+.ui-selectmenu .ui-header .ui-btn-icon_only .ui-icon {
+  margin: auto;
+}
+.ui-page.ui-empty-state .ui-header {
+  background-color: var(--background-color);
+}
+.ui-page.ui-empty-state .ui-content {
+  position: relative;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  height: 100%;
+  background-color: var(--background-color);
+}
+.ui-page.ui-empty-state .ui-content::before {
+  content: '';
+  display: block;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  -webkit-mask-image: url('images/00_page_empty_bg.png');
+          mask-image: url('images/00_page_empty_bg.png');
+  -webkit-mask-size: 100% auto;
+          mask-size: 100% auto;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  background-color: var(--background-color);
+}
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view {
+  padding-left: 16px;
+  padding-right: 16px;
+  text-align: center;
+  font-size: 16px;
+  color: var(--text-color);
+  line-height: 21.5px;
+  min-height: 286px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h1,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h2,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h3,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h4,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h5,
+.ui-page.ui-empty-state .ui-content .ui-scrollview-view h6 {
+  margin: 0;
+  margin-bottom: 27px;
+  line-height: 27px;
+  font-size: 20px;
+  font-weight: lighter;
+  color: T0222L1;
+}
+@media only screen and (orientation: landscape) {
+  .ui-page.ui-empty-state .ui-content:before {
+    -webkit-mask-image: url('images/00_page_empty_bg_h.png');
+            mask-image: url('images/00_page_empty_bg_h.png');
+    -webkit-mask-size: 100% 100px;
+            mask-size: 100% 100px;
+  }
+}
+.ui-listview.ui-listview-empty-state-show {
+  height: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-listview.ui-listview-empty-state-show .ui-li-empty-state {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-listview.ui-listview-empty-state-show .ui-li-static {
+  height: 27px;
+}
+.ui-listview .ui-li-empty-state {
+  width: 100%;
+  display: none;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  position: relative;
+  -webkit-align-content: center;
+      -ms-flex-line-pack: center;
+          align-content: center;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  box-sizing: border-box;
+  padding: 0 0 42px 0;
+}
+.ui-empty-state-content {
+  pointer-events: none;
+  padding-left: 16px;
+  padding-right: 16px;
+  text-align: center;
+  font-size: 16px;
+  color: T0222L4;
+  line-height: 21.5px;
+  height: 286px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-empty-state-content h1,
+.ui-empty-state-content h2,
+.ui-empty-state-content h3,
+.ui-empty-state-content h4,
+.ui-empty-state-content h5,
+.ui-empty-state-content h6 {
+  margin: 0;
+  margin-bottom: 27px;
+  line-height: 27px;
+  font-size: 20px;
+  font-weight: lighter;
+  color: T0222L3;
+}
+.ui-page-floatingactions .ui-listview .ui-li-empty-state {
+  padding: 0 0 94px 0;
+}
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+  appearance: none;
+}
+input[type="search"][disabled] {
+  background-color: transparent;
+}
+.ui-search-input {
+  font-size: 20px;
+  overflow: hidden;
+  background-color: transparent;
+  text-shadow: 0 0 0 var(--text-color);
+  color: var(--text-input-inactive);
+  -webkit-text-fill-color: transparent;
+}
+.ui-search-input:focus {
+  text-shadow: 0 0 0 var(--text-color);
+  border-color: var(--text-input-underline-active);
+}
+.ui-search-input.ui-state-disabled {
+  text-shadow: 0 0 0 var(--text-input-disabled);
+  border-bottom: 2px solid var(--text-input-disabled);
+}
+.ui-search-input.ui-state-disabled::-webkit-input-placeholder {
+  color: var(--text-input-label-inactive);
+  text-shadow: none;
+  -webkit-text-fill-color: initial;
+}
+.ui-header-searchbar {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  padding: 0 8.5px 0 5px;
+  box-sizing: border-box;
+  overflow: initial;
+}
+.ui-header-searchbar > .ui-search-input,
+.ui-header-searchbar > input {
+  border: 0;
+  outline: 0;
+  overflow: hidden;
+  border-bottom: 1px solid;
+  border-bottom-color: var(--text-input-underline-active);
+  font-size: 20px;
+  color: var(--primary-color);
+  background-color: transparent;
+  -webkit-text-fill-color: transparent;
+  height: 40px;
+  text-shadow: 0 0 0 var(--text-color);
+  box-sizing: border-box;
+  -webkit-flex-grow: 1;
+      -ms-flex-positive: 1;
+          flex-grow: 1;
+  padding: 2px 5px 0 5px;
+  margin-right: 7.5px;
+}
+.ui-header-searchbar > .ui-search-input.ui-text-input-clear-active:focus,
+.ui-header-searchbar > input.ui-text-input-clear-active:focus,
+.ui-header-searchbar > .ui-search-input.ui-text-input-clear-active:active,
+.ui-header-searchbar > input.ui-text-input-clear-active:active {
+  text-shadow: 0 0 0 var(--text-color);
+  padding: 2px 41px 0 5px;
+}
+.ui-header-searchbar > .ui-search-input[disabled],
+.ui-header-searchbar > input[disabled],
+.ui-header-searchbar > .ui-search-input.ui-state-disabled,
+.ui-header-searchbar > input.ui-state-disabled {
+  text-shadow: 0 0 0 var(--text-input-disabled);
+}
+.ui-header-searchbar > .ui-search-input[disabled]::-webkit-input-placeholder,
+.ui-header-searchbar > input[disabled]::-webkit-input-placeholder,
+.ui-header-searchbar > .ui-search-input.ui-state-disabled::-webkit-input-placeholder,
+.ui-header-searchbar > input.ui-state-disabled::-webkit-input-placeholder {
+  text-shadow: var(--text-input-label-inactive);
+}
+.ui-header-searchbar > .ui-search-input::-webkit-input-placeholder,
+.ui-header-searchbar > input::-webkit-input-placeholder {
+  text-shadow: 0 0 0 var(--primary-color);
+}
+.ui-header-searchbar > .ui-search-input ~ .ui-text-input-clear.ui-btn.ui-btn-icon,
+.ui-header-searchbar > input ~ .ui-text-input-clear.ui-btn.ui-btn-icon {
+  top: 7.5px;
+  position: absolute;
+  right: 8.5px;
+  margin: 0;
+}
+.ui-header-searchbar > .ui-search-input ~ .ui-text-input-clear.ui-btn.ui-btn-icon::after,
+.ui-header-searchbar > input ~ .ui-text-input-clear.ui-btn.ui-btn-icon::after {
+  background-color: var(--text-color);
+}
+.ui-header-searchbar > .ui-search-input + .ui-btn.ui-btn-icon + .ui-text-input-clear.ui-btn.ui-btn-icon,
+.ui-header-searchbar > input + .ui-btn.ui-btn-icon + .ui-text-input-clear.ui-btn.ui-btn-icon {
+  right: 49.5px;
+}
+.ui-header-searchbar > .ui-search-input ~ .ui-btn-nobg::before,
+.ui-header-searchbar > input ~ .ui-btn-nobg::before {
+  background-color: var(--ripple-color);
+}
+.ui-header-searchbar .ui-header-btn-right ~ .ui-text-input-clear.ui-btn.ui-btn-icon {
+  right: 49.5px;
+}
+.ui-header-searchbar > .ui-btn:not(.ui-btn-nobg),
+.ui-header-searchbar .ui-header-btn-left.btn-icon-back,
+.ui-header-searchbar .ui-header-btn-icon.ui-header-btn-right {
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+  position: relative;
+}
+.ui-header-searchbar > .ui-btn.ui-btn-icon:not(.ui-text-input-clear):not(.btn-icon-back)::after {
+  -webkit-mask-size: 25px 25px;
+          mask-size: 25px 25px;
+}
+.ui-header-searchbar > .ui-header-btn-right {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  position: relative;
+}
+.ui-handler {
+  position: fixed;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  overflow: hidden;
+  opacity: 0;
+  transition: opacity 400ms ease-out;
+  height: 100%;
+  top: 0;
+  right: 0;
+}
+.ui-handler .ui-handler-track {
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  position: relative;
+  width: 100%;
+  height: 100%;
+  display: block;
+}
+.ui-handler .ui-handler-track .ui-handler-handle {
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  position: absolute;
+  display: block;
+  background-color: transparent;
+}
+.ui-handler .ui-handler-track .ui-handler-handle .ui-handler-expander {
+  width: 100%;
+  height: 100%;
+  float: right;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  background-color: var(--primary-color);
+  border-radius: 2.5px;
+  transition-property: width border-width border-radius;
+  transition-duration: 100ms;
+}
+.ui-handler .ui-handler-track .ui-handler-handle.ui-active .ui-handler-thumb:before {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 16px;
+  height: 16px;
+  -webkit-mask-size: 100%;
+  -moz-mask-size: 100%;
+  -ms-mask-size: 100%;
+  -o-mask-size: 100%;
+  mask-size: 100%;
+  background-color: var(--icon-color);
+}
+.ui-handler .ui-handler-track .ui-handler-handle.ui-active .ui-handler-thumb:after {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 16px;
+  height: 16px;
+  -webkit-mask-size: 100%;
+  -moz-mask-size: 100%;
+  -ms-mask-size: 100%;
+  -o-mask-size: 100%;
+  mask-size: 100%;
+  background-color: var(--icon-color);
+}
+.ui-handler.ui-handler-direction-x {
+  right: 5px;
+  bottom: 0px;
+  left: 5px;
+  height: 19px;
+  top: auto;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-handle {
+  min-width: 22px;
+  height: 16px;
+  margin-bottom: 3px;
+  top: auto;
+  bottom: 0;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: flex-end;
+  -moz-align-items: flex-end;
+  -ms-align-items: flex-end;
+  -o-align-items: flex-end;
+  -ms-flex-align: end;
+      align-items: flex-end;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-handle .ui-handler-expander {
+  height: 5px;
+  width: 100%;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-track .ui-handler-handle.ui-active {
+  min-width: 41px;
+  margin-bottom: 3px;
+  border-radius: 8px;
+  -webkit-flex-direction: row;
+  -moz-flex-direction: row;
+  -ms-flex-direction: row;
+  -o-flex-direction: row;
+  flex-direction: row;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-track .ui-handler-handle.ui-active .ui-handler-expander {
+  height: 16px;
+  border-radius: 8px;
+}
+.ui-handler.ui-handler-direction-x .ui-handler-thumb:before {
+  -webkit-mask-image: url("images/core_index_scroll_handler_h_01.png");
+          mask-image: url("images/core_index_scroll_handler_h_01.png");
+}
+.ui-handler.ui-handler-direction-x .ui-handler-thumb:after {
+  -webkit-mask-image: url("images/core_index_scroll_handler_h_02.png");
+          mask-image: url("images/core_index_scroll_handler_h_02.png");
+}
+.ui-handler.ui-handler-direction-y {
+  top: 0;
+  right: 0;
+  bottom: 0;
+  width: 19px;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+}
+.ui-handler.ui-handler-direction-y:before {
+  content: "";
+  width: 100%;
+  height: 55px;
+  background-color: transparent;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-handle {
+  width: 16px;
+  margin-right: 3px;
+  min-height: 22px;
+  left: auto;
+  right: 0;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-handle .ui-handler-expander {
+  width: 5px;
+  height: 100%;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-track {
+  margin: 5px 0;
+  background-color: transparent;
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-track .ui-handler-handle.ui-active {
+  width: 16px;
+  margin-right: 3px;
+  min-height: 41px;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-track .ui-handler-handle.ui-active .ui-handler-expander {
+  border-radius: 8px;
+  width: 16px;
+}
+.ui-handler.ui-handler-direction-y .ui-handler-thumb:before {
+  -webkit-mask-image: url("images/core_index_scroll_handler_v_01.png");
+          mask-image: url("images/core_index_scroll_handler_v_01.png");
+}
+.ui-handler.ui-handler-direction-y .ui-handler-thumb:after {
+  -webkit-mask-image: url("images/core_index_scroll_handler_v_02.png");
+          mask-image: url("images/core_index_scroll_handler_v_02.png");
+}
+.ui-handler.disabled {
+  display: none;
+}
+.ui-handler .ui-handler-thumb {
+  width: 16px;
+  height: 16px;
+  position: relative;
+}
+.ui-handler-visible {
+  opacity: 1;
+}
+.scrollbar-disabled {
+  overflow: hidden !important;
+}
+.scrollbar-disabled .ui-scrollview-clip {
+  width: 105%;
+}
+.scrollbar-disabled .ui-scrollview-clip[data-direction="x"] {
+  width: 100%;
+  height: 105%;
+}
+.ui-container {
+  white-space: nowrap;
+  padding-bottom: 10px;
+}
+.ui-container > * {
+  scroll-snap-align: center;
+}
+.ui-container .ui-container-item {
+  display: inline-block;
+  margin-left: 3px;
+  margin-right: 3px;
+  width: 188px;
+}
+.ui-container .ui-container-item:last-child {
+  padding-right: 20px;
+}
+.ui-container.ui-container-middle .ui-favorite.ui-btn {
+  width: 103px;
+}
+.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content {
+  width: 103px;
+}
+.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content img {
+  width: 100px;
+  height: 100px;
+}
+.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content .ui-title,
+.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content .ui-subtitle {
+  font-family: Roboto-Medium;
+  width: 100%;
+  text-align: left;
+  text-overflow: ellipsis;
+  color: #7b7b7b;
+}
+.ui-drawer {
+  position: absolute;
+  background-color: var(--background-color);
+  z-index: 1201;
+  box-sizing: border-box;
+  overflow-x: hidden;
+  overflow-y: scroll;
+}
+.ui-drawer-header {
+  height: 56px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-drawer-title {
+  font-size: 19px;
+  color: var(--appbar-main-text-color);
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  margin-left: 20px;
+}
+.ui-drawer .ui-listview {
+  margin: 0;
+  position: absolute;
+  z-index: 2000;
+  width: 100%;
+  height: 100%;
+}
+.ui-drawer .ui-listview .ui-drawer-sub-list > .ui-btn-inner .ui-btn-text .ui-link-inherit {
+  padding-left: 13px;
+}
+.ui-drawer-overlay {
+  position: absolute;
+  background-color: var(--overlay);
+  z-index: 1200;
+}
+.ui-header .ui-btn.ui-drawer-button.ui-btn-icon-only {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 27px;
+  height: 36px;
+}
+.ui-header .ui-btn.ui-drawer-button.ui-btn-icon-only::after {
+  width: 27px;
+  height: 36px;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  margin-top: 0;
+  top: 0;
+  left: 0;
+}
+.ui-dropdownmenu-overlay {
+  opacity: 0;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 1200;
+}
+.ui-dropdownmenu {
+  box-sizing: border-box;
+  width: 100%;
+  display: block;
+  position: relative;
+}
+.ui-dropdownmenu:focus {
+  outline: none;
+}
+.ui-dropdownmenu:active {
+  outline: none;
+}
+.ui-dropdownmenu:active .ui-dropdownmenu-placeholder {
+  background-color: W021L1P;
+}
+.ui-dropdownmenu::before {
+  content: "";
+  opacity: 0;
+  width: 90%;
+  height: 26px;
+  background-color: var(--ripple-color);
+  position: absolute;
+  top: 17px;
+  left: 5%;
+  transition-property: width, height, top, left;
+  transition-duration: 0.2s;
+  transition-timing-function: ease;
+}
+.ui-dropdownmenu:active::before {
+  content: "";
+  opacity: 1;
+  width: 94%;
+  height: 40px;
+  background-color: var(--ripple-color);
+  position: absolute;
+  top: 10px;
+  left: 3%;
+}
+.ui-dropdownmenu .ui-dropdownmenu-placeholder {
+  box-sizing: border-box;
+  text-align: left;
+  width: 100%;
+  display: inline-block;
+  vertical-align: middle;
+  position: relative;
+  height: 100%;
+  line-height: 60px;
+  white-space: nowrap;
+  padding: 0 26px 0 16px;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  font-size: 17px;
+  text-indent: 5px;
+  background-color: W021L1;
+}
+.ui-dropdownmenu .ui-dropdownmenu-placeholder::after {
+  content: "";
+  position: absolute;
+  width: calc(100% -  32px);
+  height: 1px;
+  bottom: 9px;
+  right: 16px;
+  background-color: F057;
+}
+.ui-dropdownmenu select {
+  width: 100%;
+  display: none;
+}
+.ui-dropdownmenu.ui-focus {
+  background-color: var(--ripple-color);
+}
+.ui-dropdownmenu-inline {
+  width: auto;
+  display: inline-block;
+}
+.ui-dropdownmenu-disabled {
+  opacity: 1;
+}
+.ui-dropdownmenu-disabled .ui-dropdownmenu-placeholder {
+  color: var(--dropdown-menu-options-color-dim);
+}
+.ui-dropdownmenu-force-display {
+  display: block !important;
+}
+.ui-dropdownmenu-native select {
+  display: block;
+  top: 0;
+  left: 0;
+  position: absolute;
+  height: 100%;
+  outline: 0;
+  opacity: 0;
+  border: 0;
+  margin: 0;
+}
+.ui-dropdownmenu-overlay-hidden {
+  display: none;
+}
+@-webkit-keyframes open-to-bottom {
+  from {
+    opacity: .5;
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+  to {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes open-to-top {
+  from {
+    opacity: .5;
+    -webkit-transform: translate3d(0, 100%, 0);
+    -ms-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+  to {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes close-to-bottom {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, 100%, 0);
+    -ms-transform: translate3d(0, 100%, 0);
+    transform: translate3d(0, 100%, 0);
+  }
+}
+@-webkit-keyframes close-to-top {
+  from {
+    opacity: 1;
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    opacity: 0;
+    -webkit-transform: translate3d(0, -100%, 0);
+    -ms-transform: translate3d(0, -100%, 0);
+    transform: translate3d(0, -100%, 0);
+  }
+}
+.ui-dropdownmenu-options-wrapper {
+  position: absolute;
+  visibility: hidden;
+  top: -5000px;
+  overflow: hidden;
+  z-index: 1201;
+  min-width: 168px;
+  max-width: 100vw;
+  padding: 3px;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-vertical-margins {
+  margin-top: 3px;
+  margin-bottom: 3px;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-active {
+  visibility: visible;
+  overflow-y: auto;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-opening.ui-dropdownmenu-options-top .ui-dropdownmenu-options {
+  -webkit-animation: open-to-top 300ms;
+  animation: open-to-top 300ms;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-opening.ui-dropdownmenu-options-bottom .ui-dropdownmenu-options {
+  -webkit-animation: open-to-bottom 300ms;
+  animation: open-to-bottom 300ms;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-closing.ui-dropdownmenu-options-top .ui-dropdownmenu-options {
+  -webkit-animation: close-to-bottom 300ms;
+  animation: close-to-bottom 300ms;
+}
+.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-closing.ui-dropdownmenu-options-bottom .ui-dropdownmenu-options {
+  -webkit-animation: close-to-top 300ms;
+  animation: close-to-top 300ms;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options {
+  box-sizing: border-box;
+  list-style: none;
+  padding: 0;
+  margin: 0;
+  max-height: calc(100vh -  6px);
+  overflow-y: auto;
+  background-color: var(--dropdown-menu-options-background);
+  border-radius: 26px;
+  box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.35);
+  border: var(--dropdown-menu-options-border);
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options:focus {
+  outline: none;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-disabled {
+  color: var(--dropdown-menu-options-color-dim);
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-selected {
+  color: var(--primary-dark-color);
+  font-family: Roboto-Medium;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-selected::after {
+  width: 20px;
+  height: 20px;
+  margin-left: 16px;
+  margin-right: 24px;
+  content: '';
+  position: absolute;
+  -webkit-mask-image: url('images/1_App_bar/tw_ic_ab_back_mtrl.svg');
+          mask-image: url('images/1_App_bar/tw_ic_ab_back_mtrl.svg');
+  -webkit-mask-size: 100%, 0;
+          mask-size: 100%, 0;
+  -webkit-mask-position: center;
+          mask-position: center;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  right: 0;
+  -webkit-transform: translateY(-50%);
+      -ms-transform: translateY(-50%);
+          transform: translateY(-50%);
+  top: 50%;
+  background-color: var(--primary-dark-color);
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li {
+  padding: 15px 60px 15px 24px;
+  font-size: 17px;
+  font-family: Roboto-Regular;
+  display: block;
+  position: relative;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  color: var(--dropdown-menu-options-color);
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li.ui-dropdown-two-lines {
+  max-height: 2em;
+  line-height: 1.4em;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:not(.ui-dropdown-two-lines) {
+  white-space: nowrap;
+  height: 20px;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:focus,
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:active {
+  outline: none;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li::before {
+  content: "";
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: var(--ripple-color);
+  opacity: 0;
+}
+.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:active::before {
+  opacity: 1;
+}
+.ui-dropdownmenu-active::-webkit-scrollbar {
+  display: none;
+}
+.ui-listview li.ui-li-static.ui-li-has-dropdownmenu {
+  padding: 0;
+}
+.ui-listview li.ui-li-static.ui-li-has-dropdownmenu .ui-dropdownmenu-placeholder {
+  line-height: 60px;
+}
+.ui-li-static.ui-li-has-dropdownmenu {
+  height: 60px;
+}
+.ui-appbar .ui-dropdownmenu-placeholder {
+  line-height: 56px;
+}
+.ui-appbar-expanded .ui-dropdownmenu-placeholder {
+  line-height: 59px;
+}
+.ui-panel-changer {
+  position: relative;
+  display: block;
+  width: 100%;
+  left: 0;
+}
+.ui-panel {
+  position: absolute;
+  height: 100%;
+  width: 100%;
+}
+.ui-panel.ui-panel-active {
+  display: block;
+}
+.ui-panel.slide-in,
+.ui-panel.slide-out,
+.ui-panel.slide-reverse-out,
+.ui-panel.slide-reverse-in {
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
+  -webkit-animation-duration: 400ms;
+  animation-duration: 400ms;
+}
+.ui-panel.pre-in {
+  z-index: 100;
+}
+.ui-panel.slide-out {
+  -webkit-animation-name: panelslideouttoleft;
+  animation-name: panelslideouttoleft;
+}
+.ui-panel.slide-in {
+  -webkit-animation-name: panelslideinfromright;
+  animation-name: panelslideinfromright;
+}
+.ui-panel.slide-reverse-out {
+  -webkit-animation-name: panelslideouttoright;
+  animation-name: panelslideouttoright;
+}
+.ui-panel.slide-reverse-in {
+  -webkit-animation-name: panelslideinfromleft;
+  animation-name: panelslideinfromleft;
+}
+.ui-panel .ui-content {
+  height: 100%;
+}
+@-webkit-keyframes panelslideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+@keyframes panelslideouttoleft {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+}
+@-webkit-keyframes panelslideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes panelslideinfromright {
+  from {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@-webkit-keyframes panelslideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@keyframes panelslideouttoright {
+  from {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(100%, 0, 0);
+    -ms-transform: translate3d(100%, 0, 0);
+    transform: translate3d(100%, 0, 0);
+  }
+}
+@-webkit-keyframes panelslideinfromleft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+@keyframes panelslideinfromleft {
+  from {
+    -webkit-transform: translate3d(-100%, 0, 0);
+    -ms-transform: translate3d(-100%, 0, 0);
+    transform: translate3d(-100%, 0, 0);
+  }
+  to {
+    -webkit-transform: translate3d(0, 0, 0);
+    -ms-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+  }
+}
+.ui-navigation {
+  -webkit-order: 2;
+  -moz-order: 2;
+  -ms-order: 2;
+  -o-order: 2;
+  -ms-flex-order: 2;
+      order: 2;
+  height: 35px;
+  box-sizing: border-box;
+  background-color: var(--background-color);
+  border-top: 1px solid var(--color-white);
+  white-space: nowrap;
+  overflow-x: scroll;
+  overflow-y: hidden;
+}
+.ui-navigation::-webkit-scrollbar {
+  display: none;
+}
+.ui-navigation .ui-navigation-container {
+  margin: 0;
+  padding: 0;
+  display: inline-block;
+  list-style-type: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item {
+  position: relative;
+  height: 34px;
+  line-height: 34px;
+  vertical-align: top;
+  overflow: hidden;
+  display: inline-block;
+  color: var(--text-color);
+  font-size: 16px;
+  background-color: transparent;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item:first-child {
+  margin-left: 9px;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item:first-child::before {
+  content: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item .ui-arrow {
+  float: left;
+  height: 34px;
+  width: 30px;
+  color: var(--text-color);
+  background-color: var(--color-white);
+  -webkit-mask-image: url("images/core_navigation_bar_icon_arrow.png");
+  -webkit-mask-size: 100% 100%;
+  margin: 0 -9px 0;
+  opacity: .6;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item .ui-text {
+  display: block;
+  position: relative;
+  float: left;
+  height: 21.5px;
+  color: var(--text-color);
+  padding: 3px 7px 4.5px;
+  line-height: 21.5px;
+  margin-top: 2.5px;
+  text-decoration: none;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  opacity: .6;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item .ui-text.ui-focus {
+  background-color: rgba(50, 150, 166, 0.4);
+  outline: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item:last-child {
+  margin-right: 9px;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-active-animation .ui-arrow {
+  -webkit-animation: navigation_active_show_animation_arrow linear 133ms;
+  animation: navigation_active_show_animation_arrow linear 133ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-active-animation .ui-text {
+  -webkit-animation: navigation_active_show_animation_text linear 166ms;
+  animation: navigation_active_show_animation_text linear 166ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back .ui-arrow {
+  -webkit-animation: none;
+  animation: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back .ui-text {
+  -webkit-animation: navigation_active_back_animation_text linear 184ms;
+  animation: navigation_active_back_animation_text linear 184ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-hide .ui-arrow {
+  -webkit-animation: navigation_active_hide_animation_text linear 150ms;
+  animation: navigation_active_hide_animation_text linear 150ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-hide .ui-text {
+  -webkit-animation: navigation_active_hide_animation_text linear 184ms;
+  animation: navigation_active_hide_animation_text linear 184ms;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigation-active .ui-arrow {
+  opacity: .6;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigation-active .ui-text {
+  color: var(--ripple-color);
+  opacity: 1;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back-hide .ui-arrow {
+  -webkit-animation: none;
+  animation: none;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back-hide .ui-text {
+  -webkit-animation: navigation_active_back_hide_animation_text linear 184ms;
+  animation: navigation_active_back_hide_animation_text linear 184ms;
+  opacity: 1;
+}
+.ui-navigation .ui-navigation-container .ui-navigation-item.ui-btn-active .ui-text::before {
+  content: "";
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  left: 50%;
+  top: 50%;
+  background-color: var(--ripple-color);
+  opacity: 0;
+  color: var(--ripple-color);
+  -webkit-animation: navigation_press_animation linear 500ms;
+  animation: navigation_press_animation linear 500ms;
+}
+@-webkit-keyframes navigation_active_show_animation_text {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@keyframes navigation_active_show_animation_text {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes navigation_active_back_animation_text {
+  0% {
+    opacity: .6;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@keyframes navigation_active_back_animation_text {
+  0% {
+    opacity: .6;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes navigation_active_back_hide_animation_text {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: .6;
+  }
+}
+@keyframes navigation_active_back_hide_animation_text {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: .6;
+  }
+}
+@-webkit-keyframes navigation_active_show_animation_arrow {
+  0% {
+    opacity: 0;
+  }
+  20% {
+    opacity: 0;
+  }
+  100% {
+    opacity: .6;
+  }
+}
+@keyframes navigation_active_show_animation_arrow {
+  0% {
+    opacity: 0;
+  }
+  20% {
+    opacity: 0;
+  }
+  100% {
+    opacity: .6;
+  }
+}
+@-webkit-keyframes navigation_active_hide_animation_text {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@keyframes navigation_active_hide_animation_text {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@-webkit-keyframes navigation_press_animation {
+  0% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(0.7);
+    -ms-transform: translate(-50%, -50%) scale(0.7);
+    transform: translate(-50%, -50%) scale(0.7);
+  }
+  5% {
+    opacity: .3;
+  }
+  100% {
+    opacity: .3;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+}
+@keyframes navigation_press_animation {
+  0% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(0.7);
+    -ms-transform: translate(-50%, -50%) scale(0.7);
+    transform: translate(-50%, -50%) scale(0.7);
+  }
+  5% {
+    opacity: .3;
+  }
+  100% {
+    opacity: .3;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+}
+@-webkit-keyframes navigation_pressup_animation {
+  0% {
+    opacity: .3;
+  }
+  100% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+}
+@keyframes navigation_pressup_animation {
+  0% {
+    opacity: .3;
+  }
+  100% {
+    opacity: 0;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+}
+.ui-tabs {
+  position: relative;
+  height: 100%;
+  overflow: hidden;
+  border-bottom-left-radius: 26px;
+  border-bottom-right-radius: 26px;
+}
+.ui-tabs .ui-listview {
+  overflow: hidden;
+  min-height: 100%;
+  min-width: 100%;
+}
+.ui-section-changer {
+  height: 100%;
+  position: relative;
+  overflow: hidden;
+  display: block;
+}
+.ui-section-changer section {
+  overflow: auto;
+}
+.ui-indexscrollbar {
+  display: block;
+  position: absolute;
+  right: 0;
+  top: 0;
+  width: 20px;
+  height: 100%;
+  padding-left: 1px;
+  background-color: var(--control-background);
+  z-index: 1000;
+  overflow: visible;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  cursor: pointer;
+  box-sizing: border-box;
+}
+.ui-indexscrollbar::before {
+  width: 20px;
+  display: block;
+  position: absolute;
+  right: 20px;
+  height: 100%;
+  content: " ";
+  background-color: transparent;
+}
+.ui-indexscrollbar ul {
+  list-style-type: none;
+  margin: 0;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  left: 0;
+  visibility: visible;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+  -webkit-align-items: stretch;
+  -moz-align-items: stretch;
+  -ms-align-items: stretch;
+  -o-align-items: stretch;
+  -ms-flex-align: stretch;
+      align-items: stretch;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  padding: 0;
+  box-sizing: border-box;
+}
+.ui-indexscrollbar ul li {
+  cursor: pointer;
+  color: var(--text-color);
+  display: block;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  text-align: center;
+  font-size: 12px;
+  font-weight: bold;
+  border-bottom: 1px solid var(--primary-color);
+  border-left: 1px solid var(--border-surface);
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+  max-height: 20px;
+  min-height: 20px;
+}
+.ui-indexscrollbar ul li a {
+  text-decoration: none;
+  width: 18px;
+  height: 19px;
+  color: inherit;
+  border: none;
+  outline: none;
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+}
+.ui-indexscrollbar ul li a:focus {
+  background-color: var(--ripple-color);
+}
+.ui-indexscrollbar ul li.ui-state-selected {
+  border-left: 2px solid var(--primary-color);
+  position: relative;
+  width: 18px;
+}
+.ui-indexscrollbar ul li.ui-state-selected::before {
+  content: "";
+  position: absolute;
+  height: 100%;
+  width: 17px;
+  left: -1px;
+  top: -1px;
+  border: 1px solid var(--border-surface);
+  border-left: none;
+}
+.ui-indexscrollbar ul::before,
+.ui-indexscrollbar ul::after {
+  content: "";
+  width: 20px;
+  border-left: 1px solid var(--border-surface);
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+  pointer-events: none;
+  -webkit-flex-basis: auto;
+      -ms-flex-preferred-size: auto;
+          flex-basis: auto;
+}
+.ui-indexscrollbar ul.ui-indexscrollbar-supplementary {
+  position: relative;
+  height: auto;
+  top: 0;
+  right: -20px;
+  width: 100%;
+}
+.ui-indexscrollbar .ui-indexscrollbar-margin {
+  width: 20px;
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  border-left: 1px solid var(--border-surface);
+}
+.ui-indexscrollbar + .ui-listview li {
+  padding-right: 20px;
+}
+.ui-indexscrollbar ul li:first-child {
+  padding-top: 21px;
+  position: relative;
+}
+.ui-indexscrollbar ul li:first-child::before {
+  content: "";
+  height: 20px;
+  width: 20px;
+  position: absolute;
+  top: 0;
+  left: 0;
+  background-color: var(--text-color);
+  -webkit-mask-image: url("../default/images/controls/core_floating_icon_search.png");
+          mask-image: url("../default/images/controls/core_floating_icon_search.png");
+  -webkit-mask-size: 80%;
+          mask-size: 80%;
+  -webkit-mask-position: center center;
+          mask-position: center center;
+}
+.ui-indexscrollbar ul li:first-child::after {
+  content: "";
+  height: 1px;
+  width: 20px;
+  position: absolute;
+  top: 20px;
+  left: 0;
+  background-color: var(--primary-color);
+}
+.ui-indexscrollbar ul li:last-child {
+  border-bottom-color: transparent;
+}
+.ui-indexscrollbar-indicator {
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 999;
+  display: none;
+}
+.ui-indexscrollbar-indicator > span {
+  width: 84px;
+  line-height: 84px;
+  position: absolute;
+  display: block;
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+  font-size: 56px;
+  border-radius: 50%;
+  text-align: center;
+  box-sizing: border-box;
+  background-color: var(--control-background);
+  color: var(--text-color);
+}
+.ui-icon-add::after {
+  -webkit-mask-image: url("images/2_Buttons/tw_ic_ab_add_mtrl.svg");
+          mask-image: url("images/2_Buttons/tw_ic_ab_add_mtrl.svg");
+}
+.ui-icon-delete::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_bb_delete_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_bb_delete_mtrl.svg");
+}
+.ui-icon-cancel::after {
+  -webkit-mask-image: url("images/controls/core_button_cancel.png");
+          mask-image: url("images/controls/core_button_cancel.png");
+}
+.ui-icon-reorder::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_list_icon_reorder.svg");
+          mask-image: url("images/3_Controllers/tw_list_icon_reorder.svg");
+}
+.ui-icon-pause::after {
+  -webkit-mask-image: url("images/controls/00_button_pause.png");
+          mask-image: url("images/controls/00_button_pause.png");
+}
+.ui-icon-share::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_bb_share_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_bb_share_mtrl.svg");
+}
+.ui-icon-check::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_ab_back_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_ab_back_mtrl.svg");
+}
+.ui-icon-move::after {
+  -webkit-mask-image: url("images/1_App_bar/tw_ic_bb_move_mtrl.svg");
+          mask-image: url("images/1_App_bar/tw_ic_bb_move_mtrl.svg");
+}
+.ui-icon-plus::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_list_icon_add_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_list_icon_add_mtrl.svg");
+}
+.ui-icon-minus::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_list_icon_delete_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_list_icon_delete_mtrl.svg");
+}
+.ui-icon-up::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_expander_close_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_expander_close_mtrl.svg");
+}
+.ui-icon-down::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+}
+.ui-icon-left::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+  -webkit-transform: translate(-50%, -50%) rotateZ(90deg);
+      -ms-transform: translate(-50%, -50%) rotate(90deg);
+          transform: translate(-50%, -50%) rotateZ(90deg);
+}
+.ui-icon-right::after {
+  -webkit-mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+          mask-image: url("images/3_Controllers/tw_expander_open_mtrl.svg");
+}
+.ui-icon-next::after {
+  -webkit-mask-image: url(images/3_Controllers/tw_expander_close_mtrl.svg);
+          mask-image: url(images/3_Controllers/tw_expander_close_mtrl.svg);
+}
+.ui-btn.ui-icon-next::after,
+.ui-btn.ui-icon-right::after {
+  -webkit-transform: translate(-50%, -50%) rotateZ(90deg);
+      -ms-transform: translate(-50%, -50%) rotate(90deg);
+          transform: translate(-50%, -50%) rotateZ(90deg);
+}
+.ui-btn.ui-icon-left::after {
+  -webkit-transform: translate(-50%, -50%) rotateZ(-90deg);
+      -ms-transform: translate(-50%, -50%) rotate(-90deg);
+          transform: translate(-50%, -50%) rotateZ(-90deg);
+}
+:root {
+  --button-fab-radius: 50%;
+  --button-fab-icon-color: var(--color-white);
+  --button-fab-right: 24px;
+  --button-fab-bottom: 24px;
+  --button-fab-width: 56px;
+  --button-fab-height: 56px;
+  --button-fab-icon-width: 24px;
+  --button-fab-icon-height: 24px;
+}
+tau-button {
+  -webkit-align-items: flex-start;
+      -ms-flex-align: start;
+          align-items: flex-start;
+  background-color: #dddddd;
+  border-bottom-color: #dddddd;
+  border-bottom-style: outset;
+  border-bottom-width: 2px;
+  border-image-outset: 0;
+  border-image-repeat: stretch;
+  border-image-slice: 100%;
+  border-image-source: none;
+  border-image-width: 1;
+  border-left-color: #dddddd;
+  border-left-style: outset;
+  border-left-width: 2px;
+  border-right-color: #dddddd;
+  border-right-style: outset;
+  border-right-width: 2px;
+  border-top-color: #dddddd;
+  border-top-style: outset;
+  border-top-width: 2px;
+  box-sizing: border-box;
+  color: #000000;
+  cursor: default;
+  display: inline-block;
+  font-family: 'Arial', 'MS Trebuchet', sans-serif;
+  font-size: 13.3333330154419px;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: normal;
+  letter-spacing: normal;
+  line-height: normal;
+  margin-bottom: 0;
+  margin-left: 0;
+  margin-right: 0;
+  margin-top: 0;
+  padding-bottom: 1px;
+  padding-left: 6px;
+  padding-right: 6px;
+  padding-top: 1px;
+  text-align: center;
+  text-indent: 0;
+  text-rendering: auto;
+  text-shadow: none;
+  text-transform: none;
+  word-spacing: 0;
+  -webkit-writing-mode: horizontal-tb;
+      -ms-writing-mode: lr-tb;
+          writing-mode: horizontal-tb;
+}
+@-webkit-keyframes btn_pressup_animation {
+  0% {
+    opacity: 1;
+  }
+  33% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@keyframes btn_pressup_animation {
+  0% {
+    opacity: 1;
+  }
+  33% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@-webkit-keyframes btn_press_animation_nobg {
+  0% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+  100% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1.425);
+    -ms-transform: translate(-50%, -50%) scale(1.425);
+    transform: translate(-50%, -50%) scale(1.425);
+  }
+}
+@keyframes btn_press_animation_nobg {
+  0% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1);
+    -ms-transform: translate(-50%, -50%) scale(1);
+    transform: translate(-50%, -50%) scale(1);
+  }
+  100% {
+    opacity: 1;
+    -webkit-transform: translate(-50%, -50%) scale(1.425);
+    -ms-transform: translate(-50%, -50%) scale(1.425);
+    transform: translate(-50%, -50%) scale(1.425);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_opacity_in {
+  0% {
+    background-color: transparent;
+  }
+  100% {
+    background-color: var(--ripple-button-flat-color);
+  }
+}
+@keyframes btn_press_animation_flat_opacity_in {
+  0% {
+    background-color: transparent;
+  }
+  100% {
+    background-color: var(--ripple-button-flat-color);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_opacity_out {
+  0% {
+    background-color: var(--ripple-button-flat-color);
+  }
+  100% {
+    background-color: transparent;
+  }
+}
+@keyframes btn_press_animation_flat_opacity_out {
+  0% {
+    background-color: var(--ripple-button-flat-color);
+  }
+  100% {
+    background-color: transparent;
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_opacity_in {
+  0% {
+    background-color: var(--button-background-flat);
+  }
+  100% {
+    background-color: var(--ripple-button-flat-color);
+  }
+}
+@keyframes btn_press_animation_flat_icon_opacity_in {
+  0% {
+    background-color: var(--button-background-flat);
+  }
+  100% {
+    background-color: var(--ripple-button-flat-color);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_opacity_out {
+  0% {
+    background-color: var(--ripple-button-flat-color);
+  }
+  100% {
+    background-color: var(--button-background-flat);
+  }
+}
+@keyframes btn_press_animation_flat_icon_opacity_out {
+  0% {
+    background-color: var(--ripple-button-flat-color);
+  }
+  100% {
+    background-color: var(--button-background-flat);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_scale {
+  0% {
+    -webkit-transform: translate(-50%, -50%) scale(0.95);
+            transform: translate(-50%, -50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translate(-50%, -50%) scale(1);
+            transform: translate(-50%, -50%) scale(1);
+  }
+}
+@keyframes btn_press_animation_flat_scale {
+  0% {
+    -webkit-transform: translate(-50%, -50%) scale(0.95);
+            transform: translate(-50%, -50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translate(-50%, -50%) scale(1);
+            transform: translate(-50%, -50%) scale(1);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_scale {
+  0% {
+    -webkit-transform: translate(-50%, -50%) scale(0.95);
+            transform: translate(-50%, -50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translate(-50%, -50%) scale(1);
+            transform: translate(-50%, -50%) scale(1);
+  }
+}
+@keyframes btn_press_animation_flat_icon_scale {
+  0% {
+    -webkit-transform: translate(-50%, -50%) scale(0.95);
+            transform: translate(-50%, -50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translate(-50%, -50%) scale(1);
+            transform: translate(-50%, -50%) scale(1);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_scale_left {
+  0% {
+    -webkit-transform: translateY(-50%) scale(0.95);
+            transform: translateY(-50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translateY(-50%) scale(1);
+            transform: translateY(-50%) scale(1);
+  }
+}
+@keyframes btn_press_animation_flat_icon_scale_left {
+  0% {
+    -webkit-transform: translateY(-50%) scale(0.95);
+            transform: translateY(-50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translateY(-50%) scale(1);
+            transform: translateY(-50%) scale(1);
+  }
+}
+@-webkit-keyframes btn_press_animation_flat_icon_scale_top {
+  0% {
+    -webkit-transform: translateX(-50%) scale(0.95);
+            transform: translateX(-50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translateX(-50%) scale(1);
+            transform: translateX(-50%) scale(1);
+  }
+}
+@keyframes btn_press_animation_flat_icon_scale_top {
+  0% {
+    -webkit-transform: translateX(-50%) scale(0.95);
+            transform: translateX(-50%) scale(0.95);
+  }
+  100% {
+    -webkit-transform: translateX(-50%) scale(1);
+            transform: translateX(-50%) scale(1);
+  }
+}
+@-webkit-keyframes animation_opacity_in {
+  0% {
+    opacity: 0;
+  }
+  10% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@keyframes animation_opacity_in {
+  0% {
+    opacity: 0;
+  }
+  10% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@-webkit-keyframes animation_opacity_out {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+@keyframes animation_opacity_out {
+  0% {
+    opacity: 1;
+  }
+  100% {
+    opacity: 0;
+  }
+}
+button.ui-btn,
+input[type="button"].ui-btn {
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  width: 100%;
+  border: none;
+  outline: none;
+}
+a.ui-btn {
+  text-decoration: none;
+  width: 100%;
+}
+.ui-btn {
+  position: relative;
+  padding: 0 16px;
+  min-height: 36px;
+  vertical-align: middle;
+  text-overflow: ellipsis;
+  text-align: center;
+  color: var(--primary-color);
+  font-size: var(--button-text-font-size);
+  white-space: nowrap;
+  cursor: pointer;
+  background-color: var(--button-background);
+  box-sizing: border-box;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  z-index: 0;
+  border-radius: 18px;
+  font-family: Roboto-Medium;
+}
+.ui-btn::before {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  width: 100%;
+  height: 100%;
+  opacity: 0;
+  content: "";
+  border-width: 0;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+}
+.ui-btn::after {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  -webkit-mask-size: 100% 100%;
+  -moz-mask-size: 100% 100%;
+  -ms-mask-size: 100% 100%;
+  -o-mask-size: 100% 100%;
+  mask-size: 100% 100%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+  -webkit-mask-repeat: no-repeat;
+  -moz-mask-repeat: no-repeat;
+  -ms-mask-repeat: no-repeat;
+  -o-mask-repeat: no-repeat;
+  mask-repeat: no-repeat;
+  -webkit-mask-position: center;
+  -moz-mask-position: center;
+  -ms-mask-position: center;
+  -o-mask-position: center;
+  mask-position: center;
+  -webkit-mask-size: 100%;
+  -moz-mask-size: 100%;
+  -ms-mask-size: 100%;
+  -o-mask-size: 100%;
+  mask-size: 100%;
+  content: "";
+}
+.ui-btn:focus {
+  outline: none;
+}
+.ui-btn:not(.ui-btn-nobg)::before {
+  z-index: -1;
+  border-radius: 26px;
+  background-color: var(--ripple-color);
+  box-sizing: border-box;
+}
+.ui-btn:not(.ui-btn-nobg).ui-btn-active::before {
+  opacity: 1;
+  -webkit-animation: btn_press_animation_flat_opacity_in linear 100ms, btn_press_animation_flat_opacity_out linear 400ms 100ms, btn_press_animation_flat_scale cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+          animation: btn_press_animation_flat_opacity_in linear 100ms, btn_press_animation_flat_opacity_out linear 400ms 100ms, btn_press_animation_flat_scale cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+}
+.ui-btn.ui-btn-focus {
+  outline: 2px solid var(--primary-color);
+}
+.ui-btn.ui-btn-nobg {
+  background-color: transparent;
+  color: var(--primary-color);
+}
+.ui-btn.ui-btn-nobg::before {
+  background-color: var(--ripple-color);
+  opacity: 0;
+  border-radius: 50%;
+  width: 40px;
+  height: 40px;
+  -webkit-transform: translate(-50%, -50%) scale(1);
+  -ms-transform: translate(-50%, -50%) scale(1);
+  transform: translate(-50%, -50%) scale(1);
+}
+.ui-btn.ui-btn-nobg.ui-btn-active::before {
+  -webkit-animation: btn_press_animation_nobg linear 315ms;
+          animation: btn_press_animation_nobg linear 315ms;
+  opacity: 1;
+  -webkit-transform: translate(-50%, -50%) scale(1.425);
+  -ms-transform: translate(-50%, -50%) scale(1.425);
+  transform: translate(-50%, -50%) scale(1.425);
+}
+.ui-btn.ui-btn-nobg.ui-btn-active.ui-btn-inactive::before {
+  opacity: 0;
+  -webkit-transform: translate(-50%, -50%) scale(1.425);
+  -ms-transform: translate(-50%, -50%) scale(1.425);
+  transform: translate(-50%, -50%) scale(1.425);
+}
+.ui-btn.ui-btn-nobg.ui-btn-active.ui-btn-inactive::after {
+  -webkit-animation: btn_pressup_animation 300ms linear;
+  animation: btn_pressup_animation 300ms linear;
+  opacity: 0;
+}
+.ui-btn.ui-btn-nobg.ui-btn-icon::after {
+  background-color: var(--text-color);
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-position: center;
+          mask-position: center;
+}
+.ui-btn.ui-btn-nobg.ui-btn-icon.ui-btn-active::after {
+  background-color: var(--text-color);
+}
+.ui-btn.ui-btn-nobg.ui-btn-icon.ui-icon-delete::after {
+  background-color: F060L3;
+  transition: background-color 15ms;
+}
+.ui-btn.ui-btn-nobg.ui-btn-icon.ui-icon-delete.ui-btn-active::after {
+  background-color: F060L3P;
+  transition: background-color 300ms;
+}
+.ui-btn.ui-btn-icon.ui-state-disabled::after {
+  opacity: 0.4;
+}
+.ui-btn.ui-btn-icon.ui-btn-circle {
+  width: 49px;
+  height: 49px;
+}
+.ui-btn.ui-btn-icon.ui-btn-circle::after {
+  background-color: var(--text-color);
+}
+.ui-btn.ui-btn-icon.ui-btn-nobg {
+  width: 40px;
+  height: 40px;
+  text-indent: -4999.5px;
+  padding: 10px 0;
+  border-radius: 0;
+}
+.ui-btn.ui-btn-icon.ui-btn-nobg.ui-inline {
+  width: 40px;
+}
+.ui-btn.ui-btn-icon.ui-btn-nobg::after {
+  width: 25px;
+  height: 25px;
+}
+.ui-btn.ui-btn-icon.ui-color-add::after {
+  background-color: var(--btn-add-color);
+}
+.ui-btn.ui-btn-icon.ui-color-delete::after {
+  background-color: var(--btn-delete-color);
+}
+.ui-btn.ui-inline {
+  display: inline-block;
+  width: auto;
+}
+.ui-btn.ui-hidden {
+  display: none;
+}
+.ui-btn.ui-state-disabled {
+  pointer-events: none;
+  background-color: var(--button-background);
+  color: var(--button-text-color-disabled);
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-only {
+  text-indent: -4999.5px;
+  width: 104px;
+}
+.ui-btn.ui-btn-icon::after {
+  background-color: var(--button-icon-color);
+}
+.ui-btn.ui-btn-icon.ui-btn-active::after {
+  background-color: var(--text-color);
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-left {
+  padding-left: 65px;
+  padding-right: 30px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-left::after {
+  left: 29px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-right {
+  padding-left: 30px;
+  padding-right: 65px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-right::after {
+  right: 29px;
+  left: auto;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-left::after,
+.ui-btn.ui-btn-icon.ui-btn-icon-right::after {
+  top: 50%;
+  -webkit-transform: translate(0, -50%);
+  -ms-transform: translate(0, -50%);
+  transform: translate(0, -50%);
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-top {
+  padding-top: 65px;
+  padding-bottom: 40px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-top::after {
+  top: 28px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-bottom {
+  padding-top: 40px;
+  padding-bottom: 65px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-bottom::after {
+  bottom: 28px;
+}
+.ui-btn.ui-btn-icon.ui-btn-icon-top::after,
+.ui-btn.ui-btn-icon.ui-btn-icon-bottom::after {
+  left: 50%;
+  -webkit-transform: translate(-50%, 0);
+  -ms-transform: translate(-50%, 0);
+  transform: translate(-50%, 0);
+}
+.ui-btn.ui-btn-text-light,
+.ui-btn.ui-btn-text-dark {
+  min-height: 24px;
+  height: 24px;
+  line-height: 17px;
+  min-width: 48px;
+  font-size: 16px;
+  padding: 4px 12px;
+}
+.ui-btn.ui-btn-text-light.ui-btn-active,
+.ui-btn.ui-btn-text-dark.ui-btn-active {
+  font-size: 16px;
+}
+.ui-btn.ui-btn-text-light {
+  background-color: W019;
+}
+.ui-btn.ui-btn-text-light.ui-btn-active {
+  background-color: W019P;
+}
+.ui-btn.ui-btn-text-dark {
+  background-color: W020;
+}
+.ui-btn.ui-btn-text-dark.ui-btn-active::before {
+  background-color: W020P;
+}
+.ui-btn.ui-btn-flat {
+  color: var(--primary-dark-color);
+}
+.ui-btn.ui-btn-flat::before {
+  border-radius: 22px;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon {
+  color: var(--text-color);
+  min-height: 32px;
+  max-width: 32px;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon::after {
+  width: 32px;
+  height: 32px;
+  border-radius: 28px;
+  -webkit-mask-size: 32px;
+          mask-size: 32px;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon::before {
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+      -ms-transform: translate(-50%, -50%);
+          transform: translate(-50%, -50%);
+  height: 32px;
+  width: 32px;
+  border-radius: 28px;
+  background-color: var(--button-background-flat);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top {
+  line-height: normal;
+  height: 60px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-flex-direction: column-reverse;
+      -ms-flex-direction: column-reverse;
+          flex-direction: column-reverse;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  padding: 0;
+  color: var(--appbar-subtitle-color);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top::after {
+  top: auto;
+  left: auto;
+  border-radius: 0;
+  width: 24px;
+  height: 24px;
+  -webkit-mask-size: 24px;
+          mask-size: 24px;
+  position: relative;
+  padding-bottom: 1px;
+  -webkit-transform: none;
+      -ms-transform: none;
+          transform: none;
+  background-color: var(--bottom-button-icon-color);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top::before {
+  top: auto;
+  left: auto;
+  border-radius: 12px;
+  -webkit-transform: none;
+      -ms-transform: none;
+          transform: none;
+  width: 100%;
+  height: 56px;
+  opacity: 0;
+  background-color: var(--ripple-color);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top.ui-btn-icon.ui-btn-active::before {
+  -webkit-animation: animation_opacity_in 200ms linear;
+          animation: animation_opacity_in 200ms linear;
+  -webkit-animation-fill-mode: both;
+          animation-fill-mode: both;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-top.ui-btn-icon.ui-btn-inactive::before {
+  -webkit-animation: animation_opacity_out 50ms linear;
+          animation: animation_opacity_out 50ms linear;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-left {
+  padding-top: 13px;
+  padding-right: 8px;
+  padding-bottom: 13px;
+  max-height: 56px;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-left::after {
+  left: 0;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-left::before {
+  left: 0;
+  -webkit-transform: translateY(-50%);
+      -ms-transform: translateY(-50%);
+          transform: translateY(-50%);
+}
+.ui-btn.ui-btn-flat.ui-btn-icon-left.ui-btn-icon.ui-btn-active::before {
+  -webkit-animation: btn_press_animation_flat_icon_opacity_in linear 100ms, btn_press_animation_flat_icon_opacity_out linear 400ms 100ms, btn_press_animation_flat_icon_scale_left cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+          animation: btn_press_animation_flat_icon_opacity_in linear 100ms, btn_press_animation_flat_icon_opacity_out linear 400ms 100ms, btn_press_animation_flat_icon_scale_left cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+}
+.ui-btn.ui-btn-flat.ui-btn-icon.ui-btn-active::before {
+  -webkit-animation: btn_press_animation_flat_icon_opacity_in linear 100ms, btn_press_animation_flat_icon_opacity_out linear 400ms 100ms, btn_press_animation_flat_icon_scale cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+          animation: btn_press_animation_flat_icon_opacity_in linear 100ms, btn_press_animation_flat_icon_opacity_out linear 400ms 100ms, btn_press_animation_flat_icon_scale cubic-bezier(0.33, 0, 0.2, 1) 350ms;
+}
+.ui-btn.ui-btn-flat.ui-btn-disabled {
+  opacity: 0.4;
+}
+.ui-btn.ui-btn-contained {
+  background-color: var(--button-background-contained);
+  color: var(--text-color);
+  font-size: var(--button-contained-text-font-size);
+  border-radius: 22px;
+  width: auto;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  padding-top: 12px;
+  padding-bottom: 12px;
+}
+.ui-btn.ui-btn-contained::before {
+  border-radius: 22px;
+}
+.ui-btn.ui-btn-contained:not(.ui-btn-inline) {
+  max-width: 75%;
+  width: 60%;
+  display: block;
+  margin: 0 auto;
+}
+.ui-btn.ui-btn-contained.ui-state-disabled {
+  opacity: 0.4;
+  color: var(--button-text-contained-dim-color);
+}
+.ui-btn.ui-btn-contained-colored {
+  background-color: var(--primary-dark-color);
+  font-size: 17px;
+  color: var(--color-white);
+}
+.ui-btn.ui-btn-contained-colored.ui-state-disabled {
+  color: var(--color-white);
+}
+.ui-btn.ui-btn-fab {
+  position: fixed;
+  right: var(--button-fab-right);
+  bottom: var(--button-fab-bottom);
+  width: var(--button-fab-width);
+  height: var(--button-fab-height);
+  background-color: var(--primary-color);
+  z-index: 1000;
+  border-radius: var(--button-fab-radius);
+}
+.ui-btn.ui-btn-fab::after {
+  background-color: var(--button-fab-icon-color);
+  width: var(--button-fab-icon-width);
+  height: var(--button-fab-icon-height);
+}
+.ui-btn.ui-btn-fab.ui-btn-active.ui-btn-icon::after {
+  background-color: var(--button-fab-icon-color);
+}
+.ui-btn .ui-btn-content {
+  width: 90px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  margin: 0 auto;
+}
+.ui-btn .ui-btn-content :first-child {
+  font-size: 13px;
+  font-family: Roboto-Regular;
+  color: #949494;
+}
+.ui-btn .ui-btn-content :nth-child(2) {
+  font-size: 13px;
+  font-family: Roboto-Medium;
+  color: #404040;
+}
+@media all and (min-width: 673px) and (min-height: 411px) {
+  .ui-btn.ui-btn-contained:not(.ui-btn-inline):not(.ui-btn.ui-popup-toast-has-button) {
+    max-width: 60%;
+    min-width: 240px;
+  }
+}
+.ui-listview li.ui-li-has-btn {
+  box-sizing: border-box;
+}
+.ui-listview li .ui-btn.ui-btn-contained {
+  border-radius: 18px;
+  font-size: var(--button-contained-list-text-font-size);
+  padding-top: 8px;
+  padding-bottom: 8px;
+}
+.ui-listview .ui-btn-flat,
+.ui-listview .ui-btn-contained {
+  margin-right: 24px;
+  margin-left: 8px;
+}
+.ui-li-has-btn {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  height: 60px;
+}
+.ui-li-has-btn .ui-btn {
+  margin: -7px auto;
+  max-width: 248px;
+}
+.ui-li-has-btn .ui-btn ~ .ui-btn {
+  margin-left: 8px;
+}
+.ui-listview .ui-expandable,
+.ui-content-area .ui-expandable {
+  padding: 0 24px;
+  -webkit-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-listview .ui-expandable .ui-expandable-heading,
+.ui-content-area .ui-expandable .ui-expandable-heading {
+  color: var(--text-color);
+  font-size: 18px;
+  font-weight: normal;
+  padding-top: 15px;
+  padding-bottom: 16px;
+  line-height: 21px;
+  margin: 0;
+  position: relative;
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle {
+  position: relative;
+  display: block;
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle:focus,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle:focus {
+  outline: 0;
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle::after,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle::after {
+  content: "";
+  position: absolute;
+  right: -8px;
+  top: calc(50% -  16px);
+  -webkit-mask-image: url("images/6_Lists/tw_expander_close_mtrl.svg");
+          mask-image: url("images/6_Lists/tw_expander_close_mtrl.svg");
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  -webkit-mask-position: center;
+          mask-position: center;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  background-color: var(--expander-color);
+  width: 32px;
+  height: 32px;
+  transition: all 330ms ease;
+  -webkit-transform: rotate(0);
+      -ms-transform: rotate(0);
+          transform: rotate(0);
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-btn,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn {
+  width: 32px;
+  height: 32px;
+  min-height: auto;
+  position: absolute;
+  right: -8px;
+  top: calc(50% -  16px);
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-btn::before,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn::before {
+  width: 32px;
+  height: 32px;
+  display: none;
+}
+.ui-listview .ui-expandable .ui-expandable-heading .ui-btn::after,
+.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn::after {
+  width: 32px;
+  height: 32px;
+  -webkit-mask-size: 32px;
+          mask-size: 32px;
+  background-color: var(--expander-color);
+  transition: all 330ms ease;
+  -webkit-transform: translate(-50%, -50%) rotate(0);
+      -ms-transform: translate(-50%, -50%) rotate(0);
+          transform: translate(-50%, -50%) rotate(0);
+}
+.ui-listview .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-expandable-heading-toggle::after,
+.ui-content-area .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-expandable-heading-toggle::after {
+  -webkit-transform: rotate(180deg);
+      -ms-transform: rotate(180deg);
+          transform: rotate(180deg);
+}
+.ui-listview .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-btn::after,
+.ui-content-area .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-btn::after {
+  -webkit-transform: translate(-50%, -50%) rotate(180deg);
+      -ms-transform: translate(-50%, -50%) rotate(180deg);
+          transform: translate(-50%, -50%) rotate(180deg);
+}
+.ui-listview .ui-expandable .ui-expandable-content,
+.ui-content-area .ui-expandable .ui-expandable-content {
+  transition: all 330ms ease;
+  overflow: auto;
+}
+.ui-listview .ui-expandable .ui-expandable-content .ui-listview,
+.ui-content-area .ui-expandable .ui-expandable-content .ui-listview {
+  padding: 0;
+  margin-left: 18px;
+}
+.ui-listview .ui-expandable .ui-expandable-content .ui-listview li,
+.ui-content-area .ui-expandable .ui-expandable-content .ui-listview li {
+  color: var(--expandable-text-color);
+  padding-top: 15px;
+  padding-bottom: 16px;
+  line-height: 21px;
+  margin: 0;
+}
+.ui-listview .ui-expandable .ui-expandable-content-collapsed,
+.ui-content-area .ui-expandable .ui-expandable-content-collapsed {
+  overflow: hidden;
+  max-height: 0 !important;
+  display: none;
+  transition: all 330ms ease;
+}
+.ui-listview .ui-expandable.ui-state-disabled,
+.ui-content-area .ui-expandable.ui-state-disabled {
+  cursor: default !important;
+  pointer-events: none;
+  zoom: 1;
+}
+.ui-listview .ui-expandable.ui-state-disabled .ui-expandable-heading .ui-expandable-heading-toggle::after,
+.ui-content-area .ui-expandable.ui-state-disabled .ui-expandable-heading .ui-expandable-heading-toggle::after {
+  background-color: var(--control-background);
+}
+.ui-expandable-from ~ *:not(.ui-expandable-to) {
+  display: none;
+}
+.ui-listview .ui-expandable-from ~ *:not(.ui-expandable-to) {
+  display: none;
+}
+.ui-expandable-from.ui-expandable-expanded ~ *:not(.ui-expandable-to) {
+  display: inherit;
+}
+.ui-listview .ui-expandable-to ~ *:not(.ui-expandable-from) {
+  display: inherit;
+}
+.ui-expandable-to .ui-btn.ui-btn-flat,
+.ui-expandable-from .ui-btn.ui-btn-flat {
+  width: 32px;
+  height: 32px;
+  min-height: auto;
+  margin: auto;
+}
+.ui-expandable-to .ui-btn.ui-btn-flat::before,
+.ui-expandable-from .ui-btn.ui-btn-flat::before {
+  width: 32px;
+  height: 32px;
+}
+.ui-expandable-to .ui-btn.ui-btn-flat::after,
+.ui-expandable-from .ui-btn.ui-btn-flat::after {
+  width: 32px;
+  height: 32px;
+  -webkit-mask-size: 32px;
+          mask-size: 32px;
+  background-color: var(--expander-color);
+  transition: all 330ms ease;
+  -webkit-transform: translate(-50%, -50%) rotate(0);
+      -ms-transform: translate(-50%, -50%) rotate(0);
+          transform: translate(-50%, -50%) rotate(0);
+}
+.ui-expandable-from .ui-btn.ui-btn-flat {
+  position: absolute;
+  right: -6px;
+}
+.ui-expandable-from.ui-expandable-expanded ~ .ui-expandable-to .ui-btn.ui-btn-flat::after,
+.ui-expandable-from.ui-expandable-expanded .ui-btn.ui-btn-flat::after {
+  -webkit-transform: translate(-50%, -50%) rotate(180deg);
+      -ms-transform: translate(-50%, -50%) rotate(180deg);
+          transform: translate(-50%, -50%) rotate(180deg);
+}
+.ui-floatingactions {
+  position: fixed;
+  right: 0;
+  bottom: 21.5px;
+  height: 60px;
+  padding-left: 15px;
+  padding-right: 15px;
+  -webkit-transform: translate3d(12px, 0, 0);
+          transform: translate3d(12px, 0, 0);
+  -webkit-mask-box-image-repeat: repeat;
+  -moz-mask-box-image-repeat: repeat;
+  -ms-mask-box-image-repeat: repeat;
+  -o-mask-box-image-repeat: repeat;
+  mask-box-image-repeat: repeat;
+  -webkit-mask-box-image-width: auto;
+  -moz-mask-box-image-width: auto;
+  -ms-mask-box-image-width: auto;
+  -o-mask-box-image-width: auto;
+  mask-box-image-width: auto;
+  -webkit-mask-box-image-source: url('images/nine-patch/core_floating_button_bg.png');
+  -webkit-mask-box-image-slice: 60 64 60 64 fill;
+  -moz-mask-box-image-slice: 60 64 60 64 fill;
+  -ms-mask-box-image-slice: 60 64 60 64 fill;
+  -o-mask-box-image-slice: 60 64 60 64 fill;
+  mask-box-image-slice: 60 64 60 64 fill;
+  background-color: var(--primary-dark-color);
+  z-index: 1000;
+}
+.ui-floatingactions.ui-floatingactions-transitions {
+  transition-property: all;
+  transition-duration: 500ms;
+}
+.ui-floatingactions .ui-btn {
+  display: inline-block;
+  width: 60px;
+  height: 60px;
+  margin: 0;
+  background-color: transparent;
+  color: var(--primary-color);
+}
+.ui-floatingactions .ui-btn.ui-btn-icon {
+  width: 60px;
+}
+.ui-floatingactions .ui-btn::before {
+  background-color: var(--ripple-color);
+  opacity: 0;
+  border-radius: 50%;
+  width: 40px;
+  height: 40px;
+  -webkit-transform: translate(-50%, -50%) scale(1);
+  -ms-transform: translate(-50%, -50%) scale(1);
+  transform: translate(-50%, -50%) scale(1);
+}
+.ui-floatingactions .ui-btn.ui-btn-active::before {
+  -webkit-animation: btn_press_animation_nobg linear 315ms;
+          animation: btn_press_animation_nobg linear 315ms;
+  opacity: 1;
+  -webkit-transform: translate(-50%, -50%) scale(1.425);
+  -ms-transform: translate(-50%, -50%) scale(1.425);
+  transform: translate(-50%, -50%) scale(1.425);
+}
+.ui-floatingactions .ui-btn.ui-btn-active.ui-btn-inactive::before {
+  opacity: 0;
+  -webkit-transform: translate(-50%, -50%) scale(1.425);
+  -ms-transform: translate(-50%, -50%) scale(1.425);
+  transform: translate(-50%, -50%) scale(1.425);
+}
+.ui-floatingactions .ui-btn.ui-btn-active.ui-btn-inactive::after {
+  -webkit-animation: btn_pressup_animation 300ms linear;
+  animation: btn_pressup_animation 300ms linear;
+  opacity: 0;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon::after {
+  background-color: var(--text-color);
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-position: center;
+          mask-position: center;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-active::after {
+  background-color: var(--text-color);
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-icon-delete::after {
+  background-color: F060L3;
+  transition: background-color 15ms;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-icon-delete.ui-btn-active::after {
+  background-color: F060L3P;
+  transition: background-color 300ms;
+}
+.ui-floatingactions .ui-btn::before {
+  background-color: var(--ripple-color);
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left {
+  padding: 0;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after {
+  left: 50%;
+  top: 50%;
+  -webkit-transform: translate(-50%, -50%);
+      -ms-transform: translate(-50%, -50%);
+          transform: translate(-50%, -50%);
+  width: 40px;
+  height: 40px;
+  background-color: var(--color-white);
+  z-index: -100;
+}
+.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active ::after {
+  background-color: var(--ripple-color);
+}
+.ui-floatingactions .ui-btn.ui-icon-floating-add::after {
+  -webkit-mask-image: url("images/controls/core_floating_icon_add.png");
+          mask-image: url("images/controls/core_floating_icon_add.png");
+}
+.ui-floatingactions .ui-btn.ui-icon-floating-search::after {
+  -webkit-mask-image: url("images/controls/core_floating_icon_search.png");
+          mask-image: url("images/controls/core_floating_icon_search.png");
+}
+.ui-floatingactions .ui-btn-focus {
+  outline: none;
+  background-color: rgba(50, 150, 166, 0.4);
+}
+.ui-floatingactions .ui-btn ~ .ui-btn {
+  margin-left: -10px;
+}
+.ui-floatingactions.ui-floatingactions-expand-to-right {
+  padding-right: 30px;
+  right: -15px;
+}
+.ui-floatingactions.ui-floatingactions-expand-to-left {
+  padding-left: 30px;
+}
+.ui-floatingactions:focus {
+  outline: none;
+  background-color: rgba(78, 97, 173, 0.8);
+}
+.ui-floatingactions-reposition:focus {
+  background-color: var(--ripple-color);
+}
+.ui-content .ui-floatingactions,
+.ui-tabs .ui-floatingactions {
+  background-color: var(--primary-dark-color);
+}
+.ui-content .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after,
+.ui-tabs .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after {
+  background-color: var(--color-white);
+}
+.ui-content .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after,
+.ui-tabs .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after {
+  background-color: var(--ripple-color);
+}
+.ui-content .ui-floatingactions .ui-btn::before,
+.ui-tabs .ui-floatingactions .ui-btn::before {
+  background-color: var(--ripple-color);
+}
+.ui-content .ui-floatingactions:focus,
+.ui-tabs .ui-floatingactions:focus {
+  outline: none;
+  background-color: rgba(78, 97, 173, 0.8);
+}
+.ui-content .ui-floatingactions-reposition:focus,
+.ui-tabs .ui-floatingactions-reposition:focus {
+  background-color: var(--ripple-color);
+}
+.ui-indexscrollbar ~ .ui-floatingactions {
+  background-color: var(--primary-dark-color);
+}
+.ui-indexscrollbar ~ .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after {
+  background-color: var(--color-white);
+}
+.ui-indexscrollbar ~ .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after {
+  background-color: var(--ripple-color);
+}
+.ui-indexscrollbar ~ .ui-floatingactions .ui-btn::before {
+  background-color: var(--ripple-color);
+}
+.ui-listview ~ .ui-floatingactions .ui-btn.ui-btn-icon::after {
+  background-color: var(--color-white);
+}
+.ui-listview ~ .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-active::after {
+  background-color: var(--ripple-color);
+}
+.ui-page-floatingactions.ui-empty-state .ui-content {
+  box-sizing: border-box;
+  border-bottom: 127px solid transparent;
+}
+/*
+* Listview Style - divide single / multiline style for specific
+* If you want to see any style, search them using class name.
+*/
+/******************** custom elements styles *********************/
+tau-listview {
+  display: block;
+  list-style-type: disc;
+  -webkit-margin-before: 1em;
+  -webkit-margin-after: 1em;
+  -webkit-margin-start: 0;
+  -webkit-margin-end: 0;
+  -webkit-padding-start: 40px;
+}
+tau-expandable {
+  display: list-item;
+  text-align: -webkit-match-parent;
+}
+/******************** listview common style *********************/
+.ui-listview {
+  /**
+        * Listview cannot have style "overflow: hidden"
+        * because this widget has canvas which has to be visible outside the listview
+        */
+  margin: auto;
+  padding: 0;
+  list-style: none;
+  counter-reset: listnumbering;
+  position: relative;
+  -webkit-transform: translate3d(0, 0, 0);
+          transform: translate3d(0, 0, 0);
+  /*when set the list in drag mode before dragging*/
+  /*When dragging element*/
+}
+@media (min-width: 673px) and (min-height: 411px) {
+  .ui-listview {
+    width: 90%;
+  }
+}
+@media (min-width: 960px) {
+  .ui-listview {
+    width: 75%;
+  }
+}
+.ui-listview.ui-content-area {
+  margin-bottom: 16px;
+}
+.ui-listview.ui-content-area + button[data-style=fab] {
+  display: block;
+  min-height: 0;
+  margin-bottom: 108px;
+}
+.ui-listview li {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  position: relative;
+  box-sizing: content-box;
+  overflow: visible;
+  text-align: left;
+  font-size: 18px;
+}
+.ui-listview li[disabled] {
+  opacity: 0.4;
+}
+.ui-listview li.ui-li-subheader {
+  margin-left: 20px;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-listview li.ui-li-subheader:empty {
+  margin-top: 16px;
+}
+.ui-listview li.ui-li-subheader .ui-li-text-subheader {
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  color: var(--text-secondary-color);
+  font-family: Roboto-Medium;
+  font-size: 14px;
+  margin-left: 4px;
+  margin-right: 16px;
+  min-height: 36px;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-subheader::after {
+  content: "";
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  width: calc(100% - 20px);
+  border-bottom: 3px dotted var(--subheader-divider-color);
+  height: 0;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  margin-right: 20px;
+}
+.ui-listview li.ui-li-anchor {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  padding: 14px 0;
+  margin: 0 24px;
+}
+.ui-listview li.ui-li-has-text-input {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  padding: 18px 0 8px 0;
+  margin: 0 24px;
+}
+.ui-listview li .ui-li-checkbox-icon {
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li .ui-li-checkbox-icon img {
+  width: 40px;
+  height: 40px;
+  margin-right: 18px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-listview li .ui-li-icon {
+  width: 40px;
+  height: 40px;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  position: relative;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+          align-self: center;
+  margin: 0 12px;
+}
+.ui-listview li .ui-li-icon.ui-li-icon-small,
+.ui-listview li .ui-li-icon.ui-li-icon-small:after {
+  width: 25px !important;
+  height: 25px !important;
+}
+.ui-listview li .ui-li-icon::after,
+.ui-listview li .ui-li-icon * {
+  content: "";
+  position: absolute;
+  width: 40px;
+  height: 40px;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-position: center center;
+          mask-position: center center;
+}
+.ui-listview li .ui-li-text {
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  padding: 15px 0;
+  margin-right: 24px;
+}
+.ui-listview li .ui-li-text .ui-li-text-title {
+  font-size: 18px;
+  color: var(--text-color);
+  line-height: 21px;
+  vertical-align: middle;
+}
+.ui-listview li .ui-li-text .ui-li-text-title:only-child {
+  padding-bottom: 1px;
+}
+.ui-listview li .ui-li-text .ui-li-text-title + .ui-li-text-sub::before {
+  content: "";
+  display: block;
+  height: 4px;
+}
+.ui-listview li .ui-li-text .ui-li-text-sub {
+  font-size: 13px;
+  color: var(--text-secondary-color);
+  line-height: 15px;
+}
+.ui-listview li .ui-li-text .ui-li-text-sub + .ui-li-text-title::before {
+  content: "";
+  display: block;
+  height: 4px;
+}
+.ui-listview li .ui-li-text .ui-li-text-sub img {
+  width: 15px;
+  height: 15px;
+}
+.ui-listview li .ui-li-text .ui-li-text-value {
+  color: var(--primary-color);
+}
+.ui-listview li > .ui-li-text:first-child {
+  margin-left: 24px;
+}
+.ui-listview li.ui-li-divider::after {
+  content: "";
+  position: absolute;
+  width: calc(100% - 40px);
+  left: 20px;
+  bottom: -0.75px;
+  height: 0.75px;
+  background-color: var(--divider-color);
+  opacity: var(--divider-opacity);
+}
+.ui-listview li.ui-li-divider.ui-li-has-icon::after {
+  width: calc(100% - 84px);
+  left: 64px;
+}
+.ui-listview li.ui-li-divider.ui-li-has-checkbox::after,
+.ui-listview li.ui-li-divider.ui-li-has-radio::after {
+  width: calc(100% - 92px);
+  left: 68px;
+}
+.ui-listview li.ui-li-divider.ui-li-has-checkbox-icon::after {
+  left: 126px;
+}
+.ui-listview li + li.ui-li-divider {
+  margin-top: 0.75px;
+}
+.ui-listview li .ui-li-divider {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  margin-left: 12px;
+  margin-right: 9px;
+}
+.ui-listview li .ui-li-divider::after {
+  content: "";
+  position: absolute;
+  width: 0.5px;
+  height: 22px;
+  background-color: var(--on-off-switch-divider-color);
+}
+.ui-listview li .ui-li-action {
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+          align-self: center;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  margin-left: auto;
+  white-space: nowrap;
+}
+.ui-listview li .ui-li-action .ui-on-off-switch-container {
+  margin-right: 24px;
+}
+.ui-listview li .ui-li-right {
+  margin-left: auto !important;
+}
+.ui-listview li .ui-li-text-ellipse {
+  min-width: 0;
+  white-space: nowrap;
+}
+.ui-listview li .ui-li-text-ellipse * {
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+.ui-listview li input[type="checkbox"].ui-checkbox,
+.ui-listview li input[type="radio"].ui-radio {
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li.ui-li-selected {
+  background-color: var(--list-item-selected-color);
+}
+.ui-listview li,
+.ui-listview tau-expandable {
+  box-shadow: none;
+}
+.ui-listview li .ui-link-inherit,
+.ui-listview tau-expandable .ui-link-inherit {
+  color: var(--text-color);
+}
+.ui-listview li:not(.ui-expandable).ui-li-active,
+.ui-listview tau-expandable:not(.ui-expandable).ui-li-active {
+  background-color: var(--active);
+}
+.ui-listview li.ui-li-active.ui-expandable .ui-expandable-heading,
+.ui-listview tau-expandable.ui-li-active.ui-expandable .ui-expandable-heading {
+  background-color: var(--active);
+}
+.ui-listview li > a:not(.ui-btn),
+.ui-listview tau-expandable > a:not(.ui-btn) {
+  display: block;
+  width: 100%;
+  height: 100%;
+  margin: -16.5px -16px;
+  padding: 16.5px 16px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  overflow: hidden;
+  color: var(--text-color);
+  text-decoration: none;
+  box-sizing: border-box;
+}
+.ui-listview.ui-listview-focus {
+  box-sizing: border-box;
+  border: 2px solid blue;
+}
+.ui-listview .ui-listview-item-focus {
+  background-color: var(--ripple-color);
+}
+.ui-listview .ui-listview-item-focus a {
+  outline: none;
+}
+.ui-listview .ui-listview-background {
+  display: block;
+  box-sizing: border-box;
+  position: absolute;
+  top: 0;
+  left: 0;
+  pointer-events: none;
+  z-index: -1;
+}
+.ui-listview .ui-listview-background::before {
+  content: "250,250,250,1::0,0,0,-0.04";
+  display: none;
+}
+.ui-listview.ui-listview-background-disabled .ui-listview-background {
+  display: none;
+}
+.ui-listview .ui-li-static {
+  /**************** with progress bar ************/
+}
+.ui-listview .ui-li-static.ui-li-select-all {
+  color: var(--background-color);
+}
+.ui-listview .ui-li-static.ui-li-select-all label {
+  display: block;
+}
+.ui-listview .ui-li-static.ui-li-select-all label input[type=checkbox] {
+  float: right;
+}
+.ui-listview .ui-li-static.li-has-thumb .li-thumb {
+  position: absolute;
+  left: 16px;
+  top: 50%;
+  margin-top: -13px;
+  width: 25px;
+  height: 25px;
+}
+.ui-listview .ui-li-static.li-has-thumb .li-thumb.li-thumb-circle {
+  border-radius: 100%;
+}
+.ui-listview .ui-li-static.li-has-thumb.li-thumbnail-right .li-thumb {
+  float: right;
+  left: auto;
+  right: 16px;
+}
+.ui-listview .ui-li-static.li-has-progress {
+  padding: 12px 16px 11px;
+}
+.ui-listview .ui-li-static.li-has-progress .ui-progress {
+  margin: 16px 0 10px 0;
+}
+.ui-listview .ui-li-static .ui-btn.ui-btn-icon.ui-btn-nobg::after {
+  width: 40px;
+  height: 40px;
+}
+.ui-listview li.ui-li-flex {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  padding: 0;
+  overflow-x: visible;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex.ui-li-select-all {
+  color: var(--background-color);
+}
+.ui-listview li.ui-li-flex.ui-li-select-all label {
+  display: block;
+}
+.ui-listview li.ui-li-flex.ui-li-select-all label input[type=checkbox] {
+  float: right;
+}
+.ui-listview li.ui-li-flex .ui-li-text {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  font-size: 18px;
+  color: var(--text-color);
+  max-height: 24.25px;
+  width: 100%;
+}
+.ui-listview li.ui-li-flex .ui-li-text > *:not(.ui-li-text-sub-2) {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text .ui-li-text-sub-2 {
+  -webkit-align-self: flex-end;
+  -ms-align-self: flex-end;
+  -o-align-self: flex-end;
+  -ms-flex-item-align: end;
+      align-self: flex-end;
+}
+.ui-listview li.ui-li-flex .ui-li-text-2 {
+  color: var(--text-secondary-color);
+  line-height: 21.5px;
+  font-size: 13px;
+  max-height: 17.5px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text-2 > *:not(.ui-li-text-sub-3) {
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text-2 .ui-li-text-sub-3 {
+  -webkit-align-self: flex-end;
+  -ms-align-self: flex-end;
+  -o-align-self: flex-end;
+  -ms-flex-item-align: end;
+      align-self: flex-end;
+  margin: auto 0 auto auto;
+}
+.ui-listview li.ui-li-flex .ui-li-text-2 span + .ui-li-text-sub-3 {
+  margin-left: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub {
+  line-height: 21.5px;
+  font-size: 16px;
+  color: var(--text-secondary-color);
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub > *:not(.ui-li-text-sub-3) {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  overflow-x: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub .ui-li-text-sub-3 {
+  -webkit-align-self: flex-end;
+  -ms-align-self: flex-end;
+  -o-align-self: flex-end;
+  -ms-flex-item-align: end;
+      align-self: flex-end;
+  margin: auto 0 auto auto;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub span + .ui-li-text-sub-3 {
+  margin-left: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub-2 {
+  line-height: 27px;
+  max-width: 109px;
+  margin-left: 16px;
+  font-size: 15px;
+  color: var(--text-secondary-color);
+  float: right;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub-3 {
+  line-height: 22px;
+  max-width: 109px;
+  margin-left: 16px;
+  font-size: 16px;
+  color: var(--text-secondary-color);
+  float: right;
+}
+.ui-listview li.ui-li-flex .ui-li-text-sub + .ui-li-text-sub-3 {
+  margin-top: -1rem;
+}
+.ui-listview li.ui-li-flex .ui-li-area-a {
+  position: relative;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  min-width: 1%;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-justify-content: flex-start;
+      -ms-flex-pack: start;
+          justify-content: flex-start;
+  margin-top: 16.5px;
+  margin-bottom: 16.5px;
+  padding: 0 24px 0 18px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-b {
+  -webkit-order: 0;
+      -ms-flex-order: 0;
+          order: 0;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-image,
+.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-circle-image,
+.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-icon {
+  margin-left: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-c {
+  -webkit-order: 3;
+      -ms-flex-order: 3;
+          order: 3;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-image,
+.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-circle-image {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-icon {
+  margin-right: 8.5px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-c .ui-toggle-container {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-d {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+}
+.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-image,
+.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-circle-image {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-icon {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex input.ui-li-area-b[type="checkbox"],
+.ui-listview li.ui-li-flex input.ui-li-area-b[type="radio"] {
+  margin-left: 18px;
+  margin-right: 0;
+}
+.ui-listview li.ui-li-flex input.ui-li-area-c[type="checkbox"],
+.ui-listview li.ui-li-flex input.ui-li-area-c[type="radio"] {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex input.ui-li-area-d[type="checkbox"],
+.ui-listview li.ui-li-flex input.ui-li-area-d[type="radio"],
+.ui-listview li.ui-li-flex input.ui-li-area-d .ui-li-image,
+.ui-listview li.ui-li-flex input.ui-li-area-d .ui-li-circle-image {
+  margin-right: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-icon::after {
+  content: "";
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-position: center center;
+          mask-position: center center;
+  left: 50%;
+  top: 50%;
+  -webkit-transform: translate(-50%, -50%);
+      -ms-transform: translate(-50%, -50%);
+          transform: translate(-50%, -50%);
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-image {
+  width: 60px;
+  height: 60px;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-circle-image {
+  width: 49px;
+  height: 49px;
+  border-radius: 100%;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-icon {
+  width: 32px;
+  height: 32px;
+  position: relative;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon {
+  width: 25px;
+  min-width: 25px;
+  max-width: 25px;
+  height: 25px;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  position: relative;
+  margin-left: 16px;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon.ui-li-icon-left {
+  -webkit-order: -1;
+      -ms-flex-order: -1;
+          order: -1;
+  margin-right: 6px;
+  margin-left: 0;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon.ui-li-icon-middle {
+  top: 50%;
+  -webkit-transform: translateY(-50%);
+      -ms-transform: translateY(-50%);
+          transform: translateY(-50%);
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-c.ui-li-icon {
+  width: 40px;
+  height: 40px;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-c.ui-li-icon:after {
+  width: 25px;
+  height: 25px;
+}
+.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-d.ui-li-icon {
+  width: 25px;
+  height: 25px;
+}
+.ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a {
+  margin-top: 12px;
+  margin-bottom: 12px;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a > .ui-li-icon {
+  position: absolute;
+  right: 16px;
+}
+.ui-listview li.ui-li-flex.ui-li-flex-reverse .ui-li-area {
+  -webkit-flex-direction: column-reverse;
+      -ms-flex-direction: column-reverse;
+          flex-direction: column-reverse;
+}
+.ui-listview.ui-details .ui-li-static {
+  color: var(--text-color);
+  padding: 12px 16px 11.5px 16px;
+  height: 48.5px;
+  line-height: 27px;
+}
+.ui-listview.ui-details .ui-li-static.li-has_icon {
+  padding: 64px 16px 11.5px 16px;
+}
+.ui-listview.ui-details .ui-li-static.li-has_icon img {
+  position: absolute;
+  top: 20px;
+  left: 16px;
+}
+.ui-listview.ui-details .ui-li-static .li-text-sub {
+  color: var(--text-secondary-color);
+  height: 21.5px;
+  position: initial;
+  float: none;
+  text-align: left;
+  display: block;
+  line-height: 21.5px;
+}
+.ui-listview.ui-details .ui-listview-background {
+  display: none;
+}
+.ui-listview .li-has-right-btn .ui-btn,
+.ui-listview .li-has-right-circle-btn .ui-btn {
+  position: absolute;
+  top: 50%;
+  right: 16px;
+  -webkit-transform: translate(0, -50%);
+      -ms-transform: translate(0, -50%);
+          transform: translate(0, -50%);
+}
+.ui-listview .li-has-right-btn .ui-toggle-container,
+.ui-listview .li-has-right-circle-btn .ui-toggle-container {
+  position: absolute;
+  top: 50%;
+  right: 16px;
+  -webkit-transform: translate(0, -50%);
+      -ms-transform: translate(0, -50%);
+          transform: translate(0, -50%);
+}
+.ui-listview .li-has-right-btn .ui-toggle-container:first-child:not(:only-child),
+.ui-listview .li-has-right-circle-btn .ui-toggle-container:first-child:not(:only-child) {
+  right: 60px;
+}
+.ui-listview .li-has-right-btn .ui-btn-icon.ui-btn-nobg,
+.ui-listview .li-has-right-circle-btn .ui-btn-icon.ui-btn-nobg {
+  right: 8.5px;
+}
+.ui-listview .li-has-right-btn .ui-btn-icon.ui-btn-circle,
+.ui-listview .li-has-right-circle-btn .ui-btn-icon.ui-btn-circle {
+  right: 16px;
+}
+.ui-listview .li-has-radio.li-has-right-radio .ui-radio {
+  margin-top: 0;
+  position: absolute;
+  right: 13px;
+  left: auto;
+  top: 18px;
+}
+.ui-listview .li-has-radio.li-has-right-radio .ui-radio:first-child {
+  right: 60px;
+}
+.ui-listview.ui-drag-mode li {
+  /*align-items: center;*/
+}
+.ui-listview.ui-drag-mode li .ui-listview-handler {
+  display: block;
+  position: relative;
+  width: 32px;
+  height: 32px;
+  -webkit-flex: 0 1 auto;
+      -ms-flex: 0 1 auto;
+          flex: 0 1 auto;
+  -webkit-order: 10;
+      -ms-flex-order: 10;
+          order: 10;
+  margin: auto 16px auto auto;
+}
+.ui-listview.ui-drag-mode li .ui-listview-handler::after {
+  content: "";
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  background-color: var(--reorder-color);
+}
+.ui-listview.ui-snapshot {
+  height: 100%;
+}
+.ui-listview.ui-snapshot li {
+  position: absolute;
+  width: 100%;
+  box-sizing: border-box;
+  transition: top 0.1s linear;
+}
+.ui-listview.ui-snapshot li.ui-listview-helper {
+  transition: none;
+  background-color: var(--holder-reoder-background);
+  box-sizing: border-box;
+  border: 0.25px solid var(--holder-reoder-border);
+}
+.ui-listview.ui-snapshot li.ui-listview-helper::after {
+  display: none;
+}
+.ui-listview.ui-snapshot li.ui-listview-item.ui-listview-holder {
+  background: none;
+}
+.ui-listview.ui-snapshot li.ui-listview-item-moved {
+  opacity: 0.75;
+  transition: opacity 0.1s;
+}
+.ui-listview.ui-snapshot li:nth-last-child(2) {
+  transition: none;
+}
+.ui-listview.ui-activate-handlers li .ui-listview-handler {
+  -webkit-animation: button-handler-activate 200ms linear alternate;
+  animation: button-handler-activate 200ms linear alternate;
+}
+.ui-listview.ui-deactivate-handlers li .ui-listview-handler {
+  -webkit-animation: button-handler-deactivate 200ms linear alternate;
+  animation: button-handler-deactivate 200ms linear alternate;
+}
+.ui-listview.ui-cancel-animation li .ui-listview-handler {
+  -webkit-animation: none;
+  animation: none;
+}
+.ui-listview[data-colored-background='false'] {
+  background-color: var(--background-area-color);
+}
+.ui-listview[data-colored-background='false'] li:not(.ui-group-index) {
+  border-bottom: 1px solid #e6e6e6;
+  box-sizing: border-box;
+}
+@-webkit-keyframes button-handler-activate {
+  0% {
+    margin-right: -40px;
+  }
+  100% {
+    margin-right: 0;
+  }
+}
+@keyframes button-handler-activate {
+  0% {
+    margin-right: -40px;
+  }
+  100% {
+    margin-right: 0;
+  }
+}
+@-webkit-keyframes button-handler-deactivate {
+  0% {
+    margin-right: 0;
+  }
+  100% {
+    margin-right: -40px;
+  }
+}
+@keyframes button-handler-deactivate {
+  0% {
+    margin-right: 0;
+  }
+  100% {
+    margin-right: -40px;
+  }
+}
+.ui-page-indicator {
+  display: block;
+  position: absolute;
+  left: 50%;
+  bottom: 10px;
+  -webkit-transform: translate3d(-50%, 0, 0);
+  -ms-transform: translate3d(-50%, 0, 0);
+  transform: translate3d(-50%, 0, 0);
+}
+.ui-page-indicator-item {
+  position: relative;
+  display: inline-block;
+  width: 16px;
+  height: 16px;
+  -webkit-mask-image: -webkit-radial-gradient(black 4px, transparent 5.5px);
+  -webkit-transform: scale3d(0.7, 0.7, 1);
+  -ms-transform: scale3d(0.7, 0.7, 1);
+  transform: scale3d(0.7, 0.7, 1);
+  background-color: var(--primary-dark-color);
+  margin-right: 10px;
+  transition-duration: 150ms;
+}
+.ui-page-indicator-item:last-child {
+  margin-right: 0;
+}
+.ui-page-indicator-item.ui-page-indicator-active {
+  background-color: var(--primary-dark-color);
+  -webkit-transform: scale3d(1, 1, 1);
+  -ms-transform: scale3d(1, 1, 1);
+  transform: scale3d(1, 1, 1);
+  transition-duration: 150ms;
+}
+.ui-page-indicator-dashed .ui-page-indicator-item {
+  position: relative;
+  display: inline-block;
+  width: 20px;
+  height: 20px;
+  -webkit-mask-image: url("images/core_page_indicator_off.png");
+          mask-image: url("images/core_page_indicator_off.png");
+  -webkit-transform: rotate(0deg);
+  -ms-transform: rotate(0deg);
+  transform: rotate(0deg);
+  background-color: var(--primary-dark-color);
+  margin-right: 1px;
+  transition-duration: 150ms;
+  -webkit-mask-size: 20px;
+  -moz-mask-size: 20px;
+  -ms-mask-size: 20px;
+  -o-mask-size: 20px;
+  mask-size: 20px;
+}
+.ui-page-indicator-dashed .ui-page-indicator-item::before {
+  content: "";
+  position: absolute;
+  width: 20px;
+  height: 20px;
+  -webkit-mask-image: url("images/core_page_indicator_off_ef.png");
+          mask-image: url("images/core_page_indicator_off_ef.png");
+  -webkit-mask-size: 20px;
+  -moz-mask-size: 20px;
+  -ms-mask-size: 20px;
+  -o-mask-size: 20px;
+  mask-size: 20px;
+}
+.ui-page-indicator-dashed .ui-page-indicator-item:last-child {
+  margin-right: 0;
+}
+.ui-page-indicator-dashed .ui-page-indicator-item.ui-page-indicator-active {
+  background-color: var(--primary-dark-color);
+  -webkit-transform: rotate(90deg);
+  -ms-transform: rotate(90deg);
+  transform: rotate(90deg);
+  transition-duration: 150ms;
+}
+tau-progress {
+  display: block;
+}
+.ui-progress-container {
+  width: 360px;
+  height: inherit;
+  position: absolute;
+  top: 50%;
+  -webkit-transform: translateY(-50%);
+      -ms-transform: translateY(-50%);
+          transform: translateY(-50%);
+  box-sizing: border-box;
+}
+.ui-progress-bar {
+  position: relative;
+  min-width: 12px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  height: 32px;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  -ms-grid-column-align: center;
+      justify-items: center;
+}
+.ui-progress-bar .ui-progress-current-value {
+  font-size: 36px;
+}
+.ui-progress-text {
+  padding-top: 17px;
+  display: block;
+  font-size: 15px;
+  text-align: center;
+  color: var(--text-color);
+}
+.ui-progress-bar-labels-top {
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-progress-bar-labels-bottom {
+  -webkit-order: 3;
+      -ms-flex-order: 3;
+          order: 3;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+.ui-progress-bar-value-bg {
+  height: 3px;
+  max-height: 3px;
+  width: 100%;
+  position: relative;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  background-color: var(--progress-bar-bg-color);
+  border-radius: 1.5px;
+}
+.ui-progress-bar-label span ~ span {
+  margin-left: 2px;
+}
+.ui-progress-bar-label-left-bottom {
+  padding: 4px 0 0;
+  color: var(--text-secondary-color);
+  font-size: 16px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: left;
+  line-height: normal;
+}
+.ui-progress-bar-label-right-bottom {
+  padding: 4px 0 0;
+  color: var(--text-secondary-color);
+  font-size: 16px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: right;
+  line-height: normal;
+}
+.ui-progress-bar-label-right-top {
+  padding: 0 0 4px;
+  color: var(--progress-bar-color);
+  font-size: 16px;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: right;
+  line-height: normal;
+}
+.ui-progress-bar-value {
+  height: 3px;
+  position: absolute;
+  left: 0;
+  top: 0;
+  background-color: var(--progress-bar-color);
+  border-radius: 1.5px;
+}
+.ui-progress-circle.ui-progress-circle-full {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+.ui-progress-circle.ui-progress-circle-large {
+  width: 124px;
+  height: 124px;
+}
+.ui-progress-circle.ui-progress-circle-medium {
+  width: 56px;
+  height: 56px;
+}
+.ui-progress-circle.ui-progress-circle-small {
+  width: 44px;
+  height: 44px;
+}
+.ui-progress-circle {
+  position: relative;
+  display: inline-block;
+  box-sizing: border-box;
+}
+.ui-progress-circle * {
+  pointer-events: none;
+}
+.ui-progress-circle .ui-progress-circle-value.ui-progress-circle-half {
+  box-sizing: border-box;
+  clip: rect(auto, auto, auto, auto);
+}
+.ui-progress-circle .ui-progress-circle-value.ui-progress-circle-half .ui-progress-circle-value-right {
+  -webkit-transform: rotate(180deg);
+      -ms-transform: rotate(180deg);
+          transform: rotate(180deg);
+}
+.ui-progress-circle .ui-progress-circle-value {
+  clip: rect(0, 1em, 1em, 0.5em);
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  box-sizing: border-box;
+}
+.ui-progress-circle .ui-progress-circle-value .ui-progress-circle-value-left {
+  border: 2px solid var(--primary-color);
+  border-radius: 50%;
+  clip: rect(0, 0.5em, 1em, 0);
+  height: 100%;
+  width: 100%;
+  position: absolute;
+  box-sizing: border-box;
+}
+.ui-progress-circle .ui-progress-circle-value .ui-progress-circle-value-right {
+  border: 2px solid var(--primary-color);
+  border-radius: 50%;
+  clip: rect(0, 0.5em, 1em, 0);
+  width: 100%;
+  height: 100%;
+  position: absolute;
+  box-sizing: border-box;
+}
+.ui-progress-circle .ui-progress-circle-bg {
+  border: 2px solid var(--progress-background-color);
+  border-radius: 50%;
+  width: 100%;
+  height: 100%;
+  box-sizing: border-box;
+}
+.ui-indeterminate-bar {
+  overflow: hidden;
+  position: relative;
+  height: 3px;
+  border-radius: 1.5px;
+  background-color: var(--progress-bar-bg-color);
+}
+.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate {
+  position: relative;
+  top: 0;
+  height: 100%;
+  padding: 0;
+  background-color: transparent;
+  border-radius: 1.5px;
+}
+.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate::before {
+  content: "";
+  position: absolute;
+  width: 46%;
+  left: 0;
+  top: 0;
+  height: 100%;
+  background-color: var(--progress-bar-color);
+  -webkit-animation: indeterminate-bar1 1200ms infinite linear;
+          animation: indeterminate-bar1 1200ms infinite linear;
+}
+.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate::after {
+  content: "";
+  position: absolute;
+  width: 46%;
+  left: 93%;
+  top: 0;
+  height: 100%;
+  background-color: var(--progress-bar-color);
+  -webkit-animation: indeterminate-bar2 1200ms infinite linear;
+          animation: indeterminate-bar2 1200ms infinite linear;
+}
+@-webkit-keyframes indeterminate-bar1 {
+  0% {
+    left: -30%;
+  }
+  74.9% {
+    left: 100%;
+    opacity: 1;
+  }
+  75% {
+    left: -70%;
+    opacity: 0;
+  }
+  75.1% {
+    left: -70%;
+    opacity: 1;
+  }
+  100% {
+    left: -30%;
+  }
+}
+@keyframes indeterminate-bar1 {
+  0% {
+    left: -30%;
+  }
+  74.9% {
+    left: 100%;
+    opacity: 1;
+  }
+  75% {
+    left: -70%;
+    opacity: 0;
+  }
+  75.1% {
+    left: -70%;
+    opacity: 1;
+  }
+  100% {
+    left: -30%;
+  }
+}
+@-webkit-keyframes indeterminate-bar2 {
+  0% {
+    left: 93%;
+  }
+  59.9% {
+    left: 232%;
+    opacity: 1;
+  }
+  60% {
+    left: -46%;
+    opacity: 0;
+  }
+  60.1% {
+    left: -46%;
+    opacity: 1;
+  }
+  100% {
+    left: 93%;
+  }
+}
+@keyframes indeterminate-bar2 {
+  0% {
+    left: 93%;
+  }
+  59.9% {
+    left: 232%;
+    opacity: 1;
+  }
+  60% {
+    left: -46%;
+    opacity: 0;
+  }
+  60.1% {
+    left: -46%;
+    opacity: 1;
+  }
+  100% {
+    left: 93%;
+  }
+}
+@-webkit-keyframes rotating {
+  from {
+    -webkit-transform: rotate(0);
+            transform: rotate(0);
+  }
+  to {
+    -webkit-transform: rotate(360deg);
+            transform: rotate(360deg);
+  }
+}
+@keyframes rotating {
+  from {
+    -webkit-transform: rotate(0);
+            transform: rotate(0);
+  }
+  to {
+    -webkit-transform: rotate(360deg);
+            transform: rotate(360deg);
+  }
+}
+.ui-indeterminate-circle {
+  box-sizing: border-box;
+  margin: auto;
+  -webkit-animation: rotating 2s linear infinite;
+          animation: rotating 2s linear infinite;
+}
+.ui-indeterminate-circle::before {
+  content: "";
+  border-top-style: solid;
+  border-left-style: solid;
+  border-color: var(--progress-circle-second-color);
+  border-radius: 100% 0 0 0;
+  display: block;
+}
+.ui-indeterminate-circle::after {
+  content: "";
+  position: relative;
+  left: 50%;
+  border-right-style: solid;
+  border-bottom-style: solid;
+  border-color: var(--primary-color);
+  display: block;
+  border-radius: 100% 0;
+}
+.ui-indeterminate-circle-small-title {
+  width: 16px;
+  height: 16px;
+}
+.ui-indeterminate-circle-small-title::before,
+.ui-indeterminate-circle-small-title::after {
+  width: 6.5px;
+  height: 6.5px;
+}
+.ui-indeterminate-circle-small-title::before {
+  border-top-width: 1.5px;
+  border-left-width: 1.5px;
+}
+.ui-indeterminate-circle-small-title::after {
+  border-right-width: 1.5px;
+  border-bottom-width: 1.5px;
+}
+.ui-indeterminate-circle-small {
+  width: 24px;
+  height: 24px;
+}
+.ui-indeterminate-circle-small::before,
+.ui-indeterminate-circle-small::after {
+  width: 10px;
+  height: 10px;
+}
+.ui-indeterminate-circle-small::before {
+  border-top-width: 2px;
+  border-left-width: 2px;
+}
+.ui-indeterminate-circle-small::after {
+  border-right-width: 2px;
+  border-bottom-width: 2px;
+}
+.ui-indeterminate-circle-medium {
+  width: 48px;
+  height: 48px;
+}
+.ui-indeterminate-circle-medium::before,
+.ui-indeterminate-circle-medium::after {
+  width: 21px;
+  height: 21px;
+}
+.ui-indeterminate-circle-medium::before {
+  border-top-width: 3px;
+  border-left-width: 3px;
+}
+.ui-indeterminate-circle-medium::after {
+  border-right-width: 3px;
+  border-bottom-width: 3px;
+}
+.ui-indeterminate-circle-large {
+  width: 60px;
+  height: 60px;
+}
+.ui-indeterminate-circle-large::before,
+.ui-indeterminate-circle-large::after {
+  width: 27px;
+  height: 27px;
+}
+.ui-indeterminate-circle-large::before {
+  border-top-width: 3px;
+  border-left-width: 3px;
+}
+.ui-indeterminate-circle-large::after {
+  border-right-width: 3px;
+  border-bottom-width: 3px;
+}
+.ui-listview .ui-li-has-progress {
+  height: 4px;
+  padding: 28px 0;
+}
+.ui-listview .ui-li-has-progress-with-labels {
+  height: 4px;
+  padding: 34px 0;
+}
+.ui-scrollview-view > .ui-progress-container {
+  padding-left: 56px;
+  padding-right: 56px;
+}
+.ui-listview .ui-group-index + .ui-li-static {
+  padding-top: 16.5px;
+  padding-bottom: 16.5px;
+}
+.ui-listview .ui-group-index ~ .ui-li-static > input[type=checkbox] {
+  position: absolute;
+  right: 16px;
+  top: 17.5px;
+}
+tau-textenveloper {
+  display: block;
+}
+.ui-text-enveloper {
+  z-index: 1;
+  position: relative;
+  background-color: transparent;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  outline: none;
+  -webkit-flex-wrap: wrap;
+      -ms-flex-wrap: wrap;
+          flex-wrap: wrap;
+  overflow-x: visible;
+}
+.ui-text-enveloper.ui-text-enveloper-with-container {
+  -webkit-flex-wrap: nowrap;
+      -ms-flex-wrap: nowrap;
+          flex-wrap: nowrap;
+  -webkit-align-content: stretch;
+      -ms-flex-line-pack: stretch;
+          align-content: stretch;
+}
+.ui-text-enveloper.ui-text-enveloper-with-container .ui-text-enveloper-container {
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+  -webkit-flex-shrink: 1;
+      -ms-flex-negative: 1;
+          flex-shrink: 1;
+  -webkit-flex-basis: 100%;
+      -ms-flex-preferred-size: 100%;
+          flex-basis: 100%;
+  -webkit-flex-wrap: wrap;
+      -ms-flex-wrap: wrap;
+          flex-wrap: wrap;
+  white-space: pre-wrap;
+  overflow: visible;
+}
+.ui-text-enveloper .ui-text-enveloper-start {
+  line-height: 27px;
+  height: 27px;
+  font-size: 20px;
+  margin-top: 6.5px;
+  color: var(--primary-color);
+  margin-right: 10px;
+  display: inline-block;
+  -webkit-flex-grow: 0;
+      -ms-flex-positive: 0;
+          flex-grow: 0;
+  -webkit-flex-shrink: 0;
+      -ms-flex-negative: 0;
+          flex-shrink: 0;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn {
+  position: relative;
+  line-height: 27px;
+  height: 40px;
+  border-radius: 7.5px;
+  font-size: 20px;
+  margin-top: -1px;
+  padding: 7px 6px 6px;
+  margin-left: -6px;
+  min-height: 40px;
+  vertical-align: top;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -o-user-select: none;
+  user-select: none;
+  background-color: transparent;
+  color: var(--primary-color);
+  overflow: auto;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded::before,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn::before {
+  top: 50%;
+  left: 50%;
+  width: 100%;
+  height: 100%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+  border-radius: 0;
+  opacity: 0;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded::after,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn::after {
+  position: absolute;
+  content: "";
+  top: 50%;
+  left: 50%;
+  width: 100%;
+  height: 100%;
+  -webkit-transform: translate(-50%, -50%);
+  -ms-transform: translate(-50%, -50%);
+  transform: translate(-50%, -50%);
+  opacity: 0;
+  transition: opacity linear 200ms;
+  -webkit-mask-box-image-source: url('images/nine-patch/core_focus_round.png');
+  -webkit-mask-box-image-slice: 20 20 fill;
+  -moz-mask-box-image-slice: 20 20 fill;
+  -ms-mask-box-image-slice: 20 20 fill;
+  -o-mask-box-image-slice: 20 20 fill;
+  mask-box-image-slice: 20 20 fill;
+  background-color: var(--text-input-underline-active);
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-blur,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-blur {
+  display: none;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-blur + span,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-blur + span {
+  display: none;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-selected::after,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-selected::after {
+  opacity: 1;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-btn-active::before,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-btn-active::before {
+  opacity: 1;
+  background-color: var(--ripple-color);
+  -webkit-animation: navigation_press_animation linear 315ms;
+  animation: navigation_press_animation linear 315ms;
+}
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-btn-active.ui-btn-inactive::before,
+.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-btn-active.ui-btn-inactive::before {
+  -webkit-animation: navigation_pressup_animation linear 200ms;
+  animation: navigation_pressup_animation linear 200ms;
+}
+.ui-text-enveloper .ui-text-enveloper-btn.ui-btn:not(.ui-inline) {
+  margin-left: 3px;
+  padding-left: 5px;
+  border-bottom: 1px solid var(--primary-color);
+  overflow: visible;
+  border-radius: 0;
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  text-align: left;
+  margin-bottom: 1px;
+}
+.ui-text-enveloper .ui-text-enveloper-btn.ui-btn:not(.ui-inline) + .ui-text-enveloper-input {
+  display: block;
+  position: absolute;
+  width: 100%;
+  text-indent: 100%;
+  height: 27px;
+}
+.ui-text-enveloper .ui-text-enveloper-btn-separator {
+  display: inline-block;
+  margin: 0 6px;
+  width: 7.5px;
+}
+.ui-text-enveloper .ui-text-enveloper-btn-separator::after {
+  content: "";
+  display: block;
+  position: absolute;
+  width: 7.5px;
+  height: 16.5px;
+  margin-top: -15px;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-image: url(images/core_contact_div.png);
+          mask-image: url(images/core_contact_div.png);
+  background-color: var(--control-active-color);
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+}
+.ui-text-enveloper .ui-text-enveloper-btn-expanded {
+  color: var(--control-inactive-color);
+}
+.ui-text-enveloper .ui-text-enveloper-slash {
+  margin-top: -1px;
+  width: 13.5px;
+  height: 40px;
+  opacity: 1;
+  transition: opacity linear 200ms;
+  display: inline-block;
+  overflow: auto;
+}
+.ui-text-enveloper .ui-text-enveloper-slash::after {
+  content: "";
+  width: 7.5px;
+  margin-top: 12px;
+  height: 16.5px;
+  position: absolute;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  -webkit-mask-image: url(images/core_contact_div.png);
+          mask-image: url(images/core_contact_div.png);
+  background-color: var(--control-active-color);
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+}
+.ui-text-enveloper .ui-text-enveloper-slash.ui-text-enveloper-slash-hidden {
+  opacity: 0;
+}
+.ui-text-enveloper .ui-text-enveloper-input {
+  display: inline-block;
+  width: auto;
+  -webkit-flex: 1;
+  -moz-flex: 1;
+  -ms-flex: 1;
+  -o-flex: 1;
+  flex: 1;
+  min-width: 60px;
+  line-height: 27px;
+  height: 27px;
+  margin-top: 6px;
+  font-size: 20px;
+  background-color: transparent;
+  margin-left: -5px;
+  margin-bottom: 0;
+}
+.ui-text-enveloper .ui-text-enveloper-input-new-line {
+  clear: left;
+  width: 100%;
+}
+.ui-text-enveloper .ui-text-enveloper-input-new-line .ui-text-enveloper-input {
+  margin-left: 0;
+}
+.ui-text-enveloper .ui-text-enveloper-input-new-line.ui-text-enveloper-input-blur {
+  display: none;
+}
+.ui-text-enveloper input.ui-text-input ~ .ui-text-input-clear {
+  top: auto;
+}
+.ui-listview .ui-li-static .ui-text-enveloper,
+.ui-listview .ui-li-flex .ui-text-enveloper {
+  margin-top: -7px;
+  margin-bottom: -6px;
+  margin-right: 8.5px;
+  width: 100%;
+}
+.ui-listview .ui-li-static .ui-text-enveloper input.ui-text-input + .ui-text-input-textline,
+.ui-listview .ui-li-flex .ui-text-enveloper input.ui-text-input + .ui-text-input-textline {
+  margin-bottom: 0;
+}
+tau-gridview {
+  display: block;
+  list-style-type: disc;
+}
+.ui-gridview {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  padding: 0;
+  margin: 0;
+  list-style: none;
+}
+.ui-gridview .ui-gridview-item {
+  position: absolute;
+  border: 0.25px solid var(--grid-border-color);
+  box-sizing: border-box;
+  opacity: 0;
+  border-radius: 26px;
+  overflow: hidden;
+}
+.ui-gridview .ui-gridview-item.ui-gridview-item-active {
+  transition: -webkit-transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 1);
+  transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 1);
+  transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 1), -webkit-transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 1);
+  opacity: 1;
+}
+.ui-gridview .ui-gridview-item.ui-gridview-helper {
+  transition: none;
+  -webkit-transform: translate3d(0, 0, 0);
+          transform: translate3d(0, 0, 0);
+}
+.ui-gridview .ui-gridview-item .ui-gridview-handler {
+  display: block;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  left: 0;
+  top: 0;
+  opacity: 0;
+}
+.ui-gridview .ui-gridview-item > label {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+}
+.ui-gridview .ui-gridview-item > label.ui-gridview-image-checked {
+  background-color: var(--checkbox-image-checked);
+}
+.ui-gridview .ui-gridview-item > label > input[type="checkbox"] {
+  position: absolute;
+  margin: 8px 0 0 8px;
+  background-image: url(images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg);
+  background-size: 100%;
+  background-repeat: no-repeat;
+  opacity: 1;
+}
+.ui-gridview .ui-gridview-item > label > input[type="checkbox"]:checked {
+  background-image: url(images/3_Controllers/gallery_btn_check_bg_mtrl.svg);
+}
+.ui-gridview .ui-gridview-item > label > input[type="checkbox"]::after {
+  background-color: var(--color-white);
+}
+.ui-gridview .ui-gridview-item > label > input[type="checkbox"]:disabled {
+  opacity: 0.4;
+}
+.ui-gridview .ui-gridview-item .ui-gridview-image {
+  display: block;
+  width: 100%;
+  height: auto;
+  pointer-events: none;
+}
+.ui-gridview .ui-gridview-item.ui-gridview-item-has-label .ui-gridview-image {
+  -webkit-transform: translateY(-28.5px);
+      -ms-transform: translateY(-28.5px);
+          transform: translateY(-28.5px);
+}
+.ui-gridview .ui-gridview-item .ui-gridview-label {
+  position: absolute;
+  width: calc(100% -  30px);
+  margin: auto;
+  padding: 0 15px;
+  font-family: Roboto-Regular;
+  font-size: 16px;
+  color: var(--grid-label-color);
+  text-align: left;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  bottom: 0;
+  background-color: var(--background-area-color);
+  height: 57px;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-gridview .ui-gridview-item .ui-gridview-label p {
+  margin: 0;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
+.ui-gridview .ui-gridview-item .ui-gridview-label p:nth-child(1) {
+  font-size: 16px;
+  color: var(--grid-label-color);
+}
+.ui-gridview .ui-gridview-item .ui-gridview-label p:nth-child(2) {
+  margin-top: 3px;
+  font-size: 13px;
+  color: var(--grid-label-secondary-color);
+}
+.ui-gridview .ui-gridview-item .ui-gridview-badge {
+  position: absolute;
+  border-radius: 25px;
+  min-width: 11px;
+  background-color: var(--accent-badge);
+  color: var(--color-white);
+  top: 4.5px;
+  right: 4.5px;
+  padding: 3px 7px;
+  font-size: 11px;
+  text-align: center;
+}
+.ui-gridview .ui-gridview-item.ui-focus {
+  -webkit-filter: invert(0.2);
+          filter: invert(0.2);
+}
+.ui-gridview.ui-gridview-label-in .ui-gridview-label {
+  position: absolute;
+  bottom: 6px;
+  display: block;
+  color: var(--grid-label-color);
+}
+.ui-gridview.ui-gridview-label-out .ui-gridview-label {
+  display: block;
+  margin: 0;
+  color: var(--grid-label-color);
+  margin-bottom: 11.5px;
+}
+.ui-gridview.ui-gridview-reorder .ui-gridview-item .ui-gridview-handler {
+  opacity: 1;
+}
+.ui-gridview-cols::after {
+  content: "2";
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  opacity: 0;
+}
+.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) {
+  box-sizing: content-box;
+}
+.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+@-webkit-keyframes grid_show_item {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@keyframes grid_show_item {
+  0% {
+    opacity: 0;
+  }
+  100% {
+    opacity: 1;
+  }
+}
+@media (orientation: portrait) {
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview {
+    min-height: 509px;
+  }
+}
+@media (orientation: portrait) and (min-width: 480px) and (max-width: 959px) {
+  .ui-gridview-cols::after {
+    content: "3";
+  }
+}
+@media (orientation: landscape) {
+  .ui-gridview-cols::after {
+    content: "4";
+  }
+}
+@media (min-width: 960px) {
+  .ui-gridview-cols::after {
+    content: "5";
+  }
+}
+.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper {
+  width: 100%;
+  height: auto;
+  overflow: auto;
+  border-radius: 26px;
+}
+.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper .ui-popup-content.ui-popup-content-gridview {
+  padding: 0;
+  margin: 0;
+  height: 135px;
+}
+.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper .ui-popup-content.ui-popup-content-gridview-multiple {
+  padding: 0;
+  margin: 0;
+  height: 252px;
+}
+@media (orientation: landscape) {
+  .ui-popup.ui-popup-gridview {
+    width: 360px;
+    left: 70px;
+  }
+  .ui-gridview-image {
+    display: block;
+    width: 90.5px;
+    height: 90.5px;
+    pointer-events: none;
+  }
+}
+@media (min-width: 1920px) {
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out {
+    min-width: 1920px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out .ui-gridview-item .ui-gridview-image {
+    width: 240px;
+    height: 238px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out .ui-gridview-item .ui-gridview-label {
+    height: 39px;
+    line-height: 39px;
+    padding: 0 10px;
+    margin: 0;
+    margin-bottom: 23px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) {
+    min-width: 1920px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item {
+    width: 240px;
+    height: 238px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item .ui-gridview-image {
+    width: 240px;
+    height: 238px;
+  }
+  .ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item .ui-gridview-label {
+    height: 39px;
+    line-height: 39px;
+    padding: 0 10px;
+  }
+}
+.ui-welcome-page .ui-content .ui-scrollview-view {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+  -moz-flex-direction: column;
+  -ms-flex-direction: column;
+  -o-flex-direction: column;
+  flex-direction: column;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  text-align: center;
+  padding-bottom: 41.5px;
+}
+.ui-welcome-page .ui-content .ui-welcome-icon {
+  height: 80px;
+  width: auto;
+  -webkit-flex: 0 0 auto;
+  -moz-flex: 0 0 auto;
+  -ms-flex: 0 0 auto;
+  -o-flex: 0 0 auto;
+  flex: 0 0 auto;
+  -webkit-align-self: center;
+  -ms-align-self: center;
+  -o-align-self: center;
+  -ms-flex-item-align: center;
+      -ms-grid-row-align: center;
+      align-self: center;
+}
+.ui-welcome-page .ui-content .ui-welcome-primary-text,
+.ui-welcome-page .ui-content .ui-welcome-secondary-text {
+  margin: 0 20px;
+  font-weight: normal;
+}
+.ui-welcome-page .ui-content .ui-welcome-primary-text {
+  color: var(--text-color);
+  line-height: 33.5px;
+  font-size: 24.5px;
+}
+.ui-welcome-page .ui-content .ui-welcome-secondary-text {
+  color: var(--text-secondary-color);
+  line-height: 21.5px;
+  font-size: 17.5px;
+}
+.ui-welcome-page .ui-content .ui-welcome-primary-text + .ui-welcome-secondary-text {
+  margin-top: 29px;
+}
+.ui-welcome-page .ui-footer {
+  height: 86px;
+  text-align: center;
+  -webkit-justify-content: center;
+  -moz-justify-content: center;
+  -ms-justify-content: center;
+  -o-justify-content: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  -webkit-align-items: center;
+  -moz-align-items: center;
+  -ms-align-items: center;
+  -o-align-items: center;
+  -ms-flex-align: center;
+      align-items: center;
+}
+.ui-welcome-page .ui-footer button,
+.ui-welcome-page .ui-footer .ui-btn-welcome {
+  min-width: 248px;
+  height: 52px;
+  background-color: var(--primary-color);
+  display: inline-block;
+  width: auto;
+  -webkit-flex: 0 0 auto;
+  -moz-flex: 0 0 auto;
+  -ms-flex: 0 0 auto;
+  -o-flex: 0 0 auto;
+  flex: 0 0 auto;
+}
+.ui-welcome-page .ui-footer button:active,
+.ui-welcome-page .ui-footer .ui-btn-welcome:active,
+.ui-welcome-page .ui-footer button:focus,
+.ui-welcome-page .ui-footer .ui-btn-welcome:focus {
+  background-color: var(--ripple-color);
+}
+.ui-welcome-page .ui-footer button[disabled],
+.ui-welcome-page .ui-footer .ui-btn-welcome[disabled],
+.ui-welcome-page .ui-footer button.ui-disabled,
+.ui-welcome-page .ui-footer .ui-btn-welcome.ui-disabled {
+  background-color: var(--control-inactive-color);
+}
+.ui-dimmer {
+  position: relative;
+  border: 60px solid rgba(0, 151, 216, 0.5);
+  border-radius: 100%;
+  max-width: 720px;
+  /* @TODO: temp fix for mobile on tv usage */
+}
+.ui-dimmer::after {
+  display: block;
+  content: " ";
+  padding-bottom: 100%;
+}
+.ui-dimmer .ui-dimmer-hidden {
+  display: none;
+}
+.ui-dimmer .ui-dimmer-text {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  -webkit-transform: translate(-50%, -50%);
+      -ms-transform: translate(-50%, -50%);
+          transform: translate(-50%, -50%);
+}
+.ui-dimmer.ui-dimmer-lightbulb {
+  width: 50%;
+  left: 50%;
+  -webkit-transform: translateX(-50%);
+      -ms-transform: translateX(-50%);
+          transform: translateX(-50%);
+  padding-bottom: 50%;
+  border-radius: 0;
+  border: none;
+  background-image: url("images/dimmer/lightbulb.png");
+  background-size: contain;
+  display: block;
+}
+.ui-dimmer.ui-dimmer-lightbulb::after {
+  display: none;
+}
+.ui-dimmer.ui-dimmer-lightbulb .ui-dimmer-lightbulb-light {
+  display: block;
+  position: absolute;
+  width: 60%;
+  height: 60%;
+  left: 50%;
+  top: 5%;
+  opacity: 0.7;
+  -webkit-transform: translateX(-50%);
+      -ms-transform: translateX(-50%);
+          transform: translateX(-50%);
+  background-color: yellow;
+  -webkit-filter: blur(1.3rem);
+          filter: blur(1.3rem);
+  border-radius: 50%;
+  border: none;
+  transition: background-color 0.3s;
+}
+.wrapper {
+  -webkit-perspective: 600px;
+          perspective: 600px;
+  margin: 32px auto;
+  margin-top: 15%;
+  margin-right: 5%;
+  width: 100%;
+  height: 150px;
+}
+.wrapper_test {
+  -webkit-perspective: 600px;
+          perspective: 600px;
+  white-space: nowrap;
+}
+.outer {
+  transition: .8s;
+  -webkit-transform: rotateY(40deg);
+          transform: rotateY(40deg);
+  width: auto;
+  height: auto;
+  overflow-x: scroll;
+  margin-top: 10%;
+  margin-left: 30%;
+}
+.inner {
+  transition: .8s;
+  -webkit-transform: rotateY(40deg);
+          transform: rotateY(40deg);
+  margin-left: -15%;
+  width: auto;
+  height: auto;
+}
+.inner figure {
+  box-shadow: -3.5px 3.5px 1px -1.5px rgba(100, 100, 100, 0.5);
+  display: inline-block;
+}
+.inner img {
+  display: block;
+  width: 50px;
+  height: 50px;
+  max-width: 100%;
+  box-reflect: below 0 -webkit-gradient(linear, left bottom, left top, color-stop(0.05, rgba(255, 255, 255, 0.12)), color-stop(0.35, transparent));
+  -webkit-box-reflect: below 0 -webkit-gradient(linear, left bottom, left top, color-stop(0.05, rgba(255, 255, 255, 0.12)), color-stop(0.35, transparent));
+}
+.flipster {
+  display: block;
+  overflow-x: hidden;
+  overflow-y: visible;
+  position: relative;
+}
+.flipster:focus {
+  outline: none;
+}
+.flipster__container {
+  margin: 0;
+  padding: 0;
+  list-style-type: none;
+  position: relative;
+  display: block;
+  white-space: nowrap;
+  word-spacing: -0.25em;
+  -webkit-transform-origin: 50% 50%;
+      -ms-transform-origin: 50% 50%;
+          transform-origin: 50% 50%;
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
+}
+.flipster__item {
+  margin: 0;
+  padding: 0;
+  list-style-type: none;
+  position: relative;
+  display: inline-block;
+  white-space: normal;
+  word-spacing: normal;
+  vertical-align: bottom;
+}
+.flipster__item img {
+  max-width: 100%;
+}
+.flipster--click .flipster__item--past {
+  cursor: pointer;
+}
+.flipster--click .flipster__item--future {
+  cursor: pointer;
+}
+.flipster__button {
+  position: absolute;
+  top: 50%;
+  display: block;
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  background: none;
+  border: none;
+  padding: 0;
+  z-index: 999;
+  cursor: pointer;
+  font-size: 7.5px;
+  opacity: 0.5;
+  transition: opacity 500ms ease;
+  margin: -1em 2em;
+}
+.flipster__button svg {
+  width: 2em;
+  stroke: currentColor;
+  fill: transparent;
+  stroke-width: 3;
+  stroke-linecap: round;
+}
+.flipster__button:hover {
+  opacity: 1;
+}
+.flipster__button:focus {
+  opacity: 1;
+}
+.flipster__button--prev {
+  left: 0;
+}
+.flipster__button--next {
+  right: 0;
+}
+.flipster__nav {
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
+  display: block;
+  margin: 0 0 4em;
+  text-align: center;
+  position: relative;
+}
+.flipster__nav__item {
+  list-style-type: none;
+  margin: 0;
+  padding: 0;
+  display: inline-block;
+  margin: 0 0.25em;
+}
+.flipster__nav__link {
+  display: block;
+  color: inherit;
+  padding: 0.5em 1em;
+  position: relative;
+  overflow: hidden;
+  transition: all 250ms ease-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+}
+.flipster__nav__link::after {
+  content: '';
+  display: block;
+  background: #232221;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: -1;
+  -webkit-transform: translateY(100%) translateY(-0.25em);
+      -ms-transform: translateY(100%) translateY(-0.25em);
+          transform: translateY(100%) translateY(-0.25em);
+  transition: inherit;
+}
+.flipster__nav__link:hover {
+  color: #FFF;
+}
+.flipster__nav__link:hover::after {
+  -webkit-transform: translateY(0);
+      -ms-transform: translateY(0);
+          transform: translateY(0);
+}
+.flipster__nav__link:focus {
+  color: #FFF;
+}
+.flipster__nav__link:focus::after {
+  -webkit-transform: translateY(0);
+      -ms-transform: translateY(0);
+          transform: translateY(0);
+}
+.flipster__nav__item--current > .flipster__nav__link {
+  color: #FFF;
+}
+.flipster__nav__item--current > .flipster__nav__link::after {
+  -webkit-transform: translateY(0);
+      -ms-transform: translateY(0);
+          transform: translateY(0);
+}
+.flipster__nav__item--current .flipster__nav__child {
+  display: block;
+}
+.flipster__nav__child {
+  display: none;
+  position: absolute;
+  top: 100%;
+  left: 0;
+  right: 0;
+  margin-top: -0.5px;
+  padding: 0.5em;
+  background: #4e4441;
+  z-index: 1;
+}
+.flipster__nav__child .flipster__nav__link {
+  color: #FFF;
+}
+.flipster__nav__child .flipster__nav__link::after {
+  background: #FFF;
+}
+.flipster__nav__child .flipster__nav__link:hover {
+  color: #232221;
+}
+.flipster__nav__child .flipster__nav__link:focus {
+  color: #232221;
+}
+.flipster__nav__child .flipster__nav__item--current > .flipster__nav__link {
+  color: #232221;
+}
+.flipster--carousel .flipster__container {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+}
+.flipster--carousel .flipster__item {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  -webkit-perspective: 400px;
+          perspective: 400px;
+}
+.flipster--carousel .flipster__item__content {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+}
+.flipster--carousel .flipster__item--past {
+  opacity: 0;
+  transition-delay: 115ms;
+}
+.flipster--carousel .flipster__item--past .flipster__item__content {
+  -webkit-transform: translateX(100%) rotateY(-20deg) scale(0.5);
+          transform: translateX(100%) rotateY(-20deg) scale(0.5);
+}
+.flipster--carousel .flipster__item--future {
+  opacity: 0;
+  transition-delay: 115ms;
+}
+.flipster--carousel .flipster__item--future .flipster__item__content {
+  -webkit-transform: translateX(-100%) rotateY(20deg) scale(0.5);
+          transform: translateX(-100%) rotateY(20deg) scale(0.5);
+}
+.flipster--carousel .flipster__item--past-2 {
+  opacity: 0.6;
+  transition-delay: 20ms;
+}
+.flipster--carousel .flipster__item--past-2 .flipster__item__content {
+  -webkit-transform: translateX(25%) rotateY(40deg) scale(0.65);
+          transform: translateX(25%) rotateY(40deg) scale(0.65);
+}
+.flipster--carousel .flipster__item--future-2 {
+  opacity: 0.6;
+  transition-delay: 20ms;
+}
+.flipster--carousel .flipster__item--future-2 .flipster__item__content {
+  -webkit-transform: translateX(-25%) rotateY(-40deg) scale(0.65);
+          transform: translateX(-25%) rotateY(-40deg) scale(0.65);
+}
+.flipster--carousel .flipster__item--past-1 {
+  opacity: 0.6;
+  transition-delay: 20ms;
+}
+.flipster--carousel .flipster__item--past-1 .flipster__item__content {
+  -webkit-transform: rotateY(45deg) scale(0.8);
+          transform: rotateY(45deg) scale(0.8);
+}
+.flipster--carousel .flipster__item--future-1 {
+  opacity: 0.6;
+  transition-delay: 20ms;
+}
+.flipster--carousel .flipster__item--future-1 .flipster__item__content {
+  -webkit-transform: rotateY(-45deg) scale(0.8);
+          transform: rotateY(-45deg) scale(0.8);
+}
+.flipster--carousel .flipster__item--current .flipster__item__content {
+  -webkit-transform: translateX(0) rotateY(0deg) scale(1);
+          transform: translateX(0) rotateY(0deg) scale(1);
+  transition-delay: 60ms;
+}
+.flipster--carousel.no-rotate .flipster__item--past .flipster__item__content {
+  -webkit-transform: translateX(175%) scale(0.5);
+      -ms-transform: translateX(175%) scale(0.5);
+          transform: translateX(175%) scale(0.5);
+}
+.flipster--carousel.no-rotate .flipster__item--past-2 .flipster__item__content {
+  -webkit-transform: translateX(25%) scale(0.65);
+      -ms-transform: translateX(25%) scale(0.65);
+          transform: translateX(25%) scale(0.65);
+}
+.flipster--carousel.no-rotate .flipster__item--past-1 .flipster__item__content {
+  -webkit-transform: translateX(0%) scale(0.8);
+      -ms-transform: translateX(0%) scale(0.8);
+          transform: translateX(0%) scale(0.8);
+}
+.flipster--carousel.no-rotate .flipster__item--future .flipster__item__content {
+  -webkit-transform: translateX(-175%) scale(0.5);
+      -ms-transform: translateX(-175%) scale(0.5);
+          transform: translateX(-175%) scale(0.5);
+}
+.flipster--carousel.no-rotate .flipster__item--future-2 .flipster__item__content {
+  -webkit-transform: translateX(-25%) scale(0.65);
+      -ms-transform: translateX(-25%) scale(0.65);
+          transform: translateX(-25%) scale(0.65);
+}
+.flipster--carousel.no-rotate .flipster__item--future-1 .flipster__item__content {
+  -webkit-transform: translateX(0%) scale(0.8);
+      -ms-transform: translateX(0%) scale(0.8);
+          transform: translateX(0%) scale(0.8);
+}
+.flipster--coverflow .flipster__container {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  padding-bottom: 10%;
+}
+.flipster--coverflow .flipster__item {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  -webkit-perspective: 400px;
+          perspective: 400px;
+}
+.flipster--coverflow .flipster__item__content {
+  transition: all 350ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  -webkit-transform-origin: 50% 100%;
+      -ms-transform-origin: 50% 100%;
+          transform-origin: 50% 100%;
+  box-reflect: below 0 -webkit-gradient(linear, left bottom, left top, color-stop(0.05, rgba(255, 255, 255, 0.12)), color-stop(0.35, transparent));
+  -webkit-box-reflect: below 0 -webkit-gradient(linear, left bottom, left top, color-stop(0.05, rgba(255, 255, 255, 0.12)), color-stop(0.35, transparent));
+}
+.flipster--coverflow .flipster__item__content img:only-child {
+  display: block;
+}
+.flipster--coverflow .flipster__item--past .flipster__item__content {
+  -webkit-transform-origin: 0% 50%;
+      -ms-transform-origin: 0% 50%;
+          transform-origin: 0% 50%;
+  -webkit-transform: scale(0.75) rotateY(55deg);
+          transform: scale(0.75) rotateY(55deg);
+}
+.flipster--coverflow .flipster__item--future .flipster__item__content {
+  -webkit-transform-origin: 100% 50%;
+      -ms-transform-origin: 100% 50%;
+          transform-origin: 100% 50%;
+  -webkit-transform: scale(0.75) rotateY(-55deg);
+          transform: scale(0.75) rotateY(-55deg);
+}
+.flipster--coverflow .flip-current .flipster__item__content {
+  -webkit-transform: rotateY(0deg);
+          transform: rotateY(0deg);
+}
+.flipster--flat .flipster__container {
+  transition: all 400ms ease-in-out;
+}
+.flipster--flat .flipster__item {
+  transition: all 400ms ease-in-out;
+}
+.flipster--flat .flipster__item__content {
+  transition: all 400ms ease-in-out;
+}
+.flipster--flat .flipster__item--past {
+  opacity: 0.5;
+}
+.flipster--flat .flipster__item--past .flipster__item__content {
+  -webkit-transform: scale(0.75);
+      -ms-transform: scale(0.75);
+          transform: scale(0.75);
+}
+.flipster--flat .flipster__item--future {
+  opacity: 0.5;
+}
+.flipster--flat .flipster__item--future .flipster__item__content {
+  -webkit-transform: scale(0.75);
+      -ms-transform: scale(0.75);
+          transform: scale(0.75);
+}
+.flipster--wheel {
+  overflow: hidden;
+}
+.flipster--wheel .flipster__container {
+  transition: all 400ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  padding-bottom: 20%;
+}
+.flipster--wheel .flipster__item__content {
+  transition: all 400ms ease-in-out;
+  transition-timing-function: cubic-bezier(0.56, 0.12, 0.12, 0.98);
+  -webkit-transform-origin: 50% 100%;
+      -ms-transform-origin: 50% 100%;
+          transform-origin: 50% 100%;
+}
+.flipster--wheel .flipster__item__content img:only-child {
+  display: block;
+}
+.flipster--wheel .flipster__item--past .flipster__item__content {
+  -webkit-transform-origin: 100% 100%;
+      -ms-transform-origin: 100% 100%;
+          transform-origin: 100% 100%;
+  opacity: 0;
+  -webkit-transform: rotateZ(-80deg) translate(-170%, 110%);
+      -ms-transform: rotate(-80deg) translate(-170%, 110%);
+          transform: rotateZ(-80deg) translate(-170%, 110%);
+}
+.flipster--wheel .flipster__item--future .flipster__item__content {
+  -webkit-transform-origin: 0% 100%;
+      -ms-transform-origin: 0% 100%;
+          transform-origin: 0% 100%;
+  opacity: 0;
+  -webkit-transform: rotateZ(80deg) translate(170%, 110%);
+      -ms-transform: rotate(80deg) translate(170%, 110%);
+          transform: rotateZ(80deg) translate(170%, 110%);
+}
+.flipster--wheel .flipster__item--past-3 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(-60deg) translate(-70%, 75%);
+      -ms-transform: rotate(-60deg) translate(-70%, 75%);
+          transform: rotateZ(-60deg) translate(-70%, 75%);
+}
+.flipster--wheel .flipster__item--future-3 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(60deg) translate(70%, 75%);
+      -ms-transform: rotate(60deg) translate(70%, 75%);
+          transform: rotateZ(60deg) translate(70%, 75%);
+}
+.flipster--wheel .flipster__item--past-2 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(-40deg) translate(-17%, 30%);
+      -ms-transform: rotate(-40deg) translate(-17%, 30%);
+          transform: rotateZ(-40deg) translate(-17%, 30%);
+}
+.flipster--wheel .flipster__item--future-2 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(40deg) translate(17%, 30%);
+      -ms-transform: rotate(40deg) translate(17%, 30%);
+          transform: rotateZ(40deg) translate(17%, 30%);
+}
+.flipster--wheel .flipster__item--past-1 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(-20deg);
+      -ms-transform: rotate(-20deg);
+          transform: rotateZ(-20deg);
+}
+.flipster--wheel .flipster__item--future-1 .flipster__item__content {
+  opacity: 1;
+  -webkit-transform: rotateZ(20deg);
+      -ms-transform: rotate(20deg);
+          transform: rotateZ(20deg);
+}
+.flipster--wheel .flip-current .flipster__item__content {
+  -webkit-transform: rotateX(0deg);
+          transform: rotateX(0deg);
+}
+.ui-graph {
+  width: 100%;
+  height: 250px;
+}
+.ui-toggle-slider-container {
+  position: relative;
+  display: inline-block;
+  width: 50px;
+  height: 26px;
+}
+.ui-toggle-slider-container input {
+  background-color: #CCCCCC;
+  transition: 0.5s;
+  border-radius: 26px;
+  width: 50px;
+  height: 26px;
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+  outline: 0;
+  margin: 0;
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
+}
+.ui-toggle-slider-container input:checked {
+  background-color: #3695DD;
+}
+.ui-toggle-slider-container input:disabled {
+  background-color: W015L1D;
+}
+.ui-toggle-slider-container .ui-toggle-slider:before {
+  position: absolute;
+  content: '';
+  height: 22px;
+  width: 22px;
+  left: 1px;
+  bottom: 2px;
+  background-color: #FFFFFF;
+  transition: 0.5s;
+  border-radius: 50%;
+  pointer-events: none;
+}
+.ui-toggle-slider-container input:checked + .ui-toggle-slider:before {
+  -webkit-transform: translateX(25.5px);
+      -ms-transform: translateX(25.5px);
+          transform: translateX(25.5px);
+}
+.ui-coverflow:focus {
+  background-color: var(--ripple-color);
+}
+.ui-spin {
+  position: relative;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  height: 164px;
+  background-color: transparent;
+  overflow: hidden;
+  font-size: 32px;
+  padding: 0;
+  box-sizing: content-box;
+  width: 50px;
+}
+.ui-spin-item {
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  background-color: transparent;
+  width: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  color: var(--primary-dark-color);
+  opacity: var(--spin-item-opacity) !important;
+  -webkit-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  font-family: Roboto-Medium;
+}
+.ui-spin-item-selected {
+  opacity: 1 !important;
+}
+.ui-spin-carousel-item {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 100%;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-spin-enabling .ui-spin-item {
+  transition: 300ms opacity linear;
+}
+.ui-spin-placeholder {
+  opacity: 0;
+  pointer-events: none;
+  position: absolute;
+  display: none;
+}
+.ui-time-picker {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  height: 164px;
+  -webkit-justify-content: space-evenly;
+      -ms-flex-pack: space-evenly;
+          justify-content: space-evenly;
+}
+.ui-time-picker[data-format="12"] .ui-time-picker-container {
+  width: 28%;
+}
+.ui-time-picker[data-format="12"] .ui-time-picker-container-hour::after {
+  content: ":";
+  height: 164px;
+  width: 4%;
+  font-size: 32px;
+  color: var(--primary-dark-color);
+  position: absolute;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-time-picker[data-format="12"] .ui-time-picker-container-format .ui-spin-item {
+  font-size: 24px;
+  line-height: 54px;
+}
+.ui-time-picker[data-format="24"] .ui-time-picker-container {
+  width: 30%;
+}
+.ui-time-picker[data-format="24"] .ui-time-picker-container-hour::after {
+  content: ":";
+  height: 164px;
+  width: 13.33333333%;
+  font-size: 32px;
+  color: var(--primary-dark-color);
+  position: absolute;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-time-picker[data-format="24"] .ui-time-picker-container-format {
+  display: none;
+}
+.ui-time-picker .ui-spin {
+  width: 100%;
+  height: 164px;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-time-picker .ui-spin .ui-time-picker-input {
+  width: 50px;
+  height: 50px;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  text-align: center;
+  font-size: 32px;
+  color: transparent;
+  font-family: Roboto-Regular;
+  border-width: 0;
+  outline: unset;
+  outline-offset: unset;
+  text-shadow: 0 0 0 var(--primary-dark-color);
+  opacity: 0;
+  background-color: transparent;
+}
+.ui-time-picker .ui-spin .ui-time-picker-input:focus {
+  background-color: var(--primary-color-20p);
+}
+.ui-time-picker .ui-spin-item {
+  font-family: Roboto-Regular;
+  line-height: 56px;
+}
+.ui-time-picker-input-active .ui-time-picker-container-hour .ui-spin-item,
+.ui-time-picker-input-active .ui-time-picker-container-minute .ui-spin-item {
+  opacity: 0 !important;
+}
+.ui-time-picker-input-active .ui-time-picker-container-hour .ui-time-picker-input,
+.ui-time-picker-input-active .ui-time-picker-container-minute .ui-time-picker-input {
+  opacity: 1;
+}
+.ui-calendar-view {
+  width: 100%;
+  border-spacing: 0;
+}
+.ui-calendar-view tr td {
+  height: 32px;
+  text-align: center;
+  vertical-align: middle;
+  font-size: 15px;
+  font-family: Roboto-Regular;
+  color: var(--calendar-text-color);
+  padding: 0;
+}
+.ui-calendar-view tr td div {
+  border-radius: 100%;
+  width: 28px;
+  height: 28px;
+  line-height: 28px;
+  margin: 0 auto;
+}
+.ui-calendar-view tr td div.ui-calendar-selection {
+  background-color: var(--primary-color);
+  color: var(--calendar-select-text-color);
+}
+.ui-calendar-view tr td:only-child {
+  width: 100%;
+}
+.ui-calendar-view tr td:nth-last-child(2) {
+  width: 50%;
+}
+.ui-calendar-view tr td:nth-last-child(2) + td {
+  width: 50%;
+}
+.ui-calendar-view tr td:nth-last-child(3) {
+  width: 33.3%;
+}
+.ui-calendar-view tr td:nth-last-child(3) ~ td {
+  width: 33.3%;
+}
+.ui-calendar-view tr td:nth-last-child(4) {
+  width: 25%;
+}
+.ui-calendar-view tr td:nth-last-child(4) ~ td {
+  width: 25%;
+}
+.ui-calendar-view tr td:nth-last-child(5) {
+  width: 20%;
+}
+.ui-calendar-view tr td:nth-last-child(5) ~ td {
+  width: 20%;
+}
+.ui-calendar-view tr td:nth-last-child(6) {
+  width: 16.6%;
+}
+.ui-calendar-view tr td:nth-last-child(6) ~ td {
+  width: 16.6%;
+}
+.ui-calendar-view tr td:nth-last-child(7) {
+  width: 14.2%;
+}
+.ui-calendar-view tr td:nth-last-child(7) ~ td {
+  width: 14.2%;
+}
+.ui-calendar-view tr td:nth-child(7) {
+  color: var(--calendar-weekend-day-color);
+}
+.ui-calendar-view .ui-calendar-one-week {
+  height: 32px;
+}
+.ui-calendar-view .ui-calendar-one-week td {
+  font-family: Roboto-Regular;
+  font-size: 11px;
+  color: var(--text-secondary-color);
+}
+.ui-calendar-view .ui-calendar-one-week .ui-sunday {
+  color: var(--calendar-weekend-color);
+}
+.ui-calendar-top-space {
+  height: 10px;
+}
+.ui-calendar-prev-month-day {
+  opacity: 0.1;
+}
+.ui-calendar-next-month-day {
+  opacity: 0.4;
+}
+.ui-calendar-controller {
+  width: 100%;
+  height: 36px;
+  line-height: 36px;
+  margin: 0 auto;
+  text-align: center;
+}
+.ui-calendar-controller div.ui-calendar-switch {
+  text-align: center;
+  font-family: Roboto-Regular;
+  font-size: 17px;
+  color: var(--calendar-text-color);
+  line-height: 36px;
+  display: inline;
+}
+.ui-calendar-arrow {
+  width: 36px;
+  height: 36px;
+  -webkit-mask-repeat: no-repeat;
+          mask-repeat: no-repeat;
+  -webkit-mask-position: center;
+          mask-position: center;
+  -webkit-mask-size: 100%;
+          mask-size: 100%;
+  background-color: var(--calendar-arrow-color);
+}
+.ui-calendar-left-arrow {
+  float: left;
+  -webkit-mask-image: url("images/4_Dialogs/tw_numberpicker_prev_mtrl.svg");
+          mask-image: url("images/4_Dialogs/tw_numberpicker_prev_mtrl.svg");
+}
+.ui-calendar-right-arrow {
+  float: right;
+  -webkit-mask-image: url("images/4_Dialogs/tw_numberpicker_next_mtrl.svg");
+          mask-image: url("images/4_Dialogs/tw_numberpicker_next_mtrl.svg");
+}
+.ui-calendar-disabled {
+  opacity: 0.1;
+}
+.ui-calendar-disabled-arrow {
+  opacity: 0.4;
+}
+@media (min-width: 361px) {
+  .ui-calendar-controller {
+    width: 328px;
+    margin: 0 auto;
+  }
+}
+.ui-content-area .ui-calendar,
+.ui-popup-content .ui-calendar {
+  padding: 14px 16px;
+}
+.ui-date-picker {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  -webkit-flex-direction: column;
+      -ms-flex-direction: column;
+          flex-direction: column;
+}
+.ui-date-picker-header {
+  font-family: Roboto-Regular;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  width: 100%;
+  height: 36px;
+  font-size: 17px;
+  color: var(--date-picker-header-text-color);
+  line-height: 36px;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  margin-top: 14px;
+  margin-bottom: 10px;
+}
+.ui-date-picker-content {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  -webkit-flex-direction: row;
+      -ms-flex-direction: row;
+          flex-direction: row;
+  -webkit-justify-content: space-evenly;
+      -ms-flex-pack: space-evenly;
+          justify-content: space-evenly;
+}
+.ui-date-picker-content .ui-date-picker-container {
+  width: 28%;
+  height: 164px;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+}
+.ui-date-picker-content .ui-date-picker-container .ui-spin {
+  width: 100%;
+}
+.ui-date-picker-content .ui-date-picker-container .ui-spin-item {
+  font-size: 32px;
+  line-height: 54px;
+  font-family: Roboto-Regular;
+}
+.ui-date-picker-content .ui-date-picker-container .ui-spin-item-selected {
+  line-height: 56px;
+}
+.ui-date-picker-content .ui-date-picker-container-month .ui-spin-item {
+  font-size: 30px;
+}
+.ui-datetime-picker-wheel {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  height: 164px;
+  margin-left: 4%;
+  margin-right: 6%;
+  padding-top: 60px;
+  padding-bottom: 81px;
+}
+.ui-datetime-picker-wheel-container {
+  -webkit-flex: 1;
+      -ms-flex: 1;
+          flex: 1;
+  font-size: 22px;
+}
+.ui-datetime-picker-wheel-container-separator {
+  position: relative;
+}
+.ui-datetime-picker-wheel-container-separator::after {
+  content: ":";
+  height: 100%;
+  width: auto;
+  color: var(--primary-dark-color);
+  position: absolute;
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  right: 0;
+}
+.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-date {
+  min-width: 47%;
+}
+.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-hour {
+  min-width: 14%;
+}
+.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-minute {
+  min-width: 14%;
+}
+.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-format {
+  min-width: 13%;
+}
+.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-date {
+  min-width: 47%;
+}
+.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-hour {
+  min-width: 14%;
+}
+.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-minute {
+  min-width: 14%;
+}
+.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-format {
+  display: none;
+}
+.ui-datetime-picker-wheel .ui-spin {
+  width: 100%;
+  height: 164px;
+  -webkit-justify-content: center;
+      -ms-flex-pack: center;
+          justify-content: center;
+  white-space: nowrap;
+  font-size: 22px;
+}
+.ui-datetime-picker-wheel .ui-spin .ui-datetime-picker-wheel-input {
+  width: 50px;
+  height: 50px;
+  -webkit-align-self: center;
+      -ms-flex-item-align: center;
+              -ms-grid-row-align: center;
+          align-self: center;
+  text-align: center;
+  font-size: 22px;
+  color: transparent;
+  font-family: Roboto-Regular;
+  border-width: 0;
+  outline: unset;
+  outline-offset: unset;
+  text-shadow: 0 0 0 var(--primary-dark-color);
+  opacity: 0;
+  background-color: transparent;
+}
+.ui-datetime-picker-wheel .ui-spin .ui-datetime-picker-wheel-input:focus {
+  background-color: var(--primary-color-20p);
+}
+.ui-datetime-picker-wheel .ui-spin-item {
+  font-family: Roboto-Regular;
+  line-height: 54px;
+}
+.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-hour .ui-spin-item,
+.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-minute .ui-spin-item {
+  opacity: 0 !important;
+}
+.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-hour .ui-datetime-picker-wheel-input,
+.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-minute .ui-datetime-picker-wheel-input {
+  opacity: 1;
+}
+.ui-datetime-picker-hidden {
+  display: none;
+}
+.ui-chip {
+  display: -webkit-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  font-family: Roboto-Regular;
+  font-size: 14px;
+  height: 30px;
+  border-radius: 15px;
+  padding: 0 0 0 16px;
+  background-color: var(--chip-background-color);
+  border: 0.25px solid var(--chip-border-color);
+  box-sizing: border-box;
+  -webkit-align-items: center;
+      -ms-flex-align: center;
+          align-items: center;
+}
+.ui-chip .ui-chip-text {
+  text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap;
+  -webkit-order: 1;
+      -ms-flex-order: 1;
+          order: 1;
+}
+.ui-chip .ui-chip-button {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+}
+.ui-chip .ui-btn.ui-btn-flat {
+  -webkit-order: 2;
+      -ms-flex-order: 2;
+          order: 2;
+  width: 20px;
+  height: 20px;
+  max-width: 20px;
+  max-height: 20px;
+  min-width: 20px;
+  min-height: 20px;
+  max-width: 100%;
+  margin: auto 5px auto 10px;
+  padding: 0;
+  border-radius: 100%;
+  background-color: var(--chip-btn-background-color);
+  border: 0.5px solid var(--chip-btn-border-color);
+  box-sizing: border-box;
+}
+.ui-chip .ui-btn.ui-btn-flat::after {
+  width: 20px;
+  height: 20px;
+  -webkit-mask-size: 20px;
+          mask-size: 20px;
+}
+.ui-chip .ui-btn.ui-btn-flat::before {
+  width: 30px;
+  height: 30px;
+}
+.ui-chip .ui-btn.ui-btn-flat.ui-btn-icon {
+  background-color: var(--chip-btn-background-color);
+}
+.ui-chip .ui-btn.ui-btn-flat.ui-icon-add::after {
+  -webkit-mask-image: url(images/3_Controllers/tw_chips_icon_add_mtrl.svg);
+          mask-image: url(images/3_Controllers/tw_chips_icon_add_mtrl.svg);
+}
+.ui-chip .ui-btn.ui-btn-flat.ui-icon-delete::after {
+  -webkit-mask-image: url(images/3_Controllers/tw_chips_icon_delete_mtrl.svg);
+          mask-image: url(images/3_Controllers/tw_chips_icon_delete_mtrl.svg);
+}
+.ui-chips {
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+  margin: 0 20px;
+  row-gap: 4px;
+  -webkit-column-gap: 7px;
+          column-gap: 7px;
+  -webkit-flex-wrap: wrap;
+      -ms-flex-wrap: wrap;
+          flex-wrap: wrap;
+  max-height: 114px;
+  overflow-y: auto;
+}
+.ui-chips .ui-chip {
+  margin-top: 4px;
+  max-width: 100%;
+}
+.ui-chips.ui-chips-inline {
+  -webkit-flex-wrap: nowrap;
+      -ms-flex-wrap: nowrap;
+          flex-wrap: nowrap;
+  overflow-x: scroll;
+  height: 44px;
+}
+.tau-info-theme:after {
+  content: "default";
+}
diff --git a/d2d_app/client/lib/tau/mobile/theme/default/tau.min.css b/d2d_app/client/lib/tau/mobile/theme/default/tau.min.css
new file mode 100644 (file)
index 0000000..c18db94
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+:root{--text-secondary-color:#909090;--primary-color:#0381fe;--control-background:#e6e6e6;--textual-background:#FCFCFC;--color-white:#fafafa;--surface:#FCFCFC;--accent-badge:#F56A0D;--on-background:#858585;--border-surface:#e6e6e6;--button-background:rgba(0,0,0,0);--button-background-flat:transparent;--button-text-font-size:17px;--button-contained-text-font-size:17px;--button-contained-list-text-font-size:15px;--btn-add-color:#00b149;--btn-delete-color:#ff3d00;--checkbox-image-checked:rgba(0,0,0,.3);--slider-bg-color:rgba(3,129,254,.3);--slider-bg-disabled-color:rgba(102,102,102,.15);--slider-value-color:#0381fe;--slider-handler-color:#0381fe;--btn-toast-background:rgba(71,71,71,.9);--btn-toast-text-color:#0381fe;--toast-background:rgba(102,102,102,.95);--toast-text-color:#FFF;--progress-circle-second-color:#06b485;--on-off-switch-off-button-border:#8f8f8f;--on-off-switch-on-disabled-track-background:rgba(143,143,143,.4);--on-off-switch-off-track-background:transparent;--on-off-switch-off-disabled-track-border:rgba(143,143,143,.4)}body,body.ui-theme-light,body.ui-theme-default{--primary-color:#0381fe;--primary-dark-color:#0072de;--primary-color-20p:rgba(3,129,254,.2);--primary-color-30p:rgba(3,129,254,.3);--control-active-color:#3e91ff;--control-active-disabled-color:rgba(62,145,255,.4);--control-inactive-color:#8f8f8f;--text-color:#252525;--text-secondary-color:#909090;--color-white:#fafafa;--color-black:#000;--ripple-color:rgba(0,0,0,.1);--overlay:rgba(0,0,0,.45);--background-color:#F2F2F2;--background-area-color:#fcfcfc;--expandable-text-color:#666;--popup-background:#fcfcfc;--popup-text:#505050;--popup-text-secondary-color:#8f8f8f;--popup-footer-divider-color:#e6e6e6;--popup-scroll-divider-color:#d4d4d4;--icon-color:#3b3b3b;--appbar-main-text-color:#252525;--appbar-subtitle-color:#636363;--appbar-miltiline-title-color:#252525;--tab-text-color:#858585;--tab-text-color-dim:rgba(133,133,133,.4);--bottom-bar-color:#F2F2F2;--button-icon-color:#252525;--bottom-button-icon-color:#454545;--sub-tab-bg-color:#F2F2F2;--sub-tab-text-color:#858585;--sub-tab-active-text-color:#252525;--sub-tab-border-color:rgba(113,113,113,.8);--progress-bar-color:#0381fe;--progress-bar-bg-color:rgba(3,129,254,.3);--button-text-color-disabled:rgba(3,129,254,.4);--checkbox-favorite-color:#f5ab00;--ripple-button-flat-color:rgba(0,0,0,.1);--slider-handler-disabled-color:#d2d2d2;--slider-scale-dot:#9c9c9c;--slider-level-bar-bg-color:rgba(151,151,151,.3);--button-background-contained:rgba(0,0,0,.06);--on-off-switch-off-disabled-button-border:#d0d0d0;--on-off-switch-on-disabled-button-border:#d0d0d0;--on-off-switch-on-disabled-button-background:#fafafa;--on-off-switch-divider-color:#c4c4c4;--master-on-off-off-color:#fafafa;--master-on-off-on-color:rgba(62,145,255,.8);--chip-background-color:#e5e5e5;--chip-border-color:rgba(37,37,37,.2);--chip-btn-background-color:#f2f2f2;--chip-btn-border-color:rgba(37,37,37,.3);--text-input-invalid-color:#b00020;--dropdown-menu-options-border:.25px solid #ccc;--dropdown-menu-options-background:#fcfcfc;--dropdown-menu-options-color:#000;--dropdown-menu-options-color-dim:rgba(0,0,0,.4);--content-area-line-color:#d6d6d6;--list-item-selected-color:rgba(3,129,254,.08);--divider-color:#e6e6e6;--divider-opacity:100%;--subheader-divider-color:#979797;--grid-border-color:rgba(0,0,0,.12);--grid-label-color:#252525;--grid-label-secondary-color:#666;--expander-color:#747474;--reorder-color:#747474;--holder-reoder-background:#fcfcfc;--holder-reoder-border:#0072de;--spin-item-opacity:.1;--grid-selection-color:rgba(0,0,0,.3);--calendar-weekend-day-color:#c95151;--calendar-weekend-color:#d77e7e;--calendar-text-color:#454545;--calendar-arrow-color:#8e8e8e;--calendar-select-text-color:#fafafa;--date-picker-header-text-color:#454545;--text-input-disabled:#bebebe;--text-input-label-inactive:#8c8c8c;--text-input-underline-inactive:#8c8c8c;--text-input-underline-active:var(--primary-color);--icon-control-color:var(--color-white);--progress-background-color:#ccc;--on-off-switch-track-off:#8f8f8f;--more-options-background-color:var(--popup-background);--more-options-background-stroke:#ccc;--more-options-pressed-color:rgba(0,0,0,.1);--button-text-contained-dim-color:rgba(37,37,37,.4)}body.ui-theme-dark{--primary-color:#0381fe;--primary-dark-color:#3e91ff;--primary-color-20p:rgba(3,129,254,.2);--primary-color-30p:rgba(3,129,254,.3);--control-active-color:#3e91ff;--control-active-disabled-color:rgba(62,145,255,.4);--control-inactive-color:#8f8f8f;--text-color:#fafafa;--text-secondary-color:#999;--color-white:#fafafa;--color-black:#080808;--ripple-color:rgba(255,255,255,.2);--overlay:rgba(0,0,0,.65);--background-color:#080808;--background-area-color:#252525;--expandable-text-color:#9c9c9c;--popup-background:#252525;--popup-text:#e5e5e5;--popup-text-secondary-color:#999;--popup-footer-divider-color:rgba(230,230,230,.2);--popup-scroll-divider-color:rgba(212,212,212,.18);--icon-color:#d9d9d9;--appbar-main-text-color:#fafafa;--appbar-subtitle-color:#9c9c9c;--appbar-miltiline-title-color:#e5e5e5;--tab-text-color:#a8a9a9;--tab-text-color-dim:rgba(168,169,169,.4);--bottom-bar-color:#010101;--button-icon-color:#fafafa;--bottom-button-icon-color:#ccc;--sub-tab-bg-color:#010101;--sub-tab-text-color:#999;--sub-tab-active-text-color:#FFF;--sub-tab-border-color:rgba(255,255,255,.6);--progress-bar-color:#0381fe;--progress-bar-bg-color:rgba(3,129,254,.3);--button-text-color-disabled:rgba(3,129,254,.4);--checkbox-favorite-color:#f5ab00;--ripple-button-flat-color:rgba(255,255,255,.2);--slider-handler-disabled-color:#545454;--slider-scale-dot:gray;--slider-level-bar-bg-color:rgba(151,151,151,.3);--button-background-contained:rgba(250,250,250,.17);--on-off-switch-off-disabled-button-border:#3b3b3b;--on-off-switch-on-disabled-button-border:#3b3b3b;--on-off-switch-on-disabled-button-background:#858585;--on-off-switch-divider-color:rgba(212,212,212,.15);--master-on-off-off-color:rgba(250,250,250,.17);--master-on-off-on-color:rgba(62,145,255,.4);--chip-background-color:#252525;--chip-border-color:rgba(250,250,250,.2);--chip-btn-background-color:#f2f2f2;--chip-btn-border-color:rgba(37,37,37,.3);--text-input-invalid-color:#f66;--dropdown-menu-options-border:.75px solid #525252;--dropdown-menu-options-background:#3d3d3d;--dropdown-menu-options-color:#fafafa;--dropdown-menu-options-color-dim:rgba(250,250,250,.4);--content-area-line-color:#d6d6d6;--list-item-selected-color:rgba(250,250,250,.1);--divider-color:#d4d4d4;--divider-opacity:15%;--subheader-divider-color:#fafafa;--grid-border-color:rgba(250,250,250,.25);--grid-label-color:#fafafa;--grid-label-secondary-color:#999;--expander-color:gray;--reorder-color:gray;--holder-reoder-background:#252525;--holder-reoder-border:#3e91ff;--spin-item-opacity:.2;--grid-selection-color:rgba(0,0,0,.3);--calendar-weekend-day-color:#c95151;--calendar-weekend-color:#993d3d;--calendar-text-color:#ccc;--calendar-arrow-color:#737373;--calendar-select-text-color:#000;--date-picker-header-text-color:#ccc;--surface:#3d3d3d;--text-input-disabled:#454545;--text-input-label-inactive:#737373;--text-input-underline-inactive:#737373;--text-input-underline-active:var(--primary-color);--icon-control-color:var(--surface);--progress-background-color:#252525;--more-options-background-color:#3d3d3d;--more-options-background-stroke:#525252;--more-options-pressed-color:rgba(255,255,255,.2);--button-text-contained-dim-color:rgba(250,250,250,.4)}@font-face{font-family:Roboto-Light;src:url(fonts/Roboto-Light.ttf)}@font-face{font-family:Roboto-Regular;src:url(fonts/Roboto-Regular.ttf)}@font-face{font-family:Roboto-Medium;src:url(fonts/Roboto-Medium.ttf)}.tau-info-theme{position:absolute;top:-999px;left:-999px}.ui-appbar,header{position:relative;width:100%;box-sizing:border-box;background:var(--background-color);overflow:hidden;border:0;height:56px;margin-bottom:12px;font-family:Roboto-Regular;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-appbar:not(.ui-appbar-dragging),header:not(.ui-appbar-dragging){transition:height 100ms cubic-bezier(0.25,.46,.45,.94)}.ui-appbar:not(.ui-appbar-dragging) .ui-appbar-controls-container,header:not(.ui-appbar-dragging) .ui-appbar-controls-container,.ui-appbar:not(.ui-appbar-dragging) .ui-appbar-expanded-title-container,header:not(.ui-appbar-dragging) .ui-appbar-expanded-title-container{padding-top:0;transition:opacity 100ms cubic-bezier(0.25,.46,.45,.94)}.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast,header:not(.ui-appbar-dragging).ui-appbar-animation-fast{transition-duration:10ms}.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-controls-container,header:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-controls-container,.ui-appbar:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-expanded-title-container,header:not(.ui-appbar-dragging).ui-appbar-animation-fast .ui-appbar-expanded-title-container{transition-duration:10ms}.ui-appbar .ui-btn,header .ui-btn{padding:0}.ui-appbar .ui-btn.ui-btn-flat,header .ui-btn.ui-btn-flat{font-size:18px;font-family:Roboto-Medium;color:var(--appbar-main-text-color)}.ui-appbar .ui-btn.ui-btn-flat::before,header .ui-btn.ui-btn-flat::before{height:48px;border-radius:24px}.ui-appbar .ui-btn.ui-btn-icon,header .ui-btn.ui-btn-icon{background-color:transparent;position:relative;width:24px;height:24px;min-height:24px;margin-right:8px}.ui-appbar .ui-btn.ui-btn-icon::before,header .ui-btn.ui-btn-icon::before{width:48px;height:48px}.ui-appbar .ui-btn.ui-btn-icon::after,header .ui-btn.ui-btn-icon::after{width:24px;height:24px}.ui-appbar .ui-btn.ui-btn-icon-back::after,header .ui-btn.ui-btn-icon-back::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg)}.ui-appbar .ui-btn.ui-btn-icon-more::after,header .ui-btn.ui-btn-icon-more::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_more_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_more_mtrl.svg)}.ui-appbar .ui-btn.ui-btn-icon-search::after,header .ui-btn.ui-btn-icon-search::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_search_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_search_mtrl.svg)}.ui-appbar .ui-btn.ui-btn-icon-add::after,header .ui-btn.ui-btn-icon-add::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_add_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_add_mtrl.svg)}.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat,header .ui-btn.ui-btn-icon.ui-btn-flat{min-height:24px;display:block;margin-top:auto;margin-bottom:auto}.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat::after,header .ui-btn.ui-btn-icon.ui-btn-flat::after{-webkit-mask-size:100%;mask-size:100%;width:24px;height:24px}.ui-appbar .ui-btn.ui-btn-icon.ui-btn-flat::before,header .ui-btn.ui-btn-icon.ui-btn-flat::before{background-color:transparent;width:48px;height:48px}.ui-appbar .ui-btn.ui-btn-icon.ui-btn-icon-back,header .ui-btn.ui-btn-icon.ui-btn-icon-back{margin-left:20px;margin-right:12px}.ui-appbar .ui-appbar-controls-container,header .ui-appbar-controls-container{-webkit-flex:0 0 56px;-ms-flex:0 0 56px;flex:0 0 56px;width:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;position:absolute;bottom:0}.ui-appbar .ui-appbar-controls-container .ui-appbar-left-icons-container,header .ui-appbar-controls-container .ui-appbar-left-icons-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;min-width:24px;margin-top:auto;margin-bottom:auto}.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container,header .ui-appbar-controls-container .ui-appbar-title-container{height:56px;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:auto 0;overflow:hidden;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start}.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container .ui-appbar-title,header .ui-appbar-controls-container .ui-appbar-title-container .ui-appbar-title{max-width:100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:19px;color:var(--appbar-main-text-color)}.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-subtitle .ui-appbar-subtitle,header .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-subtitle .ui-appbar-subtitle{font-size:13px;color:var(--appbar-subtitle-color)}.ui-appbar .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-multiline .ui-appbar-title,header .ui-appbar-controls-container .ui-appbar-title-container.ui-appbar-has-multiline .ui-appbar-title{font-size:17px;color:var(--appbar-miltiline-title-color)}.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container,header .ui-appbar-controls-container .ui-appbar-action-buttons-container{height:100%;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;margin-left:auto;min-width:24px;margin-top:auto;margin-bottom:auto;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end}.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn,header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn{margin-right:12px;margin-left:12px}.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn:last-child,header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn:last-child{margin-right:20px;margin-left:15px}.ui-appbar .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn+.ui-btn-icon,header .ui-appbar-controls-container .ui-appbar-action-buttons-container .ui-btn+.ui-btn-icon{margin-left:3px}.ui-appbar .ui-appbar-expanded-title-container,header .ui-appbar-expanded-title-container{-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;opacity:0;height:0}.ui-appbar .ui-appbar-expanded-title-container .ui-appbar-title,header .ui-appbar-expanded-title-container .ui-appbar-title{line-height:54px;font-size:38px;font-family:Roboto-Light;margin-left:24px;margin-right:24px;text-align:center}.ui-appbar .ui-appbar-expanded-title-container .ui-appbar-subtitle,header .ui-appbar-expanded-title-container .ui-appbar-subtitle{line-height:20px;font-size:15px;text-align:center}.ui-appbar h1,header h1,.ui-appbar h2,header h2,.ui-appbar h3,header h3,.ui-appbar h4,header h4,.ui-appbar h5,header h5,.ui-appbar h6,header h6{margin:0;padding:0;border:0;outline:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline}.ui-appbar.ui-appbar-expanded,header.ui-appbar-expanded{height:calc(39.67% - 12px)}.ui-appbar.ui-appbar-expanded .ui-appbar-expanded-title-container,header.ui-appbar-expanded .ui-appbar-expanded-title-container{opacity:1}.ui-appbar.ui-appbar-dragging .ui-appbar-expanded-title-container,header.ui-appbar-dragging .ui-appbar-expanded-title-container{overflow:hidden}.ui-appbar .ui-label-select-all,header .ui-label-select-all{font-family:Roboto-Regular;font-size:12px;width:32px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding-top:10px;line-height:14px;margin-left:18px;margin-right:18px}.ui-appbar .ui-label-select-all input[type=checkbox].ui-checkbox,header .ui-label-select-all input[type=checkbox].ui-checkbox{margin:0 0 -3px 0}.ui-appbar .ui-appbar-container,header .ui-appbar-container{height:70px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-order:10;-ms-flex-order:10;order:10;background-color:var(--background-area-color);border-radius:26px;overflow:hidden;box-sizing:border-box;box-shadow:0 0 0 .25px var(--content-area-line-color) inset}.ui-appbar .ui-appbar-container>:first-child,header .ui-appbar-container>:first-child{margin-left:24px}.ui-appbar .ui-appbar-container .ui-title,header .ui-appbar-container .ui-title{font-size:18px;-webkit-flex:1;-ms-flex:1;flex:1}.ui-appbar .ui-appbar-container .ui-icon,header .ui-appbar-container .ui-icon{width:21px;height:21px;overflow:hidden;margin-right:22px}.ui-appbar .ui-appbar-container .ui-icon img,header .ui-appbar-container .ui-icon img{width:100%}.ui-appbar .ui-appbar-container .ui-btn.ui-btn-icon.ui-btn-icon-only,header .ui-appbar-container .ui-btn.ui-btn-icon.ui-btn-icon-only{height:48px;max-width:48px}@media all and (min-height:580px) and (orientation:landscape){.ui-appbar.ui-appbar-expanded{height:calc(30% - 12px)}}@media all and (min-height:960px){.ui-appbar.ui-appbar-expanded{height:calc(25% - 12px)}}.ui-card{border-radius:26px;overflow:hidden;box-sizing:border-box;margin-bottom:10px}.ui-card.ui-card-service{background-color:var(--background-area-color);border-radius:26px;overflow:hidden;box-sizing:border-box;box-shadow:0 0 0 .25px var(--content-area-line-color) inset}.ui-card.ui-card-service ::-webkit-scrollbar{display:none}.ui-card.ui-card-service .ui-subheader-text{color:#7b7b7b}.ui-card.ui-card-service .ui-content-subheader{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-card.ui-card-service .ui-content-subheader::after{content:"";display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;width:calc(100% - 20px);border-bottom:1px solid var(--subheader-divider-color);height:0;-webkit-align-items:center;-ms-flex-align:center;align-items:center;margin-right:20px;margin-left:10px}.ui-card.ui-card-service .ui-content-thumbnail{width:100%}.ui-card.ui-card-service .ui-content .ui-title.ui-title-medium{font-size:18px;font-family:Roboto-Medium}.ui-card.ui-card-service .ui-content.ui-scrollview-clip{border-radius:0}.ui-card.ui-card-service .ui-listview li .ui-li-icon{width:58px;height:58px}.ui-card.ui-card-service .ui-listview li .ui-li-icon img{width:58px;height:58px}.ui-card.ui-card-service .ui-listview li .ui-li-text{padding:25px 0 23px}.ui-card.ui-card-service .ui-listview li .ui-li-text-title{font-size:16px}.ui-card.ui-card-service .ui-listview li .ui-li-text-sub{font-size:12px}.ui-card .ui-header{display:-webkit-flex;display:-ms-flexbox;display:flex;height:46px;padding:0 20px}.ui-card .ui-header .ui-title{margin-top:24px;margin-bottom:3px;font-size:15px;color:var(--text-color);-webkit-order:1;-ms-flex-order:1;order:1;display:inline-block;-webkit-flex:1;-ms-flex:1;flex:1}.ui-card .ui-header .ui-icon{margin-right:10px;margin-top:20px;width:26px;height:26px;-webkit-order:0;-ms-flex-order:0;order:0;display:inline-block}.ui-card .ui-header .ui-icon img{width:100%;height:100%}.ui-card .ui-header .ui-controls{-webkit-order:2;-ms-flex-order:2;order:2;display:-webkit-flex;display:-ms-flexbox;display:flex;margin-top:20px;height:26px}.ui-card .ui-header .ui-controls .ui-btn{width:26px;height:26px;background-color:transparent;min-height:26px;padding:0;display:inline-block}.ui-card .ui-header .ui-controls .ui-btn~.ui-btn{margin-left:14px}.ui-card .ui-header .ui-controls .ui-btn::before{height:26px}.ui-card .ui-header .ui-controls .ui-btn::after{background-color:var(--background-area-color);height:26px;width:26px}.ui-card .ui-content,.ui-card .ui-content.ui-scrollview-clip{padding:10px 20px}.ui-card .ui-content.ui-tabs,.ui-card .ui-content.ui-scrollview-clip.ui-tabs{padding:0}.ui-card .ui-content .ui-section-changer .ui-content,.ui-card .ui-content.ui-scrollview-clip .ui-section-changer .ui-content{padding:0}.ui-card .ui-content .ui-title,.ui-card .ui-content.ui-scrollview-clip .ui-title{font-size:16px}.ui-card .ui-content .ui-description,.ui-card .ui-content.ui-scrollview-clip .ui-description{font-size:14px}.ui-card .ui-content video,.ui-card .ui-content.ui-scrollview-clip video{border-radius:26px}.ui-card .ui-content .ui-btn,.ui-card .ui-content.ui-scrollview-clip .ui-btn{width:86px;padding:0}.ui-card .ui-content .ui-btn .ui-btn-content,.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content{width:86px;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-card .ui-content .ui-btn .ui-btn-content img,.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content img{border-radius:15px;width:80px;height:80px;margin-bottom:8px}.ui-card .ui-content .ui-btn .ui-btn-content .ui-title,.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content .ui-title{font-size:14px;color:var(--text-color);line-height:16px}.ui-card .ui-content .ui-btn .ui-btn-content .ui-subtitle,.ui-card .ui-content.ui-scrollview-clip .ui-btn .ui-btn-content .ui-subtitle{font-size:12px;color:var(--text-secondary-color);line-height:14px}.ui-card .ui-container-item img{border-radius:16px;width:188px;height:126px;margin-bottom:17px}.ui-card .ui-container-item .ui-title{font-family:Roboto-Medium;color:var(--text-color);font-size:16px;line-height:19px;text-align:left;white-space:normal;margin-bottom:6px}.ui-card .ui-container-item .ui-subtitle{font-family:Roboto-Regular;color:var(--text-secondary-color);font-size:14px;line-height:16px;text-align:left;white-space:normal}.ui-card .ui-footer{height:63px;-webkit-justify-content:flex-end;-ms-flex-pack:end;justify-content:flex-end;padding:0 20px}.ui-card .ui-footer .ui-btn{display:inline-block;width:auto;height:43px;color:var(--color-white);font-size:14px;background-color:var(--primary-dark-color)}.ui-card .ui-sub-tab{background-color:transparent}.ui-card.ui-card-ads{background-color:var(--background-area-color);min-height:200px}.ui-card.ui-card-ads .ui-content{padding:0;border-radius:0}.ui-card.ui-card-ads .ui-content .ui-scrollview-view{overflow:hidden}.ui-card.ui-card-ads .ui-content video,.ui-card.ui-card-ads .ui-content img{border-radius:0;width:100%}.ui-card.ui-card-ads .ui-content .ui-title{font-family:Roboto-Medium;color:var(--text-color);font-size:16px;white-space:normal;margin:0 20px}.ui-card.ui-card-ads .ui-content .ui-title:last-child{margin-top:15px}.ui-card.ui-card-ads .ui-content .ui-subtitle{font-family:Roboto-Regular;color:var(--text-secondary-color);font-size:14px;white-space:normal;margin:0 20px}.ui-card.ui-card-ads .ui-content .ui-banner{position:relative;width:100%;height:150px;overflow:hidden}.ui-card.ui-card-ads .ui-content .ui-banner img{width:100%;position:absolute}.ui-card.ui-card-ads .ui-footer .ui-title{font-family:Roboto-Medium;color:var(--text-color);font-size:16px;white-space:normal;margin:0 20px 0 0;-webkit-flex:1;-ms-flex:1;flex:1;text-align:left}.LESSui-footer{box-sizing:border-box;padding:12px 24px;text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0}.LESSui-footer .ui-btn:not(.ui-btn-contained){height:52px;line-height:52px;margin:0 auto;max-width:248px}.LESSui-footer .ui-btn.ui-btn-contained:not(.ui-btn-inline){-webkit-flex:1;-ms-flex:1;flex:1}.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained){background-color:var(--button-background)}.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-btn-active::before{background-color:var(--ripple-color)}.LESSui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-state-disabled{background-color:var(--button-background)}.LESSui-footer .ui-btn~.ui-btn{margin-left:16px}.LESSui-footer .ui-btn.ui-btn-contained~.ui-btn.ui-btn-contained{margin-left:8px}.LESSui-footer.ui-grid-col-1 .ui-btn.ui-inline,.LESSui-footer.ui-grid-col-2 .ui-btn.ui-inline,.LESSui-footer.ui-grid-col-3 .ui-btn.ui-inline{display:block;width:100%}.LESSui-footer.ui-bottom-button{height:56px;padding-left:24px;padding-right:24px}.ui-footer{width:100%;box-sizing:border-box;padding:12px 24px;text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0}.ui-footer .ui-btn:not(.ui-btn-contained){height:52px;line-height:52px;margin:0 auto;max-width:248px}.ui-footer .ui-btn.ui-btn-contained:not(.ui-btn-inline){-webkit-flex:1;-ms-flex:1;flex:1}.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained){background-color:var(--button-background)}.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-btn-active::before{background-color:var(--ripple-color)}.ui-footer .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item):not(.ui-btn-welcome):not(.ui-btn-contained).ui-state-disabled{background-color:var(--button-background)}.ui-footer .ui-btn~.ui-btn{margin-left:16px}.ui-footer .ui-btn.ui-btn-contained~.ui-btn.ui-btn-contained{margin-left:8px}.ui-footer.ui-grid-col-1 .ui-btn.ui-inline,.ui-footer.ui-grid-col-2 .ui-btn.ui-inline,.ui-footer.ui-grid-col-3 .ui-btn.ui-inline{display:block;width:100%}.ui-footer.ui-bottom-button{height:56px;padding-left:24px;padding-right:24px}.ui-page:not(.ui-page-flex) .ui-footer{position:fixed;bottom:0}.ui-page.ui-page-flex .ui-footer{overflow:visible}.ui-page-container,.ui-page-container body{height:100%;font-size:22px}@media all and (max-width:359px){.ui-page-container,.ui-page-container body{font-size:19px}}.ui-page-container fieldset,.ui-page{padding:0;margin:0}.ui-page-container a img,.ui-page-container fieldset{border:0}.ui-page-container{margin:0;overflow-x:hidden;-webkit-tap-highlight-color:rgba(0,0,0,0)}[data-role=page],[data-role=dialog],.ui-page{top:0;left:0;width:100%;position:absolute;display:none;border:0}[data-role=page].ui-page-build,[data-role=dialog].ui-page-build,.ui-page.ui-page-build{display:block;visibility:hidden}[data-role=page].ui-pre-in,[data-role=dialog].ui-pre-in,.ui-page.ui-pre-in{z-index:100}[data-role=page].ui-pre-in,[data-role=dialog].ui-pre-in,.ui-page.ui-pre-in,[data-role=page].ui-page-active,[data-role=dialog].ui-page-active,.ui-page.ui-page-active{display:block;overflow:hidden}[data-role=page].ui-pre-in.ui-page-flex,[data-role=dialog].ui-pre-in.ui-page-flex,.ui-page.ui-pre-in.ui-page-flex,[data-role=page].ui-page-active.ui-page-flex,[data-role=dialog].ui-page-active.ui-page-flex,.ui-page.ui-page-active.ui-page-flex{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-content:stretch;-ms-flex-line-pack:stretch;align-content:stretch}[data-role=page].ui-pre-in.ui-page-flex .ui-header,[data-role=dialog].ui-pre-in.ui-page-flex .ui-header,.ui-page.ui-pre-in.ui-page-flex .ui-header,[data-role=page].ui-page-active.ui-page-flex .ui-header,[data-role=dialog].ui-page-active.ui-page-flex .ui-header,.ui-page.ui-page-active.ui-page-flex .ui-header{position:relative}[data-role=page].ui-pre-in.ui-page-flex .ui-content,[data-role=dialog].ui-pre-in.ui-page-flex .ui-content,.ui-page.ui-pre-in.ui-page-flex .ui-content,[data-role=page].ui-page-active.ui-page-flex .ui-content,[data-role=dialog].ui-page-active.ui-page-flex .ui-content,.ui-page.ui-page-active.ui-page-flex .ui-content{-webkit-flex:1;-ms-flex:1;flex:1}.ui-page-container,.ui-page-container .ui-page{color:var(--text-color);background-image:none;background-color:var(--background-color)}.ui-page-container.ui-page-light,.ui-page-container .ui-page.ui-page-light{background-image:none}.ui-page.ui-mobile-touch-overflow,.ui-mobile-touch-overflow.ui-native-fixed .ui-content{overflow:auto;height:100%;-webkit-overflow-scrolling:touch}.ui-page.ui-mobile-touch-overflow,.ui-page.ui-mobile-touch-overflow *{transform:rotateY(0);-ms-transform:rotateY(0);-moz-transform:rotateY(0);-webkit-transform:rotateY(0);-o-transform:rotateY(0)}.ui-page.ui-mobile-pre-transition{display:block}.ui-blocker{width:100%;height:100%;z-index:2147483647}.ui-mobile-rendering>*{visibility:hidden}.ui-bar,.ui-body{position:relative;padding:.4em 15px;overflow:hidden;display:block;clear:both}.ui-bar{font-size:16px;margin:0}.ui-bar h1,.ui-bar h2,.ui-bar h3,.ui-bar h4,.ui-bar h5,.ui-bar h6{margin:0;padding:0;font-size:16px;display:inline-block}.ui-content{border-width:0;overflow-y:visible;overflow-x:hidden;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;border-radius:26px}.ui-content.ui-content-padding,.ui-content.ui-content-padding.ui-scrollview-clip{padding-left:12px;padding-right:12px}.ui-content.ui-content-under-popup{pointer-events:none}.ui-content .ui-content-area{background-color:var(--background-area-color);border-radius:26px;overflow:hidden;box-sizing:border-box;box-shadow:0 0 0 .25px var(--content-area-line-color) inset;margin:auto auto 16px}@media (min-width:673px) and (min-height:411px){.ui-content .ui-content-area{width:90%}}@media (min-width:960px){.ui-content .ui-content-area{width:75%}}.ui-content .ui-content-area-disabled-top-rounding{border-top-left-radius:0;border-top-right-radius:0;-webkit-mask-box-image-width:0 26px 26px;mask-border-width:0 26px 26px}.ui-content .ui-content-area~.ui-content-subheader{margin-top:-16px}.ui-content .ui-content-subheader{color:var(--text-secondary-color);font-family:Roboto-Medium;font-size:14px;padding-bottom:7px;padding-top:13px;margin-left:24px;line-height:16px}body.ui-theme-dark .ui-content-area{box-shadow:unset}.ui-page-fullscreen .ui-content{padding:0}.ui-mobile-touch-overflow.ui-native-fixed .ui-content{padding-top:2.5em;padding-bottom:3em;top:0;bottom:0;height:auto;position:absolute}.ui-mobile-touch-overflow.ui-native-fullscreen .ui-content{padding-top:0;padding-bottom:0}.ui-native-bars-hidden{display:none}.ui-screen-hidden{display:none}.ui-icon{width:18px;height:18px}.ui-fullscreen img{max-width:100%}.ui-nojs{position:absolute;left:-9999px}.scrolling-scrollbar{position:absolute;pointer-events:none}.scrolling-scrollbar .scrolling-scrollthumb{background-color:#71cbd9;position:absolute}.scrolling-scrollbar.scrolling-direction-y{right:11px;width:10px}.scrolling-scrollbar.scrolling-direction-y .scrolling-scrollthumb{width:10px;min-height:44px;top:0;left:50%;margin-left:-5px}.scrolling-scrollbar.scrolling-direction-x{bottom:11px;height:10px}.scrolling-scrollbar.scrolling-direction-x .scrolling-scrollthumb{height:10px;min-width:37px;left:0;top:50%;margin-top:-5px}input[type=checkbox].ui-checkbox:not(.ui-toggle-switch){position:relative;height:32px;width:32px;box-sizing:border-box;outline:0;-webkit-appearance:none;margin:0 18px}@-webkit-keyframes checkbox-in{from{-webkit-mask-position:0 0;mask-position:0 0}to{-webkit-mask-position:100% 0;mask-position:100% 0}}@keyframes checkbox-in{from{-webkit-mask-position:0 0;mask-position:0 0}to{-webkit-mask-position:100% 0;mask-position:100% 0}}@-webkit-keyframes checkbox-out{from{-webkit-mask-position:100% 0;mask-position:100% 0}to{-webkit-mask-position:0 0;mask-position:0 0}}@keyframes checkbox-out{from{-webkit-mask-position:100% 0;mask-position:100% 0}to{-webkit-mask-position:0 0;mask-position:0 0}}input[type=checkbox].ui-checkbox::before{content:"";position:absolute;left:0;top:0;width:32px;height:32px;background-color:var(--ripple-color);border-radius:100%;opacity:0}input[type=checkbox].ui-checkbox::after{content:"";position:absolute;bottom:0;opacity:.8;background-color:var(--control-inactive-color);-webkit-animation-duration:250ms;animation-duration:250ms;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:steps(26);animation-timing-function:steps(26);width:100%;height:100%;-webkit-mask-image:url(images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg);mask-image:url(images/3_Controllers/Checkbox/sprites/sem_checkedtextview_check_to_on_mtrl_sprites.svg);-webkit-mask-size:auto 100%;mask-size:auto 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:0 0;mask-position:0 0}input[type=checkbox].ui-checkbox.ui-checkbox-backward-animation::after{-webkit-animation-name:checkbox-out;animation-name:checkbox-out}input[type=checkbox].ui-checkbox:checked::after{background-color:var(--control-active-color);-webkit-animation-name:checkbox-in;animation-name:checkbox-in}input[type=checkbox].ui-checkbox:active::before{opacity:1}input[type=checkbox].ui-checkbox:disabled{opacity:.4}input[type=checkbox].ui-checkbox.ui-checkbox-focus{outline:2px solid var(--primary-color)}@-webkit-keyframes radio-in{from{-webkit-mask-position:0 0;mask-position:0 0}to{-webkit-mask-position:100% 0;mask-position:100% 0}}@keyframes radio-in{from{-webkit-mask-position:0 0;mask-position:0 0}to{-webkit-mask-position:100% 0;mask-position:100% 0}}@-webkit-keyframes radio-out{from{-webkit-mask-position:100% 0;mask-position:100% 0}to{-webkit-mask-position:0 0;mask-position:0 0}}@keyframes radio-out{from{-webkit-mask-position:100% 0;mask-position:100% 0}to{-webkit-mask-position:0 0;mask-position:0 0}}input[type=radio].ui-radio{position:relative;height:32px;width:32px;box-sizing:border-box;outline:0;-webkit-appearance:none;margin:0 18px}input[type=radio].ui-radio::before{content:"";position:absolute;left:0;top:0;width:32px;height:32px;background-color:var(--ripple-color);border-radius:100%;opacity:0}input[type=radio].ui-radio::after{content:"";position:absolute;bottom:0;opacity:.8;background-color:var(--control-inactive-color);-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-duration:250ms;animation-duration:250ms;-webkit-animation-timing-function:steps(26);animation-timing-function:steps(26);width:100%;height:100%;-webkit-mask-image:url(images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg);mask-image:url(images/3_Controllers/Radio/sprites/sem_btn_radio_to_on_mtrl_sprites.svg);-webkit-mask-size:auto 100%;mask-size:auto 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:0 0;mask-position:0 0}input[type=radio].ui-radio.ui-radio-backward-animation::after{-webkit-animation-name:radio-out;animation-name:radio-out}input[type=radio].ui-radio:checked::after{background-color:var(--control-active-color);-webkit-animation-name:radio-in;animation-name:radio-in}input[type=radio].ui-radio:active::before{opacity:1}input[type=radio].ui-radio:disabled{opacity:.4}@-webkit-keyframes EXPAND{0%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}50%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.3);-ms-transform:translate(-50%,-50%) scale(1.3);transform:translate(-50%,-50%) scale(1.3)}100%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1.3);-ms-transform:translate(-50%,-50%) scale(1.3);transform:translate(-50%,-50%) scale(1.3)}}@keyframes EXPAND{0%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}50%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.3);-ms-transform:translate(-50%,-50%) scale(1.3);transform:translate(-50%,-50%) scale(1.3)}100%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1.3);-ms-transform:translate(-50%,-50%) scale(1.3);transform:translate(-50%,-50%) scale(1.3)}}.ui-text-input-container{width:100%}textarea.ui-text-input{resize:none;overflow:hidden;white-space:normal;transition:height 200ms linear}.ui-group-index+.ui-li-static input.ui-text-input,.ui-group-index+.ui-li-static textarea.ui-text-input{padding:0 13px 0 5px}.ui-group-index+.ui-li-static input.ui-text-input+.ui-text-input-textline,.ui-group-index+.ui-li-static textarea.ui-text-input+.ui-text-input-textline{margin:5.5px 8px 10px 0}.ui-group-index+.ui-li-static input.ui-text-input~.ui-text-input-clear,.ui-group-index+.ui-li-static textarea.ui-text-input~.ui-text-input-clear{right:0}.ui-group-index+.ui-li-static input.ui-text-input:focus.ui-text-input-clear-active,.ui-group-index+.ui-li-static textarea.ui-text-input:focus.ui-text-input-clear-active{padding-right:40px}.ui-li-static input.ui-text-input+.ui-text-input-textline,.ui-li-static textarea.ui-text-input+.ui-text-input-textline{position:absolute;width:calc(100% - 32px)}.ui-li-static input.ui-text-input+.ui-text-input-textline+.ui-text-input-error-message,.ui-li-static textarea.ui-text-input+.ui-text-input-textline+.ui-text-input-error-message{margin:8px 0 0}.ui-li-flex input.ui-text-input,.ui-li-flex textarea.ui-text-input{padding:0 5px}.ui-li-flex input.ui-text-input+.ui-text-input-textline,.ui-li-flex textarea.ui-text-input+.ui-text-input-textline{margin:5.5px 0 -6px 0}.ui-li-flex input.ui-text-input~.ui-text-input-clear,.ui-li-flex textarea.ui-text-input~.ui-text-input-clear{top:0;margin-top:-35px;margin-bottom:-6px;right:0}.ui-popup textarea.ui-text-input{min-height:27px;padding:0}.ui-popup textarea.ui-text-input+.ui-text-input-textline{margin-left:0;margin-right:0;margin-bottom:5.5px}input.ui-text-input,textarea.ui-text-input{border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;box-sizing:border-box;display:block;width:100%;line-height:26px;font-family:Roboto-Regular;-webkit-text-fill-color:transparent;font-size:19px;background-color:transparent;border:0;caret-color:var(--primary-color);margin:8px 0}input.ui-text-input.ui-text-input-disabled,textarea.ui-text-input.ui-text-input-disabled,input.ui-text-input:disabled,textarea.ui-text-input:disabled{text-shadow:0 0 0 var(--text-input-disabled)}input.ui-text-input.ui-text-input-disabled::-webkit-input-placeholder,textarea.ui-text-input.ui-text-input-disabled::-webkit-input-placeholder,input.ui-text-input:disabled::-webkit-input-placeholder,textarea.ui-text-input:disabled::-webkit-input-placeholder{text-shadow:0 0 0 var(--text-input-disabled)}input.ui-text-input:not([disabled]),textarea.ui-text-input:not([disabled]){text-shadow:0 0 0 var(--text-color)}input.ui-text-input:not([disabled])::-webkit-input-placeholder,textarea.ui-text-input:not([disabled])::-webkit-input-placeholder{text-shadow:0 0 0 var(--text-input-underline-inactive)}input.ui-text-input+.ui-text-input-textline,textarea.ui-text-input+.ui-text-input-textline{height:1px;background:var(--text-input-underline-inactive);box-sizing:border-box;display:block}input.ui-text-input+.ui-text-input-textline+.ui-text-input-error-message,textarea.ui-text-input+.ui-text-input-textline+.ui-text-input-error-message{display:none;color:var(--text-input-invalid-color);font-size:12px}input.ui-text-input:focus,textarea.ui-text-input:focus{outline:0}input.ui-text-input:focus.ui-text-input-clear-active,textarea.ui-text-input:focus.ui-text-input-clear-active{padding-right:11px}input.ui-text-input:focus+.ui-text-input-textline,textarea.ui-text-input:focus+.ui-text-input-textline{height:2px;background:var(--primary-color)}input.ui-text-input:invalid+.ui-text-input-textline,textarea.ui-text-input:invalid+.ui-text-input-textline{background:var(--text-input-invalid-color)}input.ui-text-input:invalid+.ui-text-input-textline+.ui-text-input-error-message,textarea.ui-text-input:invalid+.ui-text-input-textline+.ui-text-input-error-message{display:block}input.ui-text-input~.ui-text-input-clear,textarea.ui-text-input~.ui-text-input-clear{display:block;float:right;top:-33.5px;box-sizing:border-box;margin-right:-8.5px;margin-left:8.5px;position:relative;width:40px;height:40px}input.ui-text-input~.ui-text-input-clear.ui-btn.ui-btn-icon.ui-btn-nobg::after,textarea.ui-text-input~.ui-text-input-clear.ui-btn.ui-btn-icon.ui-btn-nobg::after{-webkit-mask-image:url(images/controls/core_button_icon_clear.png);mask-image:url(images/controls/core_button_icon_clear.png);width:40px;height:40px}input.ui-text-input~.ui-text-input-clear-hidden,textarea.ui-text-input~.ui-text-input-clear-hidden{visibility:hidden}input.ui-text-input.ui-text-input-widget-focused,textarea.ui-text-input.ui-text-input-widget-focused{background-color:var(--textual-background)}.ui-textinput-box-with-right-button{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;-o-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;height:40px}.ui-textinput-box-with-right-button>*{height:33.5px;margin-top:3.5px;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item),.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item),.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg{max-width:64px;min-width:40px;-ms-flex-basis:auto;-o-flex-basis:auto;-webkit-flex-basis:auto;-ms-flex-preferred-size:auto;flex-basis:auto;-webkit-order:1;-moz-order:1;-ms-order:1;-o-order:1;-ms-flex-order:1;order:1;width:auto;box-sizing:content-box;margin:0 10px 0 0;height:40px;min-height:40px;max-height:40px;padding:0 6px;background-color:transparent;overflow-x:visible;overflow-y:visible;color:#52c7d9;-webkit-mask-box-image-source:none;-webkit-align-self:flex-start;-ms-align-self:flex-start;-o-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::after,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::after,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg::after,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg::after{background-color:#52c7d9}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg::before,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg::before{background-color:var(--ripple-color);opacity:0}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active::before,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active::before,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-active::before,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-active::before{-webkit-animation:EXPAND 200ms;animation:EXPAND 200ms;-webkit-animation-fill-mode:both;animation-fill-mode:both;opacity:0}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon{padding:0 8.5px;margin-right:0}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::before,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::before,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon::before,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon::before{border-radius:20px;width:40px}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::after,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-icon::after,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-icon::after,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-icon::after{-webkit-mask-size:40px,40px;-moz-mask-size:40px,40px;-ms-mask-size:40px,40px;-o-mask-size:40px,40px;mask-size:40px,40px;-webkit-mask-repeat:none;-moz-mask-repeat:none;-ms-mask-repeat:none;-o-mask-repeat:none;mask-repeat:none;-webkit-mask-position:center center;-moz-mask-position:center center;-ms-mask-position:center center;-o-mask-position:center center;mask-position:center center}.ui-textinput-box-with-right-button button.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-text-light::before,.ui-textinput-box-with-right-button a.ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-text-light::before,.ui-textinput-box-with-right-button button .ui-btn.ui-btn-nobg.ui-btn-text-light::before,.ui-textinput-box-with-right-button a .ui-btn.ui-btn-nobg.ui-btn-text-light::before{border-radius:5px;width:58px;height:32.5px}.ui-textinput-box-with-right-button input.ui-text-input~.ui-text-input-clear{right:5px;left:5px}.ui-textinput-box-with-right-button input.ui-text-input:focus.ui-text-input-clear-active{padding-right:20px;margin-right:-15px}.ui-listview li.ui-textinput-box-with-right-button{padding-right:0}.ui-controlgroup .ui-radio>.ui-btn{background:var(--background-color)}.ui-controlgroup .ui-btn-inner.ui-corner-left{border-radius:0;background-clip:padding-box}.ui-controlgroup .ui-btn-inner.ui-corner-right.ui-controlgroup-last{border-radius:0;background-clip:padding-box}.ui-controlgroup .ui-radio-on .ui-btn-inner{color:#3b7796}.ui-controlgroup .ui-radio-off .ui-btn-inner{color:#c7c7c7}.ui-controlgroup.ui-controlgroup-horizontal .ui-radio-on .ui-btn-inner{color:#fafafa}.ui-page{border-top:0;background:var(--background-color);color:var(--text-color);font-weight:400;font-family:Roboto-Regular}.ui-page .ui-link-inherit{color:#fff}.ui-page .ui-link{color:#2489CE;font-weight:700}.ui-page .ui-link:hover{color:#2489CE}.ui-page .ui-link:active{color:#2489CE}.ui-page .ui-link:visited{color:#2489CE}a.ui-link-inherit{text-decoration:none!important}.ui-btn-active{color:var(--primary-color);cursor:pointer;text-decoration:none;background:var(--on-background);outline:0}.ui-btn-active a.ui-link-inherit{color:var(--primary-color)}.ui-corner-tl{border-top-left-radius:.3em}.ui-corner-tr{border-top-right-radius:.3em}.ui-corner-bl{border-bottom-left-radius:.3em}.ui-corner-br{border-bottom-right-radius:.3em}.ui-corner-top{border-top-left-radius:.3em;border-top-right-radius:.3em}.ui-corner-bottom{border-bottom-left-radius:.3em;border-bottom-right-radius:.3em}.ui-corner-right{border-top-right-radius:.3em;border-bottom-right-radius:.3em}.ui-corner-left{border-top-left-radius:.3em;border-bottom-left-radius:.3em}.ui-corner-none{border-radius:0}.ui-btn .ui-icon.ui-icon-naviframe-edit,.ui-btn .ui-icon.ui-icon-naviframe-plus,.ui-btn .ui-icon.ui-icon-naviframe-delete,.ui-btn .ui-icon.ui-icon-naviframe-search,.ui-btn .ui-icon.ui-icon-naviframe-selectall,.ui-btn .ui-icon.ui-icon-naviframe-drawer{-webkit-mask-size:100%;-moz-mask-size:100%;-ms-mask-size:100%;-o-mask-size:100%;mask-size:100%}.ui-popup.ui-ctxpopup{width:auto;padding:0;background-color:transparent;margin-top:0;max-width:100%}.ui-popup.ui-ctxpopup .ui-popup-content{width:auto;padding:0;overflow:hidden}.ui-popup.ui-ctxpopup .ui-popup-content>ul{overflow:auto}.ui-popup.ui-ctxpopup .ui-popup-content>ul::-webkit-scrollbar{height:4px}.ui-popup.ui-ctxpopup .ui-popup-content>ul::-webkit-scrollbar-thumb{background-color:var(--primary-color);border-radius:1.5px;border-bottom:1px solid #fff}.ui-popup.ui-ctxpopup .ui-popup-content>ul::-webkit-scrollbar-button{width:2px;height:4px;background-color:transparent}.ui-popup.ui-ctxpopup .ui-popup-wrapper{background-color:var(--more-options-background-color);border:1px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none;overflow:auto;margin-left:16px;margin-right:16px;width:auto}.ui-popup.ui-ctxpopup :focus{outline:0}.ui-popup.ui-ctxpopup.slideup.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:slideupfadeinfrombottom 250ms;animation:slideupfadeinfrombottom 250ms}.ui-popup.ui-ctxpopup.slideup.out{-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0);-webkit-animation:slideupfadeouttobottom 200ms;animation:slideupfadeouttobottom 200ms}.ui-popup.ui-ctxpopup .ui-listview{margin:0;border:0;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-popup.ui-ctxpopup .ui-listview li{-webkit-flex:1 0 auto;-moz-flex:1 0 auto;-ms-flex:1 0 auto;-o-flex:1 0 auto;flex:1 0 auto}.ui-popup.ui-ctxpopup .ui-listview .ui-li-anchor a{font-size:15px;line-height:20.5px;padding:0 16px;min-height:36px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview{-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview .ui-li-anchor a{height:40px;-webkit-flex-direction:row;-moz-flex-direction:row;-ms-flex-direction:row;-o-flex-direction:row;flex-direction:row;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:flex-start;-moz-justify-content:flex-start;-ms-justify-content:flex-start;-o-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;text-align:left;padding-top:0;padding-bottom:0}.ui-popup.ui-ctxpopup .ui-listview li{color:var(--text-color);font-size:15px;border-top:0;border-bottom:0;border-right:0;border-left:1px solid var(--more-options-background-color)}.ui-popup.ui-ctxpopup .ui-listview li:first-of-type{border-left-width:0}.ui-popup.ui-ctxpopup .ui-listview li.ui-li-anchor>a{box-sizing:border-box;padding-top:7.5px;padding-bottom:7.5px}.ui-popup.ui-ctxpopup .ui-listview li.ui-li-anchor.ui-li-active{background-color:var(--more-options-pressed-color)}.ui-popup.ui-ctxpopup.ui-ctxpopup-basic .ui-li-anchor{padding:0 16px;height:36px}.ui-popup.ui-ctxpopup.ui-ctxpopup-basic .ui-li-anchor>a{padding:0;margin:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor{padding:0;height:40px;width:53px}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor>a{padding:0;margin:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons .ui-li-anchor>a>span{padding:0;margin:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor{padding:0 16px;height:59px}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor>a{padding:0;margin:0;font-size:13px;line-height:20px}.ui-popup.ui-ctxpopup.ui-ctxpopup-icons-text .ui-li-anchor>a>span{padding:0;margin:0 0 2px}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li{border-top:1px solid var(--more-options-background-color);border-bottom:0;border-right:0;border-left:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li:first-of-type{border-top-width:0}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li.ui-li-anchor{padding:0 12px;height:40px}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-listview li.ui-li-anchor>a{margin:0;padding:0;overflow:visible}.ui-popup.ui-ctxpopup.ui-ctxpopup-vertical .ui-icon{display:inline-block;vertical-align:middle;margin-top:0;margin-bottom:0;margin-right:10px;margin-left:-2px}.ui-popup.ui-ctxpopup .ui-icon{width:20px;height:20px;display:block;vertical-align:middle;margin:2px auto}.ui-text-ellipsis{white-space:nowrap;text-overflow:ellipsis;-o-text-overflow:ellipsis;overflow:hidden!important}.ui-popup.ui-popup-toast{background-color:transparent;margin:0 auto;position:relative;bottom:0;width:100%}.ui-popup.ui-popup-toast .ui-popup-content{margin:auto;margin-bottom:64px;width:-webkit-fit-content;width:fit-content;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;border-radius:22px;background-color:var(--toast-background);padding:12px 20px;line-height:20px;color:var(--toast-text-color);font-size:16px;font-family:Roboto-Regular}@media all and (max-width:479px){.ui-popup.ui-popup-toast .ui-popup-content{max-width:84%}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button{width:84%}}@media all and (min-width:480px) and (max-width:959px){.ui-popup.ui-popup-toast .ui-popup-content{max-width:68%}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button{width:68%}}@media all and (min-width:960px) and (max-width:1919px){.ui-popup.ui-popup-toast .ui-popup-content{max-width:37.5%}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button{width:37.5%}}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button{text-align:left;min-height:44px;padding:0 20px;background-color:var(--btn-toast-background)}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn{padding:4px 0 4px 20px;margin:0;width:-webkit-fit-content;width:fit-content;color:var(--btn-toast-text-color);font-size:18px;font-family:Roboto-Medium;background-color:transparent;line-height:36px;overflow:visible}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item){background-color:transparent;border:0;border-radius:0;padding-right:20px;margin-right:-20px}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item)::before{background-color:var(--ripple-color)}.ui-popup.ui-popup-toast .ui-popup-content.ui-popup-toast-has-button .ui-btn:not(.ui-btn-circle):not(.ui-btn-nobg):not(.ui-floatingactions-item).ui-btn-active{background-color:transparent}.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content{display:block;padding:12px 20px}.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content.ui-popup-toast-has-button{padding-top:9px;padding-bottom:4px}.ui-popup.ui-popup-toast.ui-popup-toast-multiline .ui-popup-content.ui-popup-toast-has-button .ui-btn{margin-left:auto;padding-top:5px;padding-bottom:0}@-webkit-keyframes ui-smallpopup-show{from{display:none;opacity:0;-webkit-transform:scaleY(0);-ms-transform:scaleY(0);transform:scaleY(0)}to{display:block;opacity:1;-webkit-transform:scaleY(1);-ms-transform:scaleY(1);transform:scaleY(1)}}@keyframes ui-smallpopup-show{from{display:none;opacity:0;-webkit-transform:scaleY(0);-ms-transform:scaleY(0);transform:scaleY(0)}to{display:block;opacity:1;-webkit-transform:scaleY(1);-ms-transform:scaleY(1);transform:scaleY(1)}}.ui-smallpopup{position:fixed;display:none;margin-bottom:32px;max-width:236px;z-index:1100;vertical-align:middle;font-size:16px;word-break:break-all}.ui-smallpopup::before{position:absolute;content:'';width:100%;height:100%}.ui-smallpopup.fix{display:block}.ui-smallpopup.show{display:block;-webkit-animation:ui-smallpopup-show 500ms 1 ease;animation:ui-smallpopup-show 500ms 1 ease}.ui-smallpopup.hide{display:none}.ui-smallpopup-text-bg{position:relative;padding:3.5px 12px 5px;line-height:18.5px;margin:0;color:var(--toast-text-color);font-size:16px}.ui-popup{display:none;position:absolute;left:0;margin-bottom:16px;margin-top:32px;z-index:1201!important;background-color:var(--popup-background);border-radius:26px}@media (max-width:479px){.ui-popup{width:100%}}@media (min-width:480px) and (max-width:672px){.ui-popup{width:63%}}@media (min-width:673px) and (max-width:985px){.ui-popup{width:55%}}@media (min-width:986px){.ui-popup{width:35%}}.ui-popup .ui-popup-wrapper{width:100%}.ui-popup.ui-popup-active{display:block}.ui-popup.in{display:block}.ui-popup.ui-build{display:block;visibility:hidden}.ui-popup .ui-popup-header{width:100%;text-align:left;background-color:var(--popup-background);position:-webkit-sticky;position:sticky;font-size:20px;color:var(--text-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:Roboto-Medium}.ui-popup .ui-popup-header::after{content:"";position:absolute;left:24px;width:calc(100% - 48px);height:.75px;stroke-width:.5;visibility:hidden;background-color:var(--popup-scroll-divider-color)}@media (orientation:portrait){.ui-popup .ui-popup-header::after{top:68px}}@media (orientation:landscape){.ui-popup .ui-popup-header::after{top:45px}}.ui-popup .ui-popup-header.topDivider::after{visibility:visible}.ui-popup .ui-popup-header.ui-popup-header-has-subtitle{padding:9.75px 16px;line-height:28.5px;font-size:20px;color:T1212}.ui-popup .ui-popup-header .ui-popup-subtitle{line-height:19px}@media (orientation:portrait){.ui-popup .ui-popup-header{padding:26px 24px 19px}}@media (orientation:landscape){.ui-popup .ui-popup-header{padding:14px 24px 8px}}.ui-popup .ui-popup-content{width:100%;background-color:var(--popup-background);color:var(--popup-text);text-align:left;font-size:16px;overflow:auto;-webkit-overflow-scrolling:touch;-moz-overflow-scrolling:touch;-o-overflow-scrolling:touch;-ms-overflow-scrolling:touch;overflow-scrolling:touch;line-height:23px}.ui-popup .ui-popup-content img{display:block;margin:0 auto;padding-bottom:12px}.ui-popup .ui-popup-content.ui-date-picker-calendar{padding-left:16px;padding-right:16px}.ui-popup .ui-popup-content .ui-popup-body-text{margin-top:8px}.ui-popup .ui-popup-content .ui-popup-body-checkbox{margin-top:8px;height:32px;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-popup .ui-popup-content .ui-popup-body-checkbox input[type=Checkbox]{margin:0 12px 0 -4px}.ui-popup .ui-popup-content .ui-popup-body-checkbox span{margin-top:5px}.ui-popup .ui-popup-content ul .ui-li-has-checkbox .ui-li-text span{font-size:18px}.ui-popup .ui-popup-content ul .ui-li-has-checkbox input{margin-left:18px;margin-right:18px}.ui-popup .ui-popup-content .ui-popup-container-text{width:100%;height:19px;line-height:19px;color:var(--popup-text-color);font-size:14px;font-family:Roboto-Regular}.ui-popup .ui-popup-content .ui-popup-container-text .text-left{float:left}.ui-popup .ui-popup-content .ui-popup-container-text .text-right{float:right}@media (orientation:portrait){.ui-popup .ui-popup-content{padding:0 24px;margin-bottom:24px}}@media (orientation:landscape){.ui-popup .ui-popup-content{padding:0 24px;margin-bottom:11px}}.ui-popup .ui-popup-content.ui-popup-has-time-picker,.ui-popup .ui-popup-content.ui-popup-has-date-picker{padding-left:unset;padding-right:unset}.ui-popup .ui-popup-footer{background-color:var(--popup-background);position:-webkit-sticky;position:sticky;box-sizing:border-box;padding:12px 24px;text-align:center;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;width:100%}.ui-popup .ui-popup-footer::before{content:"";position:absolute;left:24px;width:calc(100% - 48px);height:.75px;stroke-width:.5;visibility:hidden;background-color:var(--popup-scroll-divider-color)}@media (orientation:portrait){.ui-popup .ui-popup-footer::before{bottom:80px}}@media (orientation:landscape){.ui-popup .ui-popup-footer::before{bottom:50px}}.ui-popup .ui-popup-footer.bottomDivider::before{visibility:visible}.ui-popup .ui-popup-footer .ui-btn{height:36px;margin:0 auto;max-width:248px}.ui-popup .ui-popup-footer .ui-btn.ui-btn-flat{font-size:16px}.ui-popup .ui-popup-footer div.ui-li-divider::after{content:"";position:absolute;width:1px;height:16px;top:10px;background-color:var(--popup-footer-divider-color)}.ui-popup .ui-popup-footer .ui-popup-stack .ui-btn{margin-bottom:16px}.ui-popup .ui-popup-footer .ui-popup-stack .ui-btn:nth-last-child(1){margin-bottom:0}.ui-popup .ui-popup-footer .ui-li-action{width:50%}@media (orientation:portrait){.ui-popup .ui-popup-footer{padding:0 24px 20px}}@media (orientation:landscape){.ui-popup .ui-popup-footer{padding:0 24px 4px}}.ui-popup .ui-listview{margin-left:-24px}@media (orientation:portrait){.ui-popup .ui-popup-notitle{margin-top:26px}}@media (orientation:landscape){.ui-popup .ui-popup-notitle{margin-top:14px}}.ui-popup .ui-popup-2level-description{height:auto;margin-top:8px;margin-left:8px;color:var(--popup-text-secondary-color)}.ui-popup .ui-popup-2level-description span{padding-right:12px}.ui-popup .ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a{margin-top:14px;margin-bottom:14px}.ui-popup .ui-popup-header,.ui-popup .ui-popup-content,.ui-popup .ui-popup-footer{box-sizing:border-box}.ui-popup.ui-popup-listview{background-image:url(images/page/core_theme_bg_01.png);background-repeat:no-repeat;background-size:100% 100%;overflow:hidden;background-color:transparent}.ui-popup.ui-popup-listview .ui-popup-header{padding-top:8px;padding-bottom:8px}.ui-popup.ui-popup-listview .ui-popup-content{padding:0;background-color:transparent;position:relative}.ui-popup.ui-popup-listview .ui-listview{position:relative;overflow:hidden;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui-popup.ui-popup-listview .ui-listview::before{content:"";background-color:var(--overlay);width:100%;height:100%;display:block;position:absolute;top:0;z-index:1;pointer-events:none}.ui-popup.ui-popup-moremenu{max-height:420px;overflow:hidden}@media (orientation:landscape){.ui-popup.ui-popup-moremenu{max-height:300px;width:360px}}.ui-popup-overlay{display:none;background-color:var(--overlay);background-repeat:no-repeat;background-size:100% 100%;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1200}.ui-popup-overlay.ui-popup-overlay-shown{display:block}.ui-popup.ui-popup-activity .ui-popup-content{text-align:right}@media (orientation:landscape){.ui-popup.ui-popup-activity .ui-popup-content{width:100%}}@-webkit-keyframes popup-activity{from{-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes popup-activity{from{-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(360deg);-ms-transform:rotate(360deg);transform:rotate(360deg)}}@media (orientation:landscape){.ui-popup.ui-popup-activity{width:100%}}.ui-popup.ui-popup-activity.ui-popup-activity-small .ui-popup-content{text-align:right;height:39px;padding:8px 16px;font-size:20px;color:T120L1}.ui-popup.ui-popup-activity.ui-popup-activity-small .ui-popup-content::after{content:"";width:22px;height:22px;margin-left:16px;background-color:W157E1;-webkit-mask-image:url(images/core_activity_indicator_a.svg),url(images/core_activity_indicator_b.svg),url(images/core_activity_indicator_c.svg);mask-image:url(images/core_activity_indicator_a.svg),url(images/core_activity_indicator_b.svg),url(images/core_activity_indicator_c.svg);-webkit-mask-size:100% 100%,100% 100%,100% 100%;mask-size:100% 100%,100% 100%,100% 100%;float:right;-webkit-animation-name:popup-activity;animation-name:popup-activity;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.ui-popup.ui-popup-activity.ui-popup-activity-medium .ui-popup-content{text-align:left;height:60px;padding:16px;font-size:20px;color:T120L2}.ui-popup.ui-popup-activity.ui-popup-activity-medium .ui-popup-content::before{content:"";width:28px;height:28px;margin-right:16px;background-color:W157E1;float:left;-webkit-mask-image:url(images/core_activity_indicator_a.svg),url(images/core_activity_indicator_b.svg),url(images/core_activity_indicator_c.svg);mask-image:url(images/core_activity_indicator_a.svg),url(images/core_activity_indicator_b.svg),url(images/core_activity_indicator_c.svg);-webkit-mask-size:100% 100%,100% 100%,100% 100%;mask-size:100% 100%,100% 100%,100% 100%;-webkit-animation-name:popup-activity;animation-name:popup-activity;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-timing-function:linear;animation-timing-function:linear;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.ui-popup.ui-popup-activity.ui-popup-activity-large .ui-popup-content{text-align:center;height:0;background-color:W157E1;-webkit-mask-image:url(images/core_activity_indicator_c.svg);mask-image:url(images/core_activity_indicator_c.svg);-webkit-mask-size:100% 100%;mask-size:100% 100%}.ui-popup:not(.ui-ctxpopup).slideup.out{-webkit-animation:popupslideouttobottom 400ms ease-out;animation:popupslideouttobottom 400ms ease-out}.ui-popup:not(.ui-ctxpopup).slideup.in{-webkit-animation:popupslideinfrombottom 400ms ease-out;animation:popupslideinfrombottom 400ms ease-out}.ui-popup.slideup.in:not(.ui-ctxpopup) .ui-popup-wrapper{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%);-webkit-animation:popupwrapperslideinfrombottom 350ms ease-out 50ms;animation:popupwrapperslideinfrombottom 350ms ease-out 50ms}.ui-popup.slideup.out:not(.ui-ctxpopup) .ui-popup-wrapper{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px);-webkit-animation:popupwrapperslideouttobottom 4000ms ease-out;animation:popupwrapperslideouttobottom 4000ms ease-out}.ui-popup-overlay.slideup.in:not(.ui-ctxpopup-overlay){-webkit-animation:popupoverlayfadein 400ms ease-out;animation:popupoverlayfadein 400ms ease-out}.ui-popup-overlay.slideup.out:not(.ui-ctxpopup-overlay){-webkit-animation:popupoverlayfadeout 400ms ease-out;animation:popupoverlayfadeout 400ms ease-out}@-webkit-keyframes popupslideouttobottom{from{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}to{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}}@keyframes popupslideouttobottom{from{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}to{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}}@-webkit-keyframes popupslideinfrombottom{from{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@keyframes popupslideinfrombottom{from{-webkit-transform:translateY(100%);-ms-transform:translateY(100%);transform:translateY(100%)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@-webkit-keyframes popupwrapperslideinfrombottom{from{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@keyframes popupwrapperslideinfrombottom{from{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px)}to{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}}@-webkit-keyframes popupwrapperslideouttobottom{from{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}to{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px)}}@keyframes popupwrapperslideouttobottom{from{-webkit-transform:translateY(0%);-ms-transform:translateY(0%);transform:translateY(0%)}to{-webkit-transform:translateY(25px);-ms-transform:translateY(25px);transform:translateY(25px)}}@-webkit-keyframes popupoverlayfadein{from{opacity:0}to{opacity:1}}@keyframes popupoverlayfadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes popupoverlayfadeout{from{opacity:1}to{opacity:0}}@keyframes popupoverlayfadeout{from{opacity:1}to{opacity:0}}.ui-scrollview-clip{display:block;position:relative;z-index:100;overflow-x:hidden;overflow-y:visible}.ui-scrollview-clip[data-scroll="x"]{-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory}.ui-scrollview-clip[data-scroll="x"] .ui-scrollview-view{overflow:initial}.ui-scrollview-view{overflow:hidden;min-height:100%;min-width:100%;box-sizing:border-box}.ui-scrolllistview .ui-li-divider{z-index:10}.ui-scrollbar{position:absolute;overflow:hidden;opacity:0}.ui-scrollbar-visible{opacity:1}.ui-scrollbar-y{top:0;right:1px;bottom:0;width:4px}.ui-scrollbar-x{right:1px;bottom:1px;left:1px;height:4px}.ui-scrollbar-track{position:relative;width:100%;height:100%}.ui-scrollbar-thumb{position:absolute;top:0;left:0;background-color:var(--primary-color)}.ui-scrollbar-y .ui-scrollbar-thumb{width:2.5px;height:100%;border-radius:1px;-o-box-shadow:.5px .5px 2px #080808;-ms-box-shadow:.5px .5px 2px #080808;box-shadow:.5px .5px 2px #080808}.ui-scrollbar-x .ui-scrollbar-thumb{width:100%;height:2.5px;border-radius:1px}.ui-scroll-jump-top-bg{position:absolute;top:4.5px;right:6.5px;width:18.5px;height:18.5px}.ui-scroll-jump-left-bg{position:absolute;bottom:4.5px;left:6.5px;width:18.5px;height:18.5px}.ui-overflow-indicator-top,.ui-overflow-indicator-bottom{position:absolute;display:none;width:100%;height:14.5px;opacity:1;background-repeat:no-repeat;background-size:100% 100%}.ui-overflow-indicator-top{top:0}.ui-overflow-indicator-bottom{bottom:0}.ui-overflow-effect-bottom{position:absolute;display:none;bottom:0;width:100%}.ui-overflow-top{opacity:1}.ui-overflow-top.ui-overflow-top-hide{height:0!important}.ui-overflow-bottom{opacity:1}.ui-overflow-bottom.ui-overflow-bottom-hide{height:0!important}.ui-content.ui-scrollview-clip{padding:0}.ui-content.ui-scrollview-clip>div.ui-scrollview-view{margin:0}.ui-content.ui-scrollview-clip>.ui-listview.ui-scrollview-view{margin:0}.ui-content.ui-scrollview-clip.ui-hide-scrollbar::-webkit-scrollbar{display:none}.ui-slider{position:relative;box-sizing:border-box;height:32px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:space-around;-ms-flex-pack:distribute;justify-content:space-around}.ui-slider .ui-slider-bar{background-color:var(--slider-bg-color);height:3px;border-radius:1.5px;overflow:hidden}.ui-slider .ui-slider-bar .ui-slider-value{height:100%;background-color:var(--slider-handler-color)}.ui-slider:focus{outline:0}.ui-slider .ui-slider-handler-track{position:absolute;width:100%;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-slider .ui-slider-handler-track .ui-slider-before-space{height:1px}.ui-slider .ui-slider-handler-track .ui-slider-after-space{height:1px}.ui-slider .ui-slider-handler{width:17px;height:17px;min-width:17px;min-height:17px;background-color:var(--slider-value-color);position:relative;border-radius:50%;pointer-events:none;z-index:9}.ui-slider .ui-slider-handler::before{content:"";width:32px;height:32px;opacity:0;position:absolute;left:-5px;top:-5px;border-radius:100%;background-color:var(--ripple-color)}.ui-slider.ui-slider-active .ui-slider-handler{min-width:22px;min-height:22px}.ui-slider.ui-slider-active .ui-slider-handler::before{opacity:1}.ui-slider.ui-disabled .ui-slider-bar{background-color:var(--slider-bg-disabled-color)}.ui-slider.ui-disabled .ui-slider-bar .ui-slider-value{background-color:var(--slider-handler-disabled-color)}.ui-slider.ui-disabled .ui-slider-handler{background-color:var(--slider-handler-disabled-color)}.ui-slider.ui-slider-level-bar{margin-left:5px;margin-right:5px;height:32px}.ui-slider.ui-slider-level-bar .ui-slider-bar{background-color:var(--slider-level-bar-bg-color)}.ui-slider.ui-slider-level-bar .ui-slider-bar .ui-slider-value{display:none}.ui-slider.ui-slider-level-bar .ui-slider-bar::before{display:none;border-image:none}.ui-slider.ui-slider-level-bar input{width:100%}.ui-slider.ui-slider-level-bar .ui-slider-scale{position:absolute;width:100%;height:7px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;pointer-events:none}.ui-slider.ui-slider-level-bar .ui-slider-scale .ui-slider-scale-dot{width:7px;height:7px;border-radius:100%;background-color:var(--slider-scale-dot)}.ui-slider.ui-slider-level-bar .ui-slider-handler-track{width:calc(100% + 10px);left:-5px}.ui-slider-label{font-size:12px;color:var(--text-secondary-color)}.ui-slider-label-min{position:absolute;left:0;bottom:-2px}.ui-slider-label-max{position:absolute;right:0;bottom:-2px}.ui-slider.ui-slider-has-labels{height:50px}input[data-tau-built=Slider]{opacity:0;display:block;width:100%;position:absolute;margin:0}tau-toggleswitch{display:block}.ui-toggle-container{position:relative;width:36px;height:36px}.ui-toggle-container .ui-switch-handler{position:absolute;width:100%;height:100%;top:0;left:0;background-color:transparent;pointer-events:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.ui-toggle-container .ui-switch-handler:before,.ui-toggle-container .ui-switch-handler:after{content:"";position:absolute;height:100%;width:100%;-webkit-mask-position:center center;mask-position:center center;-webkit-mask-size:100%;mask-size:100%}.ui-toggle-container .ui-switch-handler:before{background-color:W015L1i;-webkit-mask-image:url(images/controls/core_toggle_icon_off.svg);mask-image:url(images/controls/core_toggle_icon_off.svg);-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);transition:250ms ease-out 50ms}.ui-toggle-container .ui-switch-handler:after{background-color:W015L1i;-webkit-mask-image:url(images/controls/core_toggle_icon_on.svg);mask-image:url(images/controls/core_toggle_icon_on.svg);-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);transition:100ms ease-out}.ui-toggle-container input[type=checkbox].ui-toggle-switch{width:36px;height:36px;border-radius:50%;background-color:W015L1E1;-webkit-appearance:none;-moz-appearance:none;appearance:none;outline:0;margin:0;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px;transition:background-color 150ms}.ui-toggle-container input[type=checkbox].ui-toggle-switch::before{content:none}.ui-toggle-container input[type=checkbox].ui-toggle-switch:checked{background-color:var(--color-white)}.ui-toggle-container input[type=checkbox].ui-toggle-switch:checked~.ui-switch-handler::before{-webkit-transform:scale(0);-ms-transform:scale(0);transform:scale(0);transition:100ms ease-out}.ui-toggle-container input[type=checkbox].ui-toggle-switch:checked~.ui-switch-handler::after{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);transition:250ms ease-out 50ms}.ui-toggle-container input[type=checkbox].ui-toggle-switch:disabled{background-color:W015L1D}.ui-toggle-switch-focus{outline:2px solid var(--primary-color)}@-webkit-keyframes move-to-off{to{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes move-to-off{to{-webkit-transform:translateX(0);transform:translateX(0)}}@-webkit-keyframes move-to-on{to{-webkit-transform:translateX(17px);transform:translateX(17px)}}@keyframes move-to-on{to{-webkit-transform:translateX(17px);transform:translateX(17px)}}.ui-on-off-switch-container{position:relative;display:inline-block;width:43px;height:27px;max-width:43px;max-height:27px;min-width:43px;min-height:27px;overflow:hidden}.ui-on-off-switch-input{position:absolute;width:37px;height:18.5px;border-radius:9.25px;-webkit-appearance:none;display:block;margin:4.25px 3px;border:1px solid var(--on-off-switch-off-button-border);background-color:var(--on-off-switch-off-track-background);outline:0;box-sizing:border-box}.ui-on-off-switch-input:active~.ui-on-off-switch-button::before{opacity:1}.ui-on-off-switch-input:disabled{border-color:var(--on-off-switch-off-disabled-track-border)}.ui-on-off-switch-input:disabled~.ui-on-off-switch-button{border-color:var(--on-off-switch-off-disabled-button-border);background-color:var(--on-off-switch-on-disabled-button-background)}.ui-on-off-switch-button{width:22px;height:22px;border-radius:100%;margin:2.5px 2px;box-sizing:border-box;border:1px solid var(--on-off-switch-off-button-border);background-color:var(--color-white);position:absolute;top:0;left:0;pointer-events:none;z-index:1;transition:-webkit-transform cubic-bezier(0.6,.6,.8,1.49) 250ms;transition:transform cubic-bezier(0.6,.6,.8,1.49) 250ms;transition:transform cubic-bezier(0.6,.6,.8,1.49) 250ms, -webkit-transform cubic-bezier(0.6,.6,.8,1.49) 250ms;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui-on-off-switch-button::before{content:"";width:27px;height:27px;opacity:0;position:absolute;left:-3px;top:-3px;border-radius:100%;background-color:var(--ripple-color)}.ui-on-off-switch-button-on-drag{transition:none}.ui-on-off-switch-button-on-drag::before{opacity:1}.ui-on-off-switch-button-move-to-off{-webkit-animation:move-to-off 100ms ease-in-out 0s 1 normal both;animation:move-to-off 100ms ease-in-out 0s 1 normal both;transition:none}.ui-on-off-switch-button-move-to-on{-webkit-animation:move-to-on 100ms ease-in-out 0s 1 normal both;animation:move-to-on 100ms ease-in-out 0s 1 normal both;transition:none}.ui-on-off-switch-input:checked{background-color:var(--primary-color);border-color:var(--primary-color);width:37px;height:18.5px;margin:4.25px 3px}.ui-on-off-switch-input:checked:disabled{background-color:var(--on-off-switch-on-disabled-track-background);border-color:transparent}.ui-on-off-switch-input:checked:disabled~.ui-on-off-switch-button{border-color:var(--on-off-switch-on-disabled-button-border)}.ui-on-off-switch-input:checked~.ui-on-off-switch-button{border-color:var(--primary-color);-webkit-transform:translate3d(17px,0,0);transform:translate3d(17px,0,0)}.ui-master-on-off-switch{font-family:Roboto-Regular;font-size:18px;margin-left:0;margin-right:0;margin-bottom:20px;height:64px;position:relative}.ui-master-on-off-switch .ui-on-off-label{background-color:var(--master-on-off-off-color);position:absolute;left:0;right:0;width:100%;height:100%;border-radius:26px;box-sizing:border-box;padding-left:24px;padding-right:24px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-master-on-off-switch .ui-on-off-label::before{content:"";width:100%;height:64px;opacity:0;position:absolute;left:0;top:0;border-radius:26px;background-color:var(--ripple-color)}.ui-master-on-off-switch .ui-on-off-label-active::before{opacity:1}.ui-master-on-off-switch .ui-on-off-label span{-webkit-flex:1;-ms-flex:1;flex:1}.ui-master-on-off-switch .ui-on-off-label-on{color:var(--color-white);background-color:var(--master-on-off-on-color)}.ui-master-on-off-switch .ui-on-off-switch-input:active~.ui-on-off-switch-button::before{opacity:0}.ui-sub-tab{display:-webkit-flex;display:-ms-flexbox;display:flex;width:calc(100% - 48px);height:56px;margin-left:24px;margin-right:24px;background-color:var(--sub-tab-bg-color)}.ui-sub-tab a{font-family:Roboto-Regular;font-size:15px;line-height:22px;padding-left:12px;padding-right:12px;color:var(--sub-tab-text-color);border-radius:18px;box-sizing:border-box;border:0 solid var(--sub-tab-border-color);display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;width:100%;min-height:36px;text-decoration:none}.ui-sub-tab a span{position:relative;-webkit-order:1;-ms-flex-order:1;order:1;height:100%;overflow-x:hidden;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-sub-tab a.ui-tab-active{font-family:Roboto-Medium;color:var(--sub-tab-active-text-color);border-width:1px}.ui-sub-tab a.ui-sub-tab-inactive-text-overflow span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-sub-tab a::before{content:"";width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;background-color:var(--ripple-color);border-radius:26px}.ui-sub-tab a.ui-btn-active{background-color:inherit}.ui-sub-tab a.ui-btn-active::before{-webkit-animation:animation_opacity_in linear 100ms,animation_opacity_out linear 400ms 100ms;animation:animation_opacity_in linear 100ms,animation_opacity_out linear 400ms 100ms}.ui-sub-tab ul{display:-webkit-flex;display:-ms-flexbox;display:flex;margin:0;padding:0;list-style:none;position:relative;height:100%;white-space:nowrap;font-size:0}.ui-sub-tab li{text-align:center;margin:auto 0}.ui-sub-tab:not(.ui-sub-tab-static) ul li{min-width:105px}.ui-sub-tab:not(.ui-sub-tab-static).ui-sub-tab-landscape ul li{min-width:135px}.ui-main-tab{display:none;width:calc(100% - 32px);height:60px;margin-left:16px;margin-right:16px;background-color:var(--bottom-bar-color);position:fixed;bottom:0}.ui-main-tab-visible{display:block}.ui-main-tab a{font-family:Roboto-Regular;font-size:15px;line-height:22px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;position:relative;left:0;top:0;height:100%;text-decoration:none;color:var(--tab-text-color);padding-left:10px;padding-right:10px}.ui-main-tab a>span,.ui-main-tab a>div{position:relative;-webkit-order:1;-ms-flex-order:1;order:1;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding-bottom:4px;overflow:hidden}.ui-main-tab a>span::before,.ui-main-tab a>div::before{content:"";position:absolute;width:100%;height:4px;border-bottom:2.5px dotted var(--primary-dark-color);bottom:.75px;box-sizing:border-box;opacity:0}.ui-main-tab a.ui-tab-active{color:var(--primary-dark-color);font-family:Roboto-Medium}.ui-main-tab a.ui-tab-active>span::before,.ui-main-tab a.ui-tab-active>div::before{opacity:1}.ui-main-tab a:disabled{color:var(--tab-text-color-dim)}.ui-main-tab a::before{content:"";width:100%;height:43px;top:8.5px;border-radius:26px;left:0;position:absolute;opacity:0;background-color:var(--ripple-color)}.ui-main-tab a.ui-btn-active{background-color:transparent}.ui-main-tab a.ui-btn-active::before{opacity:1}.ui-main-tab ul{margin:0;padding:0;list-style:none;position:relative;height:100%;white-space:nowrap;font-size:0;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-main-tab li{text-align:center;display:block;position:relative;overflow:hidden;height:100%;-webkit-flex:1;-ms-flex:1;flex:1}.ui-main-tab .ui-li-active a::before{opacity:1}.ui-main-tab .ui-tabs-badge{position:absolute;border-radius:25px;min-width:12px;background-color:var(--accent-badge);color:var(--color-white);top:1px;right:7px;text-align:center;padding:3.5px 7.5px;font-family:Roboto-Medium;font-size:11px}.ui-marquee-content::after{content:attr(title);text-indent:75px;position:absolute;display:none}.ui-marquee-content.ui-visible{padding-right:75px}.ui-marquee-content.ui-visible::after{display:inline}.ui-footer{padding:0;z-index:100}.ui-footer .ui-bottom-bar{display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;min-height:56px;background-color:var(--bottom-bar-color);padding:0 24px}.ui-footer .ui-bottom-bar .ui-btn{font-family:Roboto-Medium;font-size:18px;text-align:center;line-height:18px;max-width:100%;height:56px}.ui-footer .ui-bottom-bar .ui-btn.ui-btn~.ui-btn{margin-left:0}.ui-footer .ui-bottom-bar .ui-btn.ui-btn-icon{font-family:Roboto-Regular;font-size:12px;line-height:normal;max-width:100%}.ui-footer .ui-bottom-bar .ui-btn.ui-btn-icon-top~.ui-btn-icon-top{margin-left:10px}.ui-footer .ui-bottom-bar .ui-btn.ui-btn-text{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-footer .ui-bottom-bar.ui-bottom-bar-icons{padding:0 10px}.ui-footer .ui-bottom-bar.ui-hidden{display:none}@media all and (min-width:673px) and (min-height:411px){.ui-footer .ui-bottom-bar{margin:0 auto;width:75%;min-width:625px}.ui-footer .ui-bottom-bar.ui-bottom-bar-icons{min-width:653px}}.ui-tokentextarea{display:table;outline:0;position:relative;background-color:W010;margin-left:-7.5px;margin-right:-7.5px}.ui-tokentextarea .ui-tokentextarea-input-area{height:26.5px}.ui-tokentextarea .ui-tokentextarea-input-area .ui-text-line{display:none}.ui-scrollview-view>.ui-tokentextarea{margin-left:-4px;margin-right:-4px}.ui-tokentextarea .ui-tokentextarea-label{display:inline-block;text-align:center;position:relative;margin-left:6.5px;margin-right:3px;padding:11.5px 0;color:T059L2;font-size:15px}.ui-tokentextarea .ui-tokentextarea-input.ui-input-text{height:26.5px;outline:0;position:relative;border:0;padding:0;color:T059L1;background-color:W010;text-align:left;font-size:15px}.ui-tokentextarea-input-visible{display:inline-block}.ui-tokentextarea-input-invisible{display:none}.ui-tokentextarea div{display:inline-block;text-align:center;cursor:pointer;position:relative;padding:.2em .5em;font-size:15px;color:T020;text-overflow:ellipsis;white-space:nowrap;margin:4px 1px}.ui-tokentextarea-block{-webkit-mask-box-image-repeat:repeat;-moz-mask-box-image-repeat:repeat;-ms-mask-box-image-repeat:repeat;-o-mask-box-image-repeat:repeat;mask-box-image-repeat:repeat;-webkit-mask-box-image-width:auto;-moz-mask-box-image-width:auto;-ms-mask-box-image-width:auto;-o-mask-box-image-width:auto;mask-box-image-width:auto;-webkit-mask-box-image-source:url(images/nine-patch/core_button_bg.png);-webkit-mask-box-image-slice:37 38 36 38 fill;-moz-mask-box-image-slice:37 38 36 38 fill;-ms-mask-box-image-slice:37 38 36 38 fill;-o-mask-box-image-slice:37 38 36 38 fill;mask-box-image-slice:37 38 36 38 fill;background-color:var(--button-background);background-color:W012;margin-left:7.5px;margin-top:6px}.ui-tokentextarea-sblock{-webkit-mask-box-image-repeat:repeat;-moz-mask-box-image-repeat:repeat;-ms-mask-box-image-repeat:repeat;-o-mask-box-image-repeat:repeat;mask-box-image-repeat:repeat;-webkit-mask-box-image-width:auto;-moz-mask-box-image-width:auto;-ms-mask-box-image-width:auto;-o-mask-box-image-width:auto;mask-box-image-width:auto;-webkit-mask-box-image-source:url(images/nine-patch/core_button_bg.png);-webkit-mask-box-image-slice:37 38 36 38 fill;-moz-mask-box-image-slice:37 38 36 38 fill;-ms-mask-box-image-slice:37 38 36 38 fill;-o-mask-box-image-slice:37 38 36 38 fill;mask-box-image-slice:37 38 36 38 fill;background-color:var(--on-background);background-color:W012P;color:T020;margin-left:7.5px;margin-top:6px}.ui-tokentextarea .ui-tokentextarea-desclabel{display:inline-block;outline:0;position:relative;border:0;color:T059L2;text-align:left;font-size:15px;margin-left:1.5px}.ui-tokentextarea-link-base{position:absolute;right:0;bottom:2px;margin-right:4.5px}.ui-triangle-container{position:relative}.ui-triangle-container .ui-triangle{position:absolute;border-style:solid;border-color:transparent;border-width:10}.ui-triangle-container .ui-triangle-top{top:0;border-top-width:0;border-left-color:transparent;border-right-color:transparent;margin-left:-10}.ui-triangle-container .ui-triangle-bottom{bottom:0;border-bottom-width:0;border-left-color:transparent;border-right-color:transparent;margin-left:-10}.ui-triangle-container .ui-triangle-left{left:0;margin-top:-10;border-left-width:0;border-left-color:transparent;border-right-color:transparent}.ui-triangle-container .ui-triangle-right{right:0;margin-top:-10;border-right-width:0;border-left-color:transparent;border-right-color:transparent}.ui-triangle-container-top{height:10;top:0;margin-top:-10}.ui-triangle-container-bottom{height:10;bottom:0;margin-bottom:-10}.ui-triangle-container-left{width:10}.ui-triangle-container-right{width:10}.ui-virtualgrid{overflow:hidden;position:absolute}.ui-virtualgrid-wrapblock{position:absolute;left:0}.ui-virtualgrid-wrapblock-x{float:left;overflow:hidden}.ui-virtualgrid-wrapblock-y{float:left;overflow:hidden}.ui-scrollbar-thumb-x{width:1.5rem!important}.ui-scrollbar-thumb-y{height:1.5rem!important}.ui-virtualgrid-overflow-indicator-x-top{position:absolute;display:block;left:0;top:0;width:56%;height:100%;opacity:0;background-repeat:no-repeat;background-size:100% 100%;background-image:url(images/00_grid_overscrolling_left.png);pointer-events:none}.ui-virtualgrid-overflow-indicator-x-bottom{position:absolute;display:block;right:0;bottom:0;width:56%;height:100%;opacity:0;background-repeat:no-repeat;background-size:100% 100%;background-image:url(images/00_grid_overscrolling_right.png);pointer-events:none}.ui-virtualgrid-overflow-indicator-y-top{position:absolute;display:block;top:0;width:100%;height:32%;opacity:0;background-repeat:no-repeat;background-size:100% 100%;background-image:url(images/00_grid_overscrolling_top.png);pointer-events:none}.ui-virtualgrid-overflow-indicator-y-bottom{position:absolute;display:block;bottom:0;width:100%;height:32%;opacity:0;background-repeat:no-repeat;background-size:100% 100%;background-image:url(images/00_grid_overscrolling_bottom.png);pointer-events:none}.ui-content.ui-virtualgrid-content{padding:0}.ui-virtualgrid{margin:4px -4px 0 0}.ui-virtualgrid .ui-li-static{padding:0;border:0;width:100%}.ui-virtualgrid .grid-icon{width:26.25px;margin:0 4px 4px 0;display:block;overflow:hidden}.ui-virtualgrid .grid-icon.ui-btn-icon-top .ui-btn-inner.ui-btn-hastxt{padding-top:15.75px}.ui-virtualgrid .grid-icon.ui-btn .ui-icon{width:106px;height:106px;-webkit-mask-size:106px 106px;-moz-mask-size:106px 106px;-ms-mask-size:106px 106px;-o-mask-size:106px 106px;mask-size:106px 106px;margin-left:-53px;background-size:106px 106px}.ui-virtualgrid .grid-icon:not(.ui-focus){background-color:#1b403d}.ui-virtualgrid .grid-thumbnail{width:38px;margin:0 4px 4px 0;display:block;overflow:hidden}.ui-virtualgrid .grid-thumbnail.ui-btn .ui-btn-inner{margin:0;padding:0}.ui-virtualgrid .grid-thumbnail.ui-btn .ui-btn-inner .ui-btn-text{display:block}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-info{left:2.625px;right:2.625px;top:1px;position:absolute;color:#c8c8c8;font-size:2.75px;text-align:right;z-index:3}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic{z-index:2;width:38px;height:38px;overflow:hidden;background-color:#1a465f;position:relative}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic img{width:25px;height:25px;position:absolute;top:19px;left:19px;margin:-12.5px}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic-full{width:38px;height:38px;overflow:hidden;position:relative;z-index:2;box-sizing:border-box}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-pic-full img{width:38px;height:38px;position:absolute;top:19px;left:19px;margin:-19px}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents{background:#21240d;padding:1.875px 2.5px;font-size:6.5px;overflow:hidden;text-overflow:ellipsis;color:#d3d3d3;z-index:2}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents .grid-thumbnail-content{overflow:hidden;text-overflow:ellipsis;height:3.875px;line-height:6.5px;min-height:6.5px;display:block}.ui-virtualgrid .grid-thumbnail .grid-thumbnail-contents .grid-thumbnail-subtext{overflow:hidden;text-overflow:ellipsis;color:gray;font-size:2.75px;margin-top:-.75px;display:block}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic{border:solid #458fff;border-top-width:1px;border-left-width:1px;border-right-width:1px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic img{top:18px;left:18px;margin:-12.5px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic-full{border:solid #458fff;border-top-width:1px;border-left-width:1px;border-right-width:1px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-pic-full img{top:18px;left:18px;margin:-19px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents{background:#458fff}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents .grid-thumbnail-content,.ui-virtualgrid .grid-thumbnail.ui-btn.ui-focus .grid-thumbnail-contents .grid-thumbnail-subtext{color:#fff}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-selected .ui-btn-inner{border:solid #ffa955 1.25px}.ui-virtualgrid .grid-thumbnail.ui-btn.ui-selected .ui-btn-text{margin:-1.25px}.ui-mobile-viewport-transitioning,.ui-mobile-viewport-transitioning .ui-page{width:100%;height:100%;overflow:hidden}.in{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-duration:350ms;animation-duration:350ms}.out{-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;-webkit-animation-duration:225ms;animation-duration:225ms}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes fadein{from{opacity:0}to{opacity:1}}@-webkit-keyframes fadeout{from{opacity:1}to{opacity:0}}@keyframes fadeout{from{opacity:1}to{opacity:0}}.fade.out{opacity:0;-webkit-animation-duration:125ms;animation-duration:125ms;-webkit-animation-name:fadeout;animation-name:fadeout}.fade.in{opacity:1;-webkit-animation-duration:225ms;animation-duration:225ms;-webkit-animation-name:fadein;animation-name:fadein}.viewport-flip{position:absolute;-webkit-perspective:1000;-ms-perspective:1000;-o-perspective:1000;perspective:1000}.flip{backface-visiblity:hidden;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.flip.out{-webkit-transform:rotateY(-90 def) scale(0.9);transform:rotateY(-90 def) scale(0.9);-webkit-animation-name:flipouttoleft;animation-name:flipouttoleft;-webkit-animation-duration:175ms;animation-duration:175ms}.flip.out.ui-ctxpopup-container{border:2px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none}.flip.in{-webkit-animation-name:flipintoright;animation-name:flipintoright;-webkit-animation-duration:225ms;animation-duration:225ms}.flip.in.ui-ctxpopup-container{border:2px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none}.ui-popup.flip.out,.flip.out.reverse{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9);-webkit-animation-name:flipouttoright;animation-name:flipouttoright}.flip.in.reverse{-webkit-animation-name:flipintoleft;animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipouttoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}}@keyframes flipouttoright{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}.flow{box-shadow:0 0 20px rgba(0,0,0,.4);-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.ui-dialog.flow{box-shadow:none}.flow.out{-webkit-animation:flowouttoleft ease 350ms;animation:flowouttoleft ease 350ms;-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}.flow.in{-webkit-animation:flowinfromright ease 350ms;animation:flowinfromright ease 350ms;-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}.ui-popup.flow.out,.flow.out.reverse{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);-webkit-animation-name:flowouttoright;animation-name:flowouttoright}.flow.in.reverse{-webkit-animation-name:flowinfromleft;animation-name:flowinfromleft}@-webkit-keyframes flowouttoleft{0%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}60%,70%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}}@keyframes flowouttoleft{0%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}60%,70%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}}@-webkit-keyframes flowouttoright{0%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}60%,70%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(100%,0,0) scale(0.7);transform:translate3d(100%,0,0) scale(0.7)}}@keyframes flowouttoright{0%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}60%,70%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(100%,0,0) scale(0.7);transform:translate3d(100%,0,0) scale(0.7)}}@-webkit-keyframes flowinfromleft{0%{-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}30%,40%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}}@keyframes flowinfromleft{0%{-webkit-transform:translate3d(-100%,0,0) scale(0.7);transform:translate3d(-100%,0,0) scale(0.7)}30%,40%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}}@-webkit-keyframes flowinfromright{0%{-webkit-transform:translate3d(100%,0,0) scale(0.7);transform:translate3d(100%,0,0) scale(0.7)}30%,40%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}}@keyframes flowinfromright{0%{-webkit-transform:translate3d(100%,0,0) scale(0.7);transform:translate3d(100%,0,0) scale(0.7)}30%,40%{-webkit-transform:translate3d(0,0,0) scale(0.7);transform:translate3d(0,0,0) scale(0.7)}100%{-webkit-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1)}}.pop{-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.pop.in{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1;-webkit-animation:popin 350ms;animation:popin 350ms}.pop.in.ui-ctxpopup-container{border:2px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none}.pop.out{-webkit-animation:fadeout 100ms;animation:fadeout 100ms}.pop.out.ui-ctxpopup-container{border:2px solid var(--more-options-stroke-color);border-radius:5px;box-shadow:none}.pop.in.reverse{-webkit-animation-name:fadein;animation-name:fadein}.ui-popup.pop.out,.pop.out.reverse{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);-webkit-animation-name:popout;animation-name:popout}@-webkit-keyframes popin{from{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);opacity:0}to{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@keyframes popin{from{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);opacity:0}to{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes popout{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);opacity:0}}@keyframes popout{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(0.8);-ms-transform:scale(0.8);transform:scale(0.8);opacity:0}}.slide.out,.slide.in{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-duration:350ms;animation-duration:350ms}.slide.out{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);-webkit-animation-name:slideouttoleft;animation-name:slideouttoleft}.slide.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation-name:slideinfromright;animation-name:slideinfromright}.ui-popup.slide.out,.slide.out.reverse{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);-webkit-animation-name:slideouttoright;animation-name:slideouttoright}.slide.in.reverse{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation-name:slideinfromleft;animation-name:slideinfromleft}@-webkit-keyframes slideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideinfromleft{from{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideinfromleft{from{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@-webkit-keyframes slideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slidedown.out{-webkit-animation:fadeout 100ms;animation:fadeout 100ms}.slidedown.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:slideinfromtop 250ms;animation:slideinfromtop 250ms}.slidedown.in.reverse{-webkit-animation:fade 150ms;animation:fade 150ms}.ui-popup.slidedown.out,.slidedown.out.reverse{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);-webkit-animation:slideouttotop 200ms;animation:slideouttotop 200ms}@-webkit-keyframes slideinfromtop{from{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideinfromtop{from{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideouttotop{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideouttotop{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideupfade.out{-webkit-animation:fadeout 100ms;animation:fadeout 100ms}.slideupfade.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:slideupfadeinfrombottom 250ms;animation:slideupfadeinfrombottom 250ms}.slideupfade.in.reverse{-webkit-animation:fadein 150ms;animation:fadein 150ms}.ui-popup.slideupfade.out,.slideupfade.out.reverse{-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0);-webkit-animation:slideupfadeouttobottom 200ms;animation:slideupfadeouttobottom 200ms}@-webkit-keyframes slideupfadeinfrombottom{from{opacity:0;-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideupfadeinfrombottom{from{opacity:0;-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes slideupfadeouttobottom{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0)}}@keyframes slideupfadeouttobottom{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,5%,0);-ms-transform:translate3d(0,5%,0);transform:translate3d(0,5%,0)}}.slidedownfade.out{-webkit-animation:fadeout 100ms;animation:fadeout 100ms}.slidedownfade.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:slidedownfadeinfromtop 250ms;animation:slidedownfadeinfromtop 250ms}.slidedownfade.in.reverse{-webkit-animation:fadein 150ms;animation:fadein 150ms}.ui-popup.slidedownfade.out,.slidedownfade.out.reverse{-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0);-webkit-animation:slidedownfadeouttotop 200ms;animation:slidedownfadeouttotop 200ms}@-webkit-keyframes slidedownfadeinfromtop{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0)}}@keyframes slidedownfadeinfromtop{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0)}}@-webkit-keyframes slidedownfadeouttotop{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0)}}@keyframes slidedownfadeouttotop{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-5%,0);-ms-transform:translate3d(0,-5%,0);transform:translate3d(0,-5%,0)}}.slidefade.out{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);-webkit-animation:slideouttoleft 225ms;animation:slideouttoleft 225ms}.slidefade.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:fadein 200ms;animation:fadein 200ms}.ui-popup.slidefade.out,.slidefade.out.reverse{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);-webkit-animation:slideouttoright 200ms;animation:slideouttoright 200ms}.slidefade.in.reverse{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation:fadein 200ms;animation:fadein 200ms}.viewport-turn{-webkit-perspective:1000;-ms-perspective:1000;-o-perspective:1000;perspective:1000;position:absolute}.turn{backface-visiblity:hidden;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.turn.out{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9);-webkit-animation:flipouttoleft 125ms;animation:flipouttoleft 125ms}.turn.in{-webkit-animation:flipintoright 250ms;animation:flipintoright 250ms}.ui-popup.turn.out,.turn.out.reverse{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9);-webkit-animation-name:flipouttoright;animation-name:flipouttoright}.turn.in.reverse{-webkit-animation-name:flipintoleft;animation-name:flipintoleft}@-webkit-keyframes flipouttoleft{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}}@keyframes flipouttoleft{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}}@-webkit-keyframes flipouttoright{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}}@keyframes flipouttoright{from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}from{-webkit-transform:rotateY(0);transform:rotateY(0)}to{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}}@-webkit-keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipintoleft{from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(-90deg) scale(0.9);transform:rotateY(-90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@-webkit-keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}@keyframes flipintoright{from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}from{-webkit-transform:rotateY(90deg) scale(0.9);transform:rotateY(90deg) scale(0.9)}to{-webkit-transform:rotateY(0);transform:rotateY(0)}}.depth{-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%}.depth.out{opacity:0;-webkit-animation:depthout 250ms ease;animation:depthout 250ms ease}.depth.in{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1;-webkit-animation:depthin 350ms ease;animation:depthin 350ms ease}.depth.in.reverse{-webkit-animation-name:depthinreverse;animation-name:depthinreverse}.ui-popup.depth.out,.depth.out.reverse{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);-webkit-animation-name:depthoutreverse;animation-name:depthoutreverse}@-webkit-keyframes depthout{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}}@keyframes depthout{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}}@-webkit-keyframes depthin{0%{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}30%{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@keyframes depthin{0%{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}30%{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes depthinreverse{0%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}30%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@keyframes depthinreverse{0%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}30%{-webkit-transform:scale(1.1);-ms-transform:scale(1.1);transform:scale(1.1);opacity:0}100%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}}@-webkit-keyframes depthoutreverse{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}}@keyframes depthoutreverse{from{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1);opacity:1}to{-webkit-transform:scale(0.9);-ms-transform:scale(0.9);transform:scale(0.9);opacity:0}}.ui-mobile-viewport-transitioning,.ui-mobile-viewport-transitioning .ui-page{width:100%;height:100%;overflow:hidden}.ui-page.slide.out,.ui-page.slide.in{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-duration:400ms;animation-duration:400ms}.ui-page.slide.out{-webkit-animation-name:pageslideouttoleft;animation-name:pageslideouttoleft}.ui-page.slide.in{-webkit-animation-name:pageslideinfromright;animation-name:pageslideinfromright}.ui-page.slide.out.reverse{-webkit-animation-name:pageslideouttoright;animation-name:pageslideouttoright;z-index:2000}.ui-page.slide.in.reverse{-webkit-animation-name:pageslideinfromleft;animation-name:pageslideinfromleft}.ui-page.slide.in.reverse::after,.ui-page.slide.out:not(.reverse)::after{content:"";background-image:url(images/page/core_theme_bg_01.png);background-repeat:no-repeat;background-size:100% 100%;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2000;opacity:0}.ui-page.slide.in.reverse::after{-webkit-animation:pagebgslideinreverse 400ms ease-out;animation:pagebgslideinreverse 400ms ease-out}.ui-page.slide.out:not(.reverse)::after{-webkit-animation:pagebgslideout 400ms ease-out;animation:pagebgslideout 400ms ease-out}@-webkit-keyframes pageslideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-25%,0,0);-ms-transform:translate3d(-25%,0,0);transform:translate3d(-25%,0,0)}}@keyframes pageslideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-25%,0,0);-ms-transform:translate3d(-25%,0,0);transform:translate3d(-25%,0,0)}}@-webkit-keyframes pageslideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes pageslideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes pageslideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes pageslideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@-webkit-keyframes pageslideinfromleft{from{-webkit-transform:translate3d(-25%,0,0);-ms-transform:translate3d(-25%,0,0);transform:translate3d(-25%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes pageslideinfromleft{from{-webkit-transform:translate3d(-25%,0,0);-ms-transform:translate3d(-25%,0,0);transform:translate3d(-25%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes pagebgslideinreverse{from{opacity:.5}to{opacity:0}}@keyframes pagebgslideinreverse{from{opacity:.5}to{opacity:0}}@-webkit-keyframes pagebgslideout{from{opacity:0}to{opacity:.5}}@keyframes pagebgslideout{from{opacity:0}to{opacity:.5}}.ui-page.slideup.out{-webkit-animation-name:fadeout;animation-name:fadeout;-webkit-animation-duration:250ms;animation-duration:250ms}.ui-page.slideup.in{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0);-webkit-animation-name:pageslideinfrombottom;animation-name:pageslideinfrombottom;-webkit-animation-duration:200ms;animation-duration:200ms}.ui-page.slideup.in.reverse{-webkit-animation-name:fadein;animation-name:fadein;-webkit-animation-duration:250ms;animation-duration:250ms}.ui-page.slideup.out.reverse{-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);-webkit-animation-name:pageslideouttobottom;animation-name:pageslideouttobottom;-webkit-animation-duration:200ms;animation-duration:200ms}@-webkit-keyframes pageslideinfrombottom{from{-webkit-transform:translate3d(0,100%,0)}to{-webkit-transform:translate3d(0,0,0)}}@-webkit-keyframes pageslideouttobottom{from{-webkit-transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(0,100%,0)}}ul.ui-virtual-list-container>ul.position_absolute{position:absolute}.ui-listview.ui-virtual-list-container .ui-li{position:relative}.ui-virtual-list-edge-effect{pointer-events:none;width:100%;height:0;position:absolute;top:0;left:0;box-shadow:0 0 rgba(0,0,0,0)}.ui-virtual-list-edge-effect.orientation-horizontal{height:100%;width:0}.ui-grid-a,.ui-grid-b,.ui-grid-c,.ui-grid-d{overflow:hidden}.ui-block-a,.ui-block-b,.ui-block-c,.ui-block-d,.ui-block-e{margin:0;padding:0;border:0;float:left;min-height:1px}.ui-grid-solo .ui-block-a{width:100%;float:none}.ui-grid-a .ui-block-a,.ui-grid-a .ui-block-b{width:50%}.ui-grid-a .ui-block-a{clear:left}.ui-grid-b .ui-block-a,.ui-grid-b .ui-block-b,.ui-grid-b .ui-block-c{width:33.333%}.ui-grid-b .ui-block-a{clear:left}.ui-grid-c .ui-block-a,.ui-grid-c .ui-block-b,.ui-grid-c .ui-block-c,.ui-grid-c .ui-block-d{width:25%}.ui-grid-c .ui-block-a{clear:left}.ui-grid-d .ui-block-a,.ui-grid-d .ui-block-b,.ui-grid-d .ui-block-c,.ui-grid-d .ui-block-d,.ui-grid-d .ui-block-e{width:20%}.ui-grid-d .ui-block-a{clear:left}.ui-navbar{overflow:hidden}.ui-navbar ul,.ui-navbar-expanded ul{list-style:none;padding:0;margin:0;position:relative;display:block;border:0}.ui-navbar-collapsed ul{float:left;width:75%;margin-right:-2px}.ui-navbar-collapsed .ui-navbar-toggle{float:left;width:25%}.ui-navbar .ui-navbar-truncate{position:absolute;left:-9999px;top:-9999px}.ui-navbar li .ui-btn,.ui-navbar .ui-navbar-toggle .ui-btn{display:block;text-align:center;margin:0;border-right-width:0}.ui-navbar li .ui-btn{margin-right:-1px}.ui-navbar li .ui-btn:last-child{margin-right:0}.ui-header .ui-navbar .ui-btn,.ui-footer .ui-navbar .ui-btn{border-top-width:0}.ui-navbar .ui-btn-inner{padding-left:2px;padding-right:2px}.ui-navbar-noicons .ui-btn-inner{padding-top:.8em;padding-bottom:.9em}.ui-navbar-expanded .ui-btn{margin:0;font-size:14px}.ui-navbar-expanded .ui-btn-inner{padding-left:5px;padding-right:5px}.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner{padding:45px 5px 15px;text-align:center}.ui-navbar-expanded .ui-btn-icon-top .ui-icon{top:15px}.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner{padding:15px 5px 45px;text-align:center}.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon{bottom:15px}.ui-navbar-expanded .ui-btn-inner{min-height:2.5em}.ui-navbar-expanded .ui-navbar-noicons .ui-btn-inner{padding-top:1.8em;padding-bottom:1.9em}.ui-select{display:block;position:relative}.ui-select select{position:absolute;left:-9999px;top:-9999px}.ui-select .ui-btn{overflow:hidden}.ui-select .ui-btn select{cursor:pointer;-webkit-appearance:button;left:0;top:0;width:100%;min-height:100%;height:3em;max-height:100%;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);z-index:2}.ui-select .ui-btn select.ui-select-nativeonly{opacity:1;text-indent:0}.ui-select .ui-btn-icon-right .ui-btn-inner{padding-right:45px}.ui-select .ui-btn-icon-right .ui-icon{right:15px}label.ui-select{font-size:16px;line-height:1.4;font-weight:400;margin:0 0 .3em;display:block}.ui-select .ui-btn-text,.ui-selectmenu .ui-btn-text{display:block;min-height:1em}.ui-select .ui-btn-text{text-overflow:ellipsis;overflow:hidden}.ui-selectmenu .ui-listview{margin:0}.ui-selectmenu .ui-btn.ui-li-divider{cursor:default}.ui-selectmenu-hidden{top:-9999px;left:-9999px;visibility:hidden}.ui-selectmenu-screen{position:absolute;top:0;left:0;width:100%;height:100%;z-index:99}.ui-selectmenu-list .ui-li .ui-icon{display:none}.ui-selectmenu-list .ui-li .ui-icon{display:block}.ui-li.ui-selectmenu-placeholder{display:none}.ui-selectmenu .ui-header .ui-title{margin:.6em 46px .8em}@media all and (min-width:450px){label.ui-select{vertical-align:top;display:inline-block;width:20%;margin:0 2% 0 0}.ui-select{width:60%;display:inline-block}}.ui-selectmenu .ui-header h1::after{content:'.';visibility:hidden}.ui-selectmenu .ui-header .ui-btn-icon_only .ui-btn-text{position:absolute;left:-9999px}.ui-selectmenu .ui-header .ui-btn-icon_only .ui-icon{margin:auto}.ui-page.ui-empty-state .ui-header{background-color:var(--background-color)}.ui-page.ui-empty-state .ui-content{position:relative;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;height:100%;background-color:var(--background-color)}.ui-page.ui-empty-state .ui-content::before{content:'';display:block;position:absolute;top:0;left:0;width:100%;height:100%;-webkit-mask-image:url(images/00_page_empty_bg.png);mask-image:url(images/00_page_empty_bg.png);-webkit-mask-size:100% auto;mask-size:100% auto;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;background-color:var(--background-color)}.ui-page.ui-empty-state .ui-content .ui-scrollview-view{padding-left:16px;padding-right:16px;text-align:center;font-size:16px;color:var(--text-color);line-height:21.5px;min-height:286px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-page.ui-empty-state .ui-content .ui-scrollview-view h1,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h2,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h3,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h4,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h5,.ui-page.ui-empty-state .ui-content .ui-scrollview-view h6{margin:0;margin-bottom:27px;line-height:27px;font-size:20px;font-weight:lighter;color:T0222L1}@media only screen and (orientation:landscape){.ui-page.ui-empty-state .ui-content:before{-webkit-mask-image:url(images/00_page_empty_bg_h.png);mask-image:url(images/00_page_empty_bg_h.png);-webkit-mask-size:100% 100px;mask-size:100% 100px}}.ui-listview.ui-listview-empty-state-show{height:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-listview.ui-listview-empty-state-show .ui-li-empty-state{display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-listview.ui-listview-empty-state-show .ui-li-static{height:27px}.ui-listview .ui-li-empty-state{width:100%;display:none;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:relative;-webkit-align-content:center;-ms-flex-line-pack:center;align-content:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;-webkit-flex:1;-ms-flex:1;flex:1;box-sizing:border-box;padding:0 0 42px}.ui-empty-state-content{pointer-events:none;padding-left:16px;padding-right:16px;text-align:center;font-size:16px;color:T0222L4;line-height:21.5px;height:286px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-empty-state-content h1,.ui-empty-state-content h2,.ui-empty-state-content h3,.ui-empty-state-content h4,.ui-empty-state-content h5,.ui-empty-state-content h6{margin:0;margin-bottom:27px;line-height:27px;font-size:20px;font-weight:lighter;color:T0222L3}.ui-page-floatingactions .ui-listview .ui-li-empty-state{padding:0 0 94px}input[type=search]::-webkit-search-decoration,input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}input[type=search][disabled]{background-color:transparent}.ui-search-input{font-size:20px;overflow:hidden;background-color:transparent;text-shadow:0 0 0 var(--text-color);color:var(--text-input-inactive);-webkit-text-fill-color:transparent}.ui-search-input:focus{text-shadow:0 0 0 var(--text-color);border-color:var(--text-input-underline-active)}.ui-search-input.ui-state-disabled{text-shadow:0 0 0 var(--text-input-disabled);border-bottom:2px solid var(--text-input-disabled)}.ui-search-input.ui-state-disabled::-webkit-input-placeholder{color:var(--text-input-label-inactive);text-shadow:none;-webkit-text-fill-color:initial}.ui-header-searchbar{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;padding:0 8.5px 0 5px;box-sizing:border-box;overflow:initial}.ui-header-searchbar>.ui-search-input,.ui-header-searchbar>input{border:0;outline:0;overflow:hidden;border-bottom:1px solid;border-bottom-color:var(--text-input-underline-active);font-size:20px;color:var(--primary-color);background-color:transparent;-webkit-text-fill-color:transparent;height:40px;text-shadow:0 0 0 var(--text-color);box-sizing:border-box;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:2px 5px 0;margin-right:7.5px}.ui-header-searchbar>.ui-search-input.ui-text-input-clear-active:focus,.ui-header-searchbar>input.ui-text-input-clear-active:focus,.ui-header-searchbar>.ui-search-input.ui-text-input-clear-active:active,.ui-header-searchbar>input.ui-text-input-clear-active:active{text-shadow:0 0 0 var(--text-color);padding:2px 41px 0 5px}.ui-header-searchbar>.ui-search-input[disabled],.ui-header-searchbar>input[disabled],.ui-header-searchbar>.ui-search-input.ui-state-disabled,.ui-header-searchbar>input.ui-state-disabled{text-shadow:0 0 0 var(--text-input-disabled)}.ui-header-searchbar>.ui-search-input[disabled]::-webkit-input-placeholder,.ui-header-searchbar>input[disabled]::-webkit-input-placeholder,.ui-header-searchbar>.ui-search-input.ui-state-disabled::-webkit-input-placeholder,.ui-header-searchbar>input.ui-state-disabled::-webkit-input-placeholder{text-shadow:var(--text-input-label-inactive)}.ui-header-searchbar>.ui-search-input::-webkit-input-placeholder,.ui-header-searchbar>input::-webkit-input-placeholder{text-shadow:0 0 0 var(--primary-color)}.ui-header-searchbar>.ui-search-input~.ui-text-input-clear.ui-btn.ui-btn-icon,.ui-header-searchbar>input~.ui-text-input-clear.ui-btn.ui-btn-icon{top:7.5px;position:absolute;right:8.5px;margin:0}.ui-header-searchbar>.ui-search-input~.ui-text-input-clear.ui-btn.ui-btn-icon::after,.ui-header-searchbar>input~.ui-text-input-clear.ui-btn.ui-btn-icon::after{background-color:var(--text-color)}.ui-header-searchbar>.ui-search-input+.ui-btn.ui-btn-icon+.ui-text-input-clear.ui-btn.ui-btn-icon,.ui-header-searchbar>input+.ui-btn.ui-btn-icon+.ui-text-input-clear.ui-btn.ui-btn-icon{right:49.5px}.ui-header-searchbar>.ui-search-input~.ui-btn-nobg::before,.ui-header-searchbar>input~.ui-btn-nobg::before{background-color:var(--ripple-color)}.ui-header-searchbar .ui-header-btn-right~.ui-text-input-clear.ui-btn.ui-btn-icon{right:49.5px}.ui-header-searchbar>.ui-btn:not(.ui-btn-nobg),.ui-header-searchbar .ui-header-btn-left.btn-icon-back,.ui-header-searchbar .ui-header-btn-icon.ui-header-btn-right{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;position:relative}.ui-header-searchbar>.ui-btn.ui-btn-icon:not(.ui-text-input-clear):not(.btn-icon-back)::after{-webkit-mask-size:25px 25px;mask-size:25px 25px}.ui-header-searchbar>.ui-header-btn-right{-webkit-order:2;-ms-flex-order:2;order:2;position:relative}.ui-handler{position:fixed;display:-webkit-flex;display:-ms-flexbox;display:flex;overflow:hidden;opacity:0;transition:opacity 400ms ease-out;height:100%;top:0;right:0}.ui-handler .ui-handler-track{-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;position:relative;width:100%;height:100%;display:block}.ui-handler .ui-handler-track .ui-handler-handle{-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;position:absolute;display:block;background-color:transparent}.ui-handler .ui-handler-track .ui-handler-handle .ui-handler-expander{width:100%;height:100%;float:right;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;background-color:var(--primary-color);border-radius:2.5px;transition-property:width border-width border-radius;transition-duration:100ms}.ui-handler .ui-handler-track .ui-handler-handle.ui-active .ui-handler-thumb:before{content:"";position:absolute;top:0;left:0;width:16px;height:16px;-webkit-mask-size:100%;-moz-mask-size:100%;-ms-mask-size:100%;-o-mask-size:100%;mask-size:100%;background-color:var(--icon-color)}.ui-handler .ui-handler-track .ui-handler-handle.ui-active .ui-handler-thumb:after{content:"";position:absolute;top:0;left:0;width:16px;height:16px;-webkit-mask-size:100%;-moz-mask-size:100%;-ms-mask-size:100%;-o-mask-size:100%;mask-size:100%;background-color:var(--icon-color)}.ui-handler.ui-handler-direction-x{right:5px;bottom:0;left:5px;height:19px;top:auto}.ui-handler.ui-handler-direction-x .ui-handler-handle{min-width:22px;height:16px;margin-bottom:3px;top:auto;bottom:0;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:flex-end;-moz-align-items:flex-end;-ms-align-items:flex-end;-o-align-items:flex-end;-ms-flex-align:end;align-items:flex-end}.ui-handler.ui-handler-direction-x .ui-handler-handle .ui-handler-expander{height:5px;width:100%;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-handler.ui-handler-direction-x .ui-handler-track .ui-handler-handle.ui-active{min-width:41px;margin-bottom:3px;border-radius:8px;-webkit-flex-direction:row;-moz-flex-direction:row;-ms-flex-direction:row;-o-flex-direction:row;flex-direction:row}.ui-handler.ui-handler-direction-x .ui-handler-track .ui-handler-handle.ui-active .ui-handler-expander{height:16px;border-radius:8px}.ui-handler.ui-handler-direction-x .ui-handler-thumb:before{-webkit-mask-image:url(images/core_index_scroll_handler_h_01.png);mask-image:url(images/core_index_scroll_handler_h_01.png)}.ui-handler.ui-handler-direction-x .ui-handler-thumb:after{-webkit-mask-image:url(images/core_index_scroll_handler_h_02.png);mask-image:url(images/core_index_scroll_handler_h_02.png)}.ui-handler.ui-handler-direction-y{top:0;right:0;bottom:0;width:19px;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}.ui-handler.ui-handler-direction-y:before{content:"";width:100%;height:55px;background-color:transparent}.ui-handler.ui-handler-direction-y .ui-handler-handle{width:16px;margin-right:3px;min-height:22px;left:auto;right:0}.ui-handler.ui-handler-direction-y .ui-handler-handle .ui-handler-expander{width:5px;height:100%}.ui-handler.ui-handler-direction-y .ui-handler-track{margin:5px 0;background-color:transparent;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1}.ui-handler.ui-handler-direction-y .ui-handler-track .ui-handler-handle.ui-active{width:16px;margin-right:3px;min-height:41px;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column}.ui-handler.ui-handler-direction-y .ui-handler-track .ui-handler-handle.ui-active .ui-handler-expander{border-radius:8px;width:16px}.ui-handler.ui-handler-direction-y .ui-handler-thumb:before{-webkit-mask-image:url(images/core_index_scroll_handler_v_01.png);mask-image:url(images/core_index_scroll_handler_v_01.png)}.ui-handler.ui-handler-direction-y .ui-handler-thumb:after{-webkit-mask-image:url(images/core_index_scroll_handler_v_02.png);mask-image:url(images/core_index_scroll_handler_v_02.png)}.ui-handler.disabled{display:none}.ui-handler .ui-handler-thumb{width:16px;height:16px;position:relative}.ui-handler-visible{opacity:1}.scrollbar-disabled{overflow:hidden!important}.scrollbar-disabled .ui-scrollview-clip{width:105%}.scrollbar-disabled .ui-scrollview-clip[data-direction="x"]{width:100%;height:105%}.ui-container{white-space:nowrap;padding-bottom:10px}.ui-container>*{scroll-snap-align:center}.ui-container .ui-container-item{display:inline-block;margin-left:3px;margin-right:3px;width:188px}.ui-container .ui-container-item:last-child{padding-right:20px}.ui-container.ui-container-middle .ui-favorite.ui-btn{width:103px}.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content{width:103px}.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content img{width:100px;height:100px}.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content .ui-title,.ui-container.ui-container-middle .ui-favorite.ui-btn .ui-btn-content .ui-subtitle{font-family:Roboto-Medium;width:100%;text-align:left;text-overflow:ellipsis;color:#7b7b7b}.ui-drawer{position:absolute;background-color:var(--background-color);z-index:1201;box-sizing:border-box;overflow-x:hidden;overflow-y:scroll}.ui-drawer-header{height:56px;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-drawer-title{font-size:19px;color:var(--appbar-main-text-color);-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;margin-left:20px}.ui-drawer .ui-listview{margin:0;position:absolute;z-index:2000;width:100%;height:100%}.ui-drawer .ui-listview .ui-drawer-sub-list>.ui-btn-inner .ui-btn-text .ui-link-inherit{padding-left:13px}.ui-drawer-overlay{position:absolute;background-color:var(--overlay);z-index:1200}.ui-header .ui-btn.ui-drawer-button.ui-btn-icon-only{position:absolute;top:0;left:0;width:27px;height:36px}.ui-header .ui-btn.ui-drawer-button.ui-btn-icon-only::after{width:27px;height:36px;-webkit-mask-size:100%;mask-size:100%;margin-top:0;top:0;left:0}.ui-dropdownmenu-overlay{opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:1200}.ui-dropdownmenu{box-sizing:border-box;width:100%;display:block;position:relative}.ui-dropdownmenu:focus{outline:0}.ui-dropdownmenu:active{outline:0}.ui-dropdownmenu:active .ui-dropdownmenu-placeholder{background-color:W021L1P}.ui-dropdownmenu::before{content:"";opacity:0;width:90%;height:26px;background-color:var(--ripple-color);position:absolute;top:17px;left:5%;transition-property:width,height,top,left;transition-duration:.2s;transition-timing-function:ease}.ui-dropdownmenu:active::before{content:"";opacity:1;width:94%;height:40px;background-color:var(--ripple-color);position:absolute;top:10px;left:3%}.ui-dropdownmenu .ui-dropdownmenu-placeholder{box-sizing:border-box;text-align:left;width:100%;display:inline-block;vertical-align:middle;position:relative;height:100%;line-height:60px;white-space:nowrap;padding:0 26px 0 16px;overflow:hidden;text-overflow:ellipsis;font-size:17px;text-indent:5px;background-color:W021L1}.ui-dropdownmenu .ui-dropdownmenu-placeholder::after{content:"";position:absolute;width:calc(100% - 32px);height:1px;bottom:9px;right:16px;background-color:F057}.ui-dropdownmenu select{width:100%;display:none}.ui-dropdownmenu.ui-focus{background-color:var(--ripple-color)}.ui-dropdownmenu-inline{width:auto;display:inline-block}.ui-dropdownmenu-disabled{opacity:1}.ui-dropdownmenu-disabled .ui-dropdownmenu-placeholder{color:var(--dropdown-menu-options-color-dim)}.ui-dropdownmenu-force-display{display:block!important}.ui-dropdownmenu-native select{display:block;top:0;left:0;position:absolute;height:100%;outline:0;opacity:0;border:0;margin:0}.ui-dropdownmenu-overlay-hidden{display:none}@-webkit-keyframes open-to-bottom{from{opacity:.5;-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes open-to-top{from{opacity:.5;-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes close-to-bottom{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,100%,0);-ms-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@-webkit-keyframes close-to-top{from{opacity:1;-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);-ms-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.ui-dropdownmenu-options-wrapper{position:absolute;visibility:hidden;top:-5000px;overflow:hidden;z-index:1201;min-width:168px;max-width:100vw;padding:3px}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-vertical-margins{margin-top:3px;margin-bottom:3px}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-active{visibility:visible;overflow-y:auto}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-opening.ui-dropdownmenu-options-top .ui-dropdownmenu-options{-webkit-animation:open-to-top 300ms;animation:open-to-top 300ms}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-opening.ui-dropdownmenu-options-bottom .ui-dropdownmenu-options{-webkit-animation:open-to-bottom 300ms;animation:open-to-bottom 300ms}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-closing.ui-dropdownmenu-options-top .ui-dropdownmenu-options{-webkit-animation:close-to-bottom 300ms;animation:close-to-bottom 300ms}.ui-dropdownmenu-options-wrapper.ui-dropdownmenu-options-closing.ui-dropdownmenu-options-bottom .ui-dropdownmenu-options{-webkit-animation:close-to-top 300ms;animation:close-to-top 300ms}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options{box-sizing:border-box;list-style:none;padding:0;margin:0;max-height:calc(100vh - 6px);overflow-y:auto;background-color:var(--dropdown-menu-options-background);border-radius:26px;box-shadow:0 0 3px 0 rgba(0,0,0,.35);border:var(--dropdown-menu-options-border)}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options:focus{outline:0}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-disabled{color:var(--dropdown-menu-options-color-dim)}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-selected{color:var(--primary-dark-color);font-family:Roboto-Medium}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options .ui-dropdownmenu-selected::after{width:20px;height:20px;margin-left:16px;margin-right:24px;content:'';position:absolute;-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg);-webkit-mask-size:100%,0;mask-size:100%,0;-webkit-mask-position:center;mask-position:center;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;right:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);top:50%;background-color:var(--primary-dark-color)}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li{padding:15px 60px 15px 24px;font-size:17px;font-family:Roboto-Regular;display:block;position:relative;overflow:hidden;text-overflow:ellipsis;color:var(--dropdown-menu-options-color)}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li.ui-dropdown-two-lines{max-height:2em;line-height:1.4em}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:not(.ui-dropdown-two-lines){white-space:nowrap;height:20px}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:focus,.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:active{outline:0}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li::before{content:"";position:absolute;top:0;left:0;width:100%;height:100%;background-color:var(--ripple-color);opacity:0}.ui-dropdownmenu-options-wrapper .ui-dropdownmenu-options li:active::before{opacity:1}.ui-dropdownmenu-active::-webkit-scrollbar{display:none}.ui-listview li.ui-li-static.ui-li-has-dropdownmenu{padding:0}.ui-listview li.ui-li-static.ui-li-has-dropdownmenu .ui-dropdownmenu-placeholder{line-height:60px}.ui-li-static.ui-li-has-dropdownmenu{height:60px}.ui-appbar .ui-dropdownmenu-placeholder{line-height:56px}.ui-appbar-expanded .ui-dropdownmenu-placeholder{line-height:59px}.ui-panel-changer{position:relative;display:block;width:100%;left:0}.ui-panel{position:absolute;height:100%;width:100%}.ui-panel.ui-panel-active{display:block}.ui-panel.slide-in,.ui-panel.slide-out,.ui-panel.slide-reverse-out,.ui-panel.slide-reverse-in{-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out;-webkit-animation-duration:400ms;animation-duration:400ms}.ui-panel.pre-in{z-index:100}.ui-panel.slide-out{-webkit-animation-name:panelslideouttoleft;animation-name:panelslideouttoleft}.ui-panel.slide-in{-webkit-animation-name:panelslideinfromright;animation-name:panelslideinfromright}.ui-panel.slide-reverse-out{-webkit-animation-name:panelslideouttoright;animation-name:panelslideouttoright}.ui-panel.slide-reverse-in{-webkit-animation-name:panelslideinfromleft;animation-name:panelslideinfromleft}.ui-panel .ui-content{height:100%}@-webkit-keyframes panelslideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes panelslideouttoleft{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@-webkit-keyframes panelslideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes panelslideinfromright{from{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@-webkit-keyframes panelslideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes panelslideouttoright{from{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}to{-webkit-transform:translate3d(100%,0,0);-ms-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@-webkit-keyframes panelslideinfromleft{from{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes panelslideinfromleft{from{-webkit-transform:translate3d(-100%,0,0);-ms-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.ui-navigation{-webkit-order:2;-moz-order:2;-ms-order:2;-o-order:2;-ms-flex-order:2;order:2;height:35px;box-sizing:border-box;background-color:var(--background-color);border-top:1px solid var(--color-white);white-space:nowrap;overflow-x:scroll;overflow-y:hidden}.ui-navigation::-webkit-scrollbar{display:none}.ui-navigation .ui-navigation-container{margin:0;padding:0;display:inline-block;list-style-type:none}.ui-navigation .ui-navigation-container .ui-navigation-item{position:relative;height:34px;line-height:34px;vertical-align:top;overflow:hidden;display:inline-block;color:var(--text-color);font-size:16px;background-color:transparent}.ui-navigation .ui-navigation-container .ui-navigation-item:first-child{margin-left:9px}.ui-navigation .ui-navigation-container .ui-navigation-item:first-child::before{content:none}.ui-navigation .ui-navigation-container .ui-navigation-item .ui-arrow{float:left;height:34px;width:30px;color:var(--text-color);background-color:var(--color-white);-webkit-mask-image:url(images/core_navigation_bar_icon_arrow.png);-webkit-mask-size:100% 100%;margin:0 -9px 0;opacity:.6}.ui-navigation .ui-navigation-container .ui-navigation-item .ui-text{display:block;position:relative;float:left;height:21.5px;color:var(--text-color);padding:3px 7px 4.5px;line-height:21.5px;margin-top:2.5px;text-decoration:none;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;opacity:.6}.ui-navigation .ui-navigation-container .ui-navigation-item .ui-text.ui-focus{background-color:rgba(50,150,166,.4);outline:0}.ui-navigation .ui-navigation-container .ui-navigation-item:last-child{margin-right:9px}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-active-animation .ui-arrow{-webkit-animation:navigation_active_show_animation_arrow linear 133ms;animation:navigation_active_show_animation_arrow linear 133ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-active-animation .ui-text{-webkit-animation:navigation_active_show_animation_text linear 166ms;animation:navigation_active_show_animation_text linear 166ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back .ui-arrow{-webkit-animation:none;animation:none}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back .ui-text{-webkit-animation:navigation_active_back_animation_text linear 184ms;animation:navigation_active_back_animation_text linear 184ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-hide .ui-arrow{-webkit-animation:navigation_active_hide_animation_text linear 150ms;animation:navigation_active_hide_animation_text linear 150ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-hide .ui-text{-webkit-animation:navigation_active_hide_animation_text linear 184ms;animation:navigation_active_hide_animation_text linear 184ms}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigation-active .ui-arrow{opacity:.6}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigation-active .ui-text{color:var(--ripple-color);opacity:1}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back-hide .ui-arrow{-webkit-animation:none;animation:none}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-navigator-back-hide .ui-text{-webkit-animation:navigation_active_back_hide_animation_text linear 184ms;animation:navigation_active_back_hide_animation_text linear 184ms;opacity:1}.ui-navigation .ui-navigation-container .ui-navigation-item.ui-btn-active .ui-text::before{content:"";position:absolute;width:100%;height:100%;left:50%;top:50%;background-color:var(--ripple-color);opacity:0;color:var(--ripple-color);-webkit-animation:navigation_press_animation linear 500ms;animation:navigation_press_animation linear 500ms}@-webkit-keyframes navigation_active_show_animation_text{0%{opacity:0}100%{opacity:1}}@keyframes navigation_active_show_animation_text{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes navigation_active_back_animation_text{0%{opacity:.6}100%{opacity:1}}@keyframes navigation_active_back_animation_text{0%{opacity:.6}100%{opacity:1}}@-webkit-keyframes navigation_active_back_hide_animation_text{0%{opacity:1}100%{opacity:.6}}@keyframes navigation_active_back_hide_animation_text{0%{opacity:1}100%{opacity:.6}}@-webkit-keyframes navigation_active_show_animation_arrow{0%{opacity:0}20%{opacity:0}100%{opacity:.6}}@keyframes navigation_active_show_animation_arrow{0%{opacity:0}20%{opacity:0}100%{opacity:.6}}@-webkit-keyframes navigation_active_hide_animation_text{0%{opacity:1}100%{opacity:0}}@keyframes navigation_active_hide_animation_text{0%{opacity:1}100%{opacity:0}}@-webkit-keyframes navigation_press_animation{0%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(0.7);-ms-transform:translate(-50%,-50%) scale(0.7);transform:translate(-50%,-50%) scale(0.7)}5%{opacity:.3}100%{opacity:.3;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@keyframes navigation_press_animation{0%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(0.7);-ms-transform:translate(-50%,-50%) scale(0.7);transform:translate(-50%,-50%) scale(0.7)}5%{opacity:.3}100%{opacity:.3;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@-webkit-keyframes navigation_pressup_animation{0%{opacity:.3}100%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@keyframes navigation_pressup_animation{0%{opacity:.3}100%{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}.ui-tabs{position:relative;height:100%;overflow:hidden;border-bottom-left-radius:26px;border-bottom-right-radius:26px}.ui-tabs .ui-listview{overflow:hidden;min-height:100%;min-width:100%}.ui-section-changer{height:100%;position:relative;overflow:hidden;display:block}.ui-section-changer section{overflow:auto}.ui-indexscrollbar{display:block;position:absolute;right:0;top:0;width:20px;height:100%;padding-left:1px;background-color:var(--control-background);z-index:1000;overflow:visible;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;cursor:pointer;box-sizing:border-box}.ui-indexscrollbar::before{width:20px;display:block;position:absolute;right:20px;height:100%;content:" ";background-color:transparent}.ui-indexscrollbar ul{list-style-type:none;margin:0;position:absolute;width:100%;height:100%;left:0;visibility:visible;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;-webkit-align-items:stretch;-moz-align-items:stretch;-ms-align-items:stretch;-o-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center;padding:0;box-sizing:border-box}.ui-indexscrollbar ul li{cursor:pointer;color:var(--text-color);display:block;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;text-align:center;font-size:12px;font-weight:700;border-bottom:1px solid var(--primary-color);border-left:1px solid var(--border-surface);-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center;max-height:20px;min-height:20px}.ui-indexscrollbar ul li a{text-decoration:none;width:18px;height:19px;color:inherit;border:0;outline:0;box-sizing:border-box;margin:0;padding:0}.ui-indexscrollbar ul li a:focus{background-color:var(--ripple-color)}.ui-indexscrollbar ul li.ui-state-selected{border-left:2px solid var(--primary-color);position:relative;width:18px}.ui-indexscrollbar ul li.ui-state-selected::before{content:"";position:absolute;height:100%;width:17px;left:-1px;top:-1px;border:1px solid var(--border-surface);border-left:0}.ui-indexscrollbar ul::before,.ui-indexscrollbar ul::after{content:"";width:20px;border-left:1px solid var(--border-surface);display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;pointer-events:none;-webkit-flex-basis:auto;-ms-flex-preferred-size:auto;flex-basis:auto}.ui-indexscrollbar ul.ui-indexscrollbar-supplementary{position:relative;height:auto;top:0;right:-20px;width:100%}.ui-indexscrollbar .ui-indexscrollbar-margin{width:20px;position:absolute;bottom:0;left:0;border-left:1px solid var(--border-surface)}.ui-indexscrollbar+.ui-listview li{padding-right:20px}.ui-indexscrollbar ul li:first-child{padding-top:21px;position:relative}.ui-indexscrollbar ul li:first-child::before{content:"";height:20px;width:20px;position:absolute;top:0;left:0;background-color:var(--text-color);-webkit-mask-image:url(../default/images/controls/core_floating_icon_search.png);mask-image:url(../default/images/controls/core_floating_icon_search.png);-webkit-mask-size:80%;mask-size:80%;-webkit-mask-position:center center;mask-position:center center}.ui-indexscrollbar ul li:first-child::after{content:"";height:1px;width:20px;position:absolute;top:20px;left:0;background-color:var(--primary-color)}.ui-indexscrollbar ul li:last-child{border-bottom-color:transparent}.ui-indexscrollbar-indicator{position:fixed;top:0;left:0;z-index:999;display:none}.ui-indexscrollbar-indicator>span{width:84px;line-height:84px;position:absolute;display:block;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);font-size:56px;border-radius:50%;text-align:center;box-sizing:border-box;background-color:var(--control-background);color:var(--text-color)}.ui-icon-add::after{-webkit-mask-image:url(images/2_Buttons/tw_ic_ab_add_mtrl.svg);mask-image:url(images/2_Buttons/tw_ic_ab_add_mtrl.svg)}.ui-icon-delete::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_bb_delete_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_bb_delete_mtrl.svg)}.ui-icon-cancel::after{-webkit-mask-image:url(images/controls/core_button_cancel.png);mask-image:url(images/controls/core_button_cancel.png)}.ui-icon-reorder::after{-webkit-mask-image:url(images/3_Controllers/tw_list_icon_reorder.svg);mask-image:url(images/3_Controllers/tw_list_icon_reorder.svg)}.ui-icon-pause::after{-webkit-mask-image:url(images/controls/00_button_pause.png);mask-image:url(images/controls/00_button_pause.png)}.ui-icon-share::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_bb_share_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_bb_share_mtrl.svg)}.ui-icon-check::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_ab_back_mtrl.svg)}.ui-icon-move::after{-webkit-mask-image:url(images/1_App_bar/tw_ic_bb_move_mtrl.svg);mask-image:url(images/1_App_bar/tw_ic_bb_move_mtrl.svg)}.ui-icon-plus::after{-webkit-mask-image:url(images/3_Controllers/tw_list_icon_add_mtrl.svg);mask-image:url(images/3_Controllers/tw_list_icon_add_mtrl.svg)}.ui-icon-minus::after{-webkit-mask-image:url(images/3_Controllers/tw_list_icon_delete_mtrl.svg);mask-image:url(images/3_Controllers/tw_list_icon_delete_mtrl.svg)}.ui-icon-up::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_close_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_close_mtrl.svg)}.ui-icon-down::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg)}.ui-icon-left::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg);-webkit-transform:translate(-50%,-50%) rotateZ(90deg);-ms-transform:translate(-50%,-50%) rotate(90deg);transform:translate(-50%,-50%) rotateZ(90deg)}.ui-icon-right::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_open_mtrl.svg)}.ui-icon-next::after{-webkit-mask-image:url(images/3_Controllers/tw_expander_close_mtrl.svg);mask-image:url(images/3_Controllers/tw_expander_close_mtrl.svg)}.ui-btn.ui-icon-next::after,.ui-btn.ui-icon-right::after{-webkit-transform:translate(-50%,-50%) rotateZ(90deg);-ms-transform:translate(-50%,-50%) rotate(90deg);transform:translate(-50%,-50%) rotateZ(90deg)}.ui-btn.ui-icon-left::after{-webkit-transform:translate(-50%,-50%) rotateZ(-90deg);-ms-transform:translate(-50%,-50%) rotate(-90deg);transform:translate(-50%,-50%) rotateZ(-90deg)}:root{--button-fab-radius:50%;--button-fab-icon-color:var(--color-white);--button-fab-right:24px;--button-fab-bottom:24px;--button-fab-width:56px;--button-fab-height:56px;--button-fab-icon-width:24px;--button-fab-icon-height:24px}tau-button{-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start;background-color:#ddd;border-bottom-color:#ddd;border-bottom-style:outset;border-bottom-width:2px;border-image-outset:0;border-image-repeat:stretch;border-image-slice:100%;border-image-source:none;border-image-width:1;border-left-color:#ddd;border-left-style:outset;border-left-width:2px;border-right-color:#ddd;border-right-style:outset;border-right-width:2px;border-top-color:#ddd;border-top-style:outset;border-top-width:2px;box-sizing:border-box;color:#000;cursor:default;display:inline-block;font-family:Arial,'MS Trebuchet',sans-serif;font-size:13.3333330154419px;font-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal;line-height:normal;margin-bottom:0;margin-left:0;margin-right:0;margin-top:0;padding-bottom:1px;padding-left:6px;padding-right:6px;padding-top:1px;text-align:center;text-indent:0;text-rendering:auto;text-shadow:none;text-transform:none;word-spacing:0;-webkit-writing-mode:horizontal-tb;-ms-writing-mode:lr-tb;writing-mode:horizontal-tb}@-webkit-keyframes btn_pressup_animation{0%{opacity:1}33%{opacity:1}100%{opacity:0}}@keyframes btn_pressup_animation{0%{opacity:1}33%{opacity:1}100%{opacity:0}}@-webkit-keyframes btn_press_animation_nobg{0%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}100%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}}@keyframes btn_press_animation_nobg{0%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}100%{opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}}@-webkit-keyframes btn_press_animation_flat_opacity_in{0%{background-color:transparent}100%{background-color:var(--ripple-button-flat-color)}}@keyframes btn_press_animation_flat_opacity_in{0%{background-color:transparent}100%{background-color:var(--ripple-button-flat-color)}}@-webkit-keyframes btn_press_animation_flat_opacity_out{0%{background-color:var(--ripple-button-flat-color)}100%{background-color:transparent}}@keyframes btn_press_animation_flat_opacity_out{0%{background-color:var(--ripple-button-flat-color)}100%{background-color:transparent}}@-webkit-keyframes btn_press_animation_flat_icon_opacity_in{0%{background-color:var(--button-background-flat)}100%{background-color:var(--ripple-button-flat-color)}}@keyframes btn_press_animation_flat_icon_opacity_in{0%{background-color:var(--button-background-flat)}100%{background-color:var(--ripple-button-flat-color)}}@-webkit-keyframes btn_press_animation_flat_icon_opacity_out{0%{background-color:var(--ripple-button-flat-color)}100%{background-color:var(--button-background-flat)}}@keyframes btn_press_animation_flat_icon_opacity_out{0%{background-color:var(--ripple-button-flat-color)}100%{background-color:var(--button-background-flat)}}@-webkit-keyframes btn_press_animation_flat_scale{0%{-webkit-transform:translate(-50%,-50%) scale(0.95);transform:translate(-50%,-50%) scale(0.95)}100%{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@keyframes btn_press_animation_flat_scale{0%{-webkit-transform:translate(-50%,-50%) scale(0.95);transform:translate(-50%,-50%) scale(0.95)}100%{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@-webkit-keyframes btn_press_animation_flat_icon_scale{0%{-webkit-transform:translate(-50%,-50%) scale(0.95);transform:translate(-50%,-50%) scale(0.95)}100%{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@keyframes btn_press_animation_flat_icon_scale{0%{-webkit-transform:translate(-50%,-50%) scale(0.95);transform:translate(-50%,-50%) scale(0.95)}100%{-webkit-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}}@-webkit-keyframes btn_press_animation_flat_icon_scale_left{0%{-webkit-transform:translateY(-50%) scale(0.95);transform:translateY(-50%) scale(0.95)}100%{-webkit-transform:translateY(-50%) scale(1);transform:translateY(-50%) scale(1)}}@keyframes btn_press_animation_flat_icon_scale_left{0%{-webkit-transform:translateY(-50%) scale(0.95);transform:translateY(-50%) scale(0.95)}100%{-webkit-transform:translateY(-50%) scale(1);transform:translateY(-50%) scale(1)}}@-webkit-keyframes btn_press_animation_flat_icon_scale_top{0%{-webkit-transform:translateX(-50%) scale(0.95);transform:translateX(-50%) scale(0.95)}100%{-webkit-transform:translateX(-50%) scale(1);transform:translateX(-50%) scale(1)}}@keyframes btn_press_animation_flat_icon_scale_top{0%{-webkit-transform:translateX(-50%) scale(0.95);transform:translateX(-50%) scale(0.95)}100%{-webkit-transform:translateX(-50%) scale(1);transform:translateX(-50%) scale(1)}}@-webkit-keyframes animation_opacity_in{0%{opacity:0}10%{opacity:1}100%{opacity:1}}@keyframes animation_opacity_in{0%{opacity:0}10%{opacity:1}100%{opacity:1}}@-webkit-keyframes animation_opacity_out{0%{opacity:1}100%{opacity:0}}@keyframes animation_opacity_out{0%{opacity:1}100%{opacity:0}}button.ui-btn,input[type=button].ui-btn{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;border:0;outline:0}a.ui-btn{text-decoration:none;width:100%}.ui-btn{position:relative;padding:0 16px;min-height:36px;vertical-align:middle;text-overflow:ellipsis;text-align:center;color:var(--primary-color);font-size:var(--button-text-font-size);white-space:nowrap;cursor:pointer;background-color:var(--button-background);box-sizing:border-box;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;z-index:0;border-radius:18px;font-family:Roboto-Medium}.ui-btn::before{position:absolute;top:50%;left:50%;width:100%;height:100%;opacity:0;content:"";border-width:0;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.ui-btn::after{position:absolute;top:50%;left:50%;-webkit-mask-size:100% 100%;-moz-mask-size:100% 100%;-ms-mask-size:100% 100%;-o-mask-size:100% 100%;mask-size:100% 100%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-mask-repeat:no-repeat;-moz-mask-repeat:no-repeat;-ms-mask-repeat:no-repeat;-o-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;-moz-mask-position:center;-ms-mask-position:center;-o-mask-position:center;mask-position:center;-webkit-mask-size:100%;-moz-mask-size:100%;-ms-mask-size:100%;-o-mask-size:100%;mask-size:100%;content:""}.ui-btn:focus{outline:0}.ui-btn:not(.ui-btn-nobg)::before{z-index:-1;border-radius:26px;background-color:var(--ripple-color);box-sizing:border-box}.ui-btn:not(.ui-btn-nobg).ui-btn-active::before{opacity:1;-webkit-animation:btn_press_animation_flat_opacity_in linear 100ms,btn_press_animation_flat_opacity_out linear 400ms 100ms,btn_press_animation_flat_scale cubic-bezier(0.33,0,.2,1) 350ms;animation:btn_press_animation_flat_opacity_in linear 100ms,btn_press_animation_flat_opacity_out linear 400ms 100ms,btn_press_animation_flat_scale cubic-bezier(0.33,0,.2,1) 350ms}.ui-btn.ui-btn-focus{outline:2px solid var(--primary-color)}.ui-btn.ui-btn-nobg{background-color:transparent;color:var(--primary-color)}.ui-btn.ui-btn-nobg::before{background-color:var(--ripple-color);opacity:0;border-radius:50%;width:40px;height:40px;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.ui-btn.ui-btn-nobg.ui-btn-active::before{-webkit-animation:btn_press_animation_nobg linear 315ms;animation:btn_press_animation_nobg linear 315ms;opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}.ui-btn.ui-btn-nobg.ui-btn-active.ui-btn-inactive::before{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}.ui-btn.ui-btn-nobg.ui-btn-active.ui-btn-inactive::after{-webkit-animation:btn_pressup_animation 300ms linear;animation:btn_pressup_animation 300ms linear;opacity:0}.ui-btn.ui-btn-nobg.ui-btn-icon::after{background-color:var(--text-color);-webkit-mask-size:100%;mask-size:100%;-webkit-mask-position:center;mask-position:center}.ui-btn.ui-btn-nobg.ui-btn-icon.ui-btn-active::after{background-color:var(--text-color)}.ui-btn.ui-btn-nobg.ui-btn-icon.ui-icon-delete::after{background-color:F060L3;transition:background-color 15ms}.ui-btn.ui-btn-nobg.ui-btn-icon.ui-icon-delete.ui-btn-active::after{background-color:F060L3P;transition:background-color 300ms}.ui-btn.ui-btn-icon.ui-state-disabled::after{opacity:.4}.ui-btn.ui-btn-icon.ui-btn-circle{width:49px;height:49px}.ui-btn.ui-btn-icon.ui-btn-circle::after{background-color:var(--text-color)}.ui-btn.ui-btn-icon.ui-btn-nobg{width:40px;height:40px;text-indent:-4999.5px;padding:10px 0;border-radius:0}.ui-btn.ui-btn-icon.ui-btn-nobg.ui-inline{width:40px}.ui-btn.ui-btn-icon.ui-btn-nobg::after{width:25px;height:25px}.ui-btn.ui-btn-icon.ui-color-add::after{background-color:var(--btn-add-color)}.ui-btn.ui-btn-icon.ui-color-delete::after{background-color:var(--btn-delete-color)}.ui-btn.ui-inline{display:inline-block;width:auto}.ui-btn.ui-hidden{display:none}.ui-btn.ui-state-disabled{pointer-events:none;background-color:var(--button-background);color:var(--button-text-color-disabled)}.ui-btn.ui-btn-icon.ui-btn-icon-only{text-indent:-4999.5px;width:104px}.ui-btn.ui-btn-icon::after{background-color:var(--button-icon-color)}.ui-btn.ui-btn-icon.ui-btn-active::after{background-color:var(--text-color)}.ui-btn.ui-btn-icon.ui-btn-icon-left{padding-left:65px;padding-right:30px}.ui-btn.ui-btn-icon.ui-btn-icon-left::after{left:29px}.ui-btn.ui-btn-icon.ui-btn-icon-right{padding-left:30px;padding-right:65px}.ui-btn.ui-btn-icon.ui-btn-icon-right::after{right:29px;left:auto}.ui-btn.ui-btn-icon.ui-btn-icon-left::after,.ui-btn.ui-btn-icon.ui-btn-icon-right::after{top:50%;-webkit-transform:translate(0,-50%);-ms-transform:translate(0,-50%);transform:translate(0,-50%)}.ui-btn.ui-btn-icon.ui-btn-icon-top{padding-top:65px;padding-bottom:40px}.ui-btn.ui-btn-icon.ui-btn-icon-top::after{top:28px}.ui-btn.ui-btn-icon.ui-btn-icon-bottom{padding-top:40px;padding-bottom:65px}.ui-btn.ui-btn-icon.ui-btn-icon-bottom::after{bottom:28px}.ui-btn.ui-btn-icon.ui-btn-icon-top::after,.ui-btn.ui-btn-icon.ui-btn-icon-bottom::after{left:50%;-webkit-transform:translate(-50%,0);-ms-transform:translate(-50%,0);transform:translate(-50%,0)}.ui-btn.ui-btn-text-light,.ui-btn.ui-btn-text-dark{min-height:24px;height:24px;line-height:17px;min-width:48px;font-size:16px;padding:4px 12px}.ui-btn.ui-btn-text-light.ui-btn-active,.ui-btn.ui-btn-text-dark.ui-btn-active{font-size:16px}.ui-btn.ui-btn-text-light{background-color:W019}.ui-btn.ui-btn-text-light.ui-btn-active{background-color:W019P}.ui-btn.ui-btn-text-dark{background-color:W020}.ui-btn.ui-btn-text-dark.ui-btn-active::before{background-color:W020P}.ui-btn.ui-btn-flat{color:var(--primary-dark-color)}.ui-btn.ui-btn-flat::before{border-radius:22px}.ui-btn.ui-btn-flat.ui-btn-icon{color:var(--text-color);min-height:32px;max-width:32px}.ui-btn.ui-btn-flat.ui-btn-icon::after{width:32px;height:32px;border-radius:28px;-webkit-mask-size:32px;mask-size:32px}.ui-btn.ui-btn-flat.ui-btn-icon::before{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);height:32px;width:32px;border-radius:28px;background-color:var(--button-background-flat)}.ui-btn.ui-btn-flat.ui-btn-icon-top{line-height:normal;height:60px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;padding:0;color:var(--appbar-subtitle-color)}.ui-btn.ui-btn-flat.ui-btn-icon-top::after{top:auto;left:auto;border-radius:0;width:24px;height:24px;-webkit-mask-size:24px;mask-size:24px;position:relative;padding-bottom:1px;-webkit-transform:none;-ms-transform:none;transform:none;background-color:var(--bottom-button-icon-color)}.ui-btn.ui-btn-flat.ui-btn-icon-top::before{top:auto;left:auto;border-radius:12px;-webkit-transform:none;-ms-transform:none;transform:none;width:100%;height:56px;opacity:0;background-color:var(--ripple-color)}.ui-btn.ui-btn-flat.ui-btn-icon-top.ui-btn-icon.ui-btn-active::before{-webkit-animation:animation_opacity_in 200ms linear;animation:animation_opacity_in 200ms linear;-webkit-animation-fill-mode:both;animation-fill-mode:both}.ui-btn.ui-btn-flat.ui-btn-icon-top.ui-btn-icon.ui-btn-inactive::before{-webkit-animation:animation_opacity_out 50ms linear;animation:animation_opacity_out 50ms linear}.ui-btn.ui-btn-flat.ui-btn-icon-left{padding-top:13px;padding-right:8px;padding-bottom:13px;max-height:56px}.ui-btn.ui-btn-flat.ui-btn-icon-left::after{left:0}.ui-btn.ui-btn-flat.ui-btn-icon-left::before{left:0;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.ui-btn.ui-btn-flat.ui-btn-icon-left.ui-btn-icon.ui-btn-active::before{-webkit-animation:btn_press_animation_flat_icon_opacity_in linear 100ms,btn_press_animation_flat_icon_opacity_out linear 400ms 100ms,btn_press_animation_flat_icon_scale_left cubic-bezier(0.33,0,.2,1) 350ms;animation:btn_press_animation_flat_icon_opacity_in linear 100ms,btn_press_animation_flat_icon_opacity_out linear 400ms 100ms,btn_press_animation_flat_icon_scale_left cubic-bezier(0.33,0,.2,1) 350ms}.ui-btn.ui-btn-flat.ui-btn-icon.ui-btn-active::before{-webkit-animation:btn_press_animation_flat_icon_opacity_in linear 100ms,btn_press_animation_flat_icon_opacity_out linear 400ms 100ms,btn_press_animation_flat_icon_scale cubic-bezier(0.33,0,.2,1) 350ms;animation:btn_press_animation_flat_icon_opacity_in linear 100ms,btn_press_animation_flat_icon_opacity_out linear 400ms 100ms,btn_press_animation_flat_icon_scale cubic-bezier(0.33,0,.2,1) 350ms}.ui-btn.ui-btn-flat.ui-btn-disabled{opacity:.4}.ui-btn.ui-btn-contained{background-color:var(--button-background-contained);color:var(--text-color);font-size:var(--button-contained-text-font-size);border-radius:22px;width:auto;text-overflow:ellipsis;overflow:hidden;padding-top:12px;padding-bottom:12px}.ui-btn.ui-btn-contained::before{border-radius:22px}.ui-btn.ui-btn-contained:not(.ui-btn-inline){max-width:75%;width:60%;display:block;margin:0 auto}.ui-btn.ui-btn-contained.ui-state-disabled{opacity:.4;color:var(--button-text-contained-dim-color)}.ui-btn.ui-btn-contained-colored{background-color:var(--primary-dark-color);font-size:17px;color:var(--color-white)}.ui-btn.ui-btn-contained-colored.ui-state-disabled{color:var(--color-white)}.ui-btn.ui-btn-fab{position:fixed;right:var(--button-fab-right);bottom:var(--button-fab-bottom);width:var(--button-fab-width);height:var(--button-fab-height);background-color:var(--primary-color);z-index:1000;border-radius:var(--button-fab-radius)}.ui-btn.ui-btn-fab::after{background-color:var(--button-fab-icon-color);width:var(--button-fab-icon-width);height:var(--button-fab-icon-height)}.ui-btn.ui-btn-fab.ui-btn-active.ui-btn-icon::after{background-color:var(--button-fab-icon-color)}.ui-btn .ui-btn-content{width:90px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin:0 auto}.ui-btn .ui-btn-content :first-child{font-size:13px;font-family:Roboto-Regular;color:#949494}.ui-btn .ui-btn-content :nth-child(2){font-size:13px;font-family:Roboto-Medium;color:#404040}@media all and (min-width:673px) and (min-height:411px){.ui-btn.ui-btn-contained:not(.ui-btn-inline):not(.ui-btn.ui-popup-toast-has-button){max-width:60%;min-width:240px}}.ui-listview li.ui-li-has-btn{box-sizing:border-box}.ui-listview li .ui-btn.ui-btn-contained{border-radius:18px;font-size:var(--button-contained-list-text-font-size);padding-top:8px;padding-bottom:8px}.ui-listview .ui-btn-flat,.ui-listview .ui-btn-contained{margin-right:24px;margin-left:8px}.ui-li-has-btn{display:-webkit-flex;display:-ms-flexbox;display:flex;height:60px}.ui-li-has-btn .ui-btn{margin:-7px auto;max-width:248px}.ui-li-has-btn .ui-btn~.ui-btn{margin-left:8px}.ui-listview .ui-expandable,.ui-content-area .ui-expandable{padding:0 24px;-webkit-user-select:none;-ms-user-select:none;user-select:none;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-listview .ui-expandable .ui-expandable-heading,.ui-content-area .ui-expandable .ui-expandable-heading{color:var(--text-color);font-size:18px;font-weight:400;padding-top:15px;padding-bottom:16px;line-height:21px;margin:0;position:relative}.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle,.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle{position:relative;display:block}.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle:focus,.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle:focus{outline:0}.ui-listview .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle::after,.ui-content-area .ui-expandable .ui-expandable-heading .ui-expandable-heading-toggle::after{content:"";position:absolute;right:-8px;top:calc(50% - 16px);-webkit-mask-image:url(images/6_Lists/tw_expander_close_mtrl.svg);mask-image:url(images/6_Lists/tw_expander_close_mtrl.svg);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:100%;mask-size:100%;background-color:var(--expander-color);width:32px;height:32px;transition:all 330ms ease;-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}.ui-listview .ui-expandable .ui-expandable-heading .ui-btn,.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn{width:32px;height:32px;min-height:auto;position:absolute;right:-8px;top:calc(50% - 16px)}.ui-listview .ui-expandable .ui-expandable-heading .ui-btn::before,.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn::before{width:32px;height:32px;display:none}.ui-listview .ui-expandable .ui-expandable-heading .ui-btn::after,.ui-content-area .ui-expandable .ui-expandable-heading .ui-btn::after{width:32px;height:32px;-webkit-mask-size:32px;mask-size:32px;background-color:var(--expander-color);transition:all 330ms ease;-webkit-transform:translate(-50%,-50%) rotate(0);-ms-transform:translate(-50%,-50%) rotate(0);transform:translate(-50%,-50%) rotate(0)}.ui-listview .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-expandable-heading-toggle::after,.ui-content-area .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-expandable-heading-toggle::after{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.ui-listview .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-btn::after,.ui-content-area .ui-expandable.ui-expandable-collapsed .ui-expandable-heading .ui-btn::after{-webkit-transform:translate(-50%,-50%) rotate(180deg);-ms-transform:translate(-50%,-50%) rotate(180deg);transform:translate(-50%,-50%) rotate(180deg)}.ui-listview .ui-expandable .ui-expandable-content,.ui-content-area .ui-expandable .ui-expandable-content{transition:all 330ms ease;overflow:auto}.ui-listview .ui-expandable .ui-expandable-content .ui-listview,.ui-content-area .ui-expandable .ui-expandable-content .ui-listview{padding:0;margin-left:18px}.ui-listview .ui-expandable .ui-expandable-content .ui-listview li,.ui-content-area .ui-expandable .ui-expandable-content .ui-listview li{color:var(--expandable-text-color);padding-top:15px;padding-bottom:16px;line-height:21px;margin:0}.ui-listview .ui-expandable .ui-expandable-content-collapsed,.ui-content-area .ui-expandable .ui-expandable-content-collapsed{overflow:hidden;max-height:0!important;display:none;transition:all 330ms ease}.ui-listview .ui-expandable.ui-state-disabled,.ui-content-area .ui-expandable.ui-state-disabled{cursor:default!important;pointer-events:none;zoom:1}.ui-listview .ui-expandable.ui-state-disabled .ui-expandable-heading .ui-expandable-heading-toggle::after,.ui-content-area .ui-expandable.ui-state-disabled .ui-expandable-heading .ui-expandable-heading-toggle::after{background-color:var(--control-background)}.ui-expandable-from~:not(.ui-expandable-to){display:none}.ui-listview .ui-expandable-from~:not(.ui-expandable-to){display:none}.ui-expandable-from.ui-expandable-expanded~:not(.ui-expandable-to){display:inherit}.ui-listview .ui-expandable-to~:not(.ui-expandable-from){display:inherit}.ui-expandable-to .ui-btn.ui-btn-flat,.ui-expandable-from .ui-btn.ui-btn-flat{width:32px;height:32px;min-height:auto;margin:auto}.ui-expandable-to .ui-btn.ui-btn-flat::before,.ui-expandable-from .ui-btn.ui-btn-flat::before{width:32px;height:32px}.ui-expandable-to .ui-btn.ui-btn-flat::after,.ui-expandable-from .ui-btn.ui-btn-flat::after{width:32px;height:32px;-webkit-mask-size:32px;mask-size:32px;background-color:var(--expander-color);transition:all 330ms ease;-webkit-transform:translate(-50%,-50%) rotate(0);-ms-transform:translate(-50%,-50%) rotate(0);transform:translate(-50%,-50%) rotate(0)}.ui-expandable-from .ui-btn.ui-btn-flat{position:absolute;right:-6px}.ui-expandable-from.ui-expandable-expanded~.ui-expandable-to .ui-btn.ui-btn-flat::after,.ui-expandable-from.ui-expandable-expanded .ui-btn.ui-btn-flat::after{-webkit-transform:translate(-50%,-50%) rotate(180deg);-ms-transform:translate(-50%,-50%) rotate(180deg);transform:translate(-50%,-50%) rotate(180deg)}.ui-floatingactions{position:fixed;right:0;bottom:21.5px;height:60px;padding-left:15px;padding-right:15px;-webkit-transform:translate3d(12px,0,0);transform:translate3d(12px,0,0);-webkit-mask-box-image-repeat:repeat;-moz-mask-box-image-repeat:repeat;-ms-mask-box-image-repeat:repeat;-o-mask-box-image-repeat:repeat;mask-box-image-repeat:repeat;-webkit-mask-box-image-width:auto;-moz-mask-box-image-width:auto;-ms-mask-box-image-width:auto;-o-mask-box-image-width:auto;mask-box-image-width:auto;-webkit-mask-box-image-source:url(images/nine-patch/core_floating_button_bg.png);-webkit-mask-box-image-slice:60 64 60 64 fill;-moz-mask-box-image-slice:60 64 60 64 fill;-ms-mask-box-image-slice:60 64 60 64 fill;-o-mask-box-image-slice:60 64 60 64 fill;mask-box-image-slice:60 64 60 64 fill;background-color:var(--primary-dark-color);z-index:1000}.ui-floatingactions.ui-floatingactions-transitions{transition-property:all;transition-duration:500ms}.ui-floatingactions .ui-btn{display:inline-block;width:60px;height:60px;margin:0;background-color:transparent;color:var(--primary-color)}.ui-floatingactions .ui-btn.ui-btn-icon{width:60px}.ui-floatingactions .ui-btn::before{background-color:var(--ripple-color);opacity:0;border-radius:50%;width:40px;height:40px;-webkit-transform:translate(-50%,-50%) scale(1);-ms-transform:translate(-50%,-50%) scale(1);transform:translate(-50%,-50%) scale(1)}.ui-floatingactions .ui-btn.ui-btn-active::before{-webkit-animation:btn_press_animation_nobg linear 315ms;animation:btn_press_animation_nobg linear 315ms;opacity:1;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}.ui-floatingactions .ui-btn.ui-btn-active.ui-btn-inactive::before{opacity:0;-webkit-transform:translate(-50%,-50%) scale(1.425);-ms-transform:translate(-50%,-50%) scale(1.425);transform:translate(-50%,-50%) scale(1.425)}.ui-floatingactions .ui-btn.ui-btn-active.ui-btn-inactive::after{-webkit-animation:btn_pressup_animation 300ms linear;animation:btn_pressup_animation 300ms linear;opacity:0}.ui-floatingactions .ui-btn.ui-btn-icon::after{background-color:var(--text-color);-webkit-mask-size:100%;mask-size:100%;-webkit-mask-position:center;mask-position:center}.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-active::after{background-color:var(--text-color)}.ui-floatingactions .ui-btn.ui-btn-icon.ui-icon-delete::after{background-color:F060L3;transition:background-color 15ms}.ui-floatingactions .ui-btn.ui-btn-icon.ui-icon-delete.ui-btn-active::after{background-color:F060L3P;transition:background-color 300ms}.ui-floatingactions .ui-btn::before{background-color:var(--ripple-color)}.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left{padding:0}.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:40px;height:40px;background-color:var(--color-white);z-index:-100}.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active ::after{background-color:var(--ripple-color)}.ui-floatingactions .ui-btn.ui-icon-floating-add::after{-webkit-mask-image:url(images/controls/core_floating_icon_add.png);mask-image:url(images/controls/core_floating_icon_add.png)}.ui-floatingactions .ui-btn.ui-icon-floating-search::after{-webkit-mask-image:url(images/controls/core_floating_icon_search.png);mask-image:url(images/controls/core_floating_icon_search.png)}.ui-floatingactions .ui-btn-focus{outline:0;background-color:rgba(50,150,166,.4)}.ui-floatingactions .ui-btn~.ui-btn{margin-left:-10px}.ui-floatingactions.ui-floatingactions-expand-to-right{padding-right:30px;right:-15px}.ui-floatingactions.ui-floatingactions-expand-to-left{padding-left:30px}.ui-floatingactions:focus{outline:0;background-color:rgba(78,97,173,.8)}.ui-floatingactions-reposition:focus{background-color:var(--ripple-color)}.ui-content .ui-floatingactions,.ui-tabs .ui-floatingactions{background-color:var(--primary-dark-color)}.ui-content .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after,.ui-tabs .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after{background-color:var(--color-white)}.ui-content .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after,.ui-tabs .ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after{background-color:var(--ripple-color)}.ui-content .ui-floatingactions .ui-btn::before,.ui-tabs .ui-floatingactions .ui-btn::before{background-color:var(--ripple-color)}.ui-content .ui-floatingactions:focus,.ui-tabs .ui-floatingactions:focus{outline:0;background-color:rgba(78,97,173,.8)}.ui-content .ui-floatingactions-reposition:focus,.ui-tabs .ui-floatingactions-reposition:focus{background-color:var(--ripple-color)}.ui-indexscrollbar~.ui-floatingactions{background-color:var(--primary-dark-color)}.ui-indexscrollbar~.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left::after{background-color:var(--color-white)}.ui-indexscrollbar~.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-icon-left.ui-btn-active::after{background-color:var(--ripple-color)}.ui-indexscrollbar~.ui-floatingactions .ui-btn::before{background-color:var(--ripple-color)}.ui-listview~.ui-floatingactions .ui-btn.ui-btn-icon::after{background-color:var(--color-white)}.ui-listview~.ui-floatingactions .ui-btn.ui-btn-icon.ui-btn-active::after{background-color:var(--ripple-color)}.ui-page-floatingactions.ui-empty-state .ui-content{box-sizing:border-box;border-bottom:127px solid transparent}tau-listview{display:block;list-style-type:disc;-webkit-margin-before:1em;-webkit-margin-after:1em;-webkit-margin-start:0;-webkit-margin-end:0;-webkit-padding-start:40px}tau-expandable{display:list-item;text-align:-webkit-match-parent}.ui-listview{margin:auto;padding:0;list-style:none;counter-reset:listnumbering;position:relative;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@media (min-width:673px) and (min-height:411px){.ui-listview{width:90%}}@media (min-width:960px){.ui-listview{width:75%}}.ui-listview.ui-content-area{margin-bottom:16px}.ui-listview.ui-content-area+button[data-style=fab]{display:block;min-height:0;margin-bottom:108px}.ui-listview li{display:-webkit-flex;display:-ms-flexbox;display:flex;position:relative;box-sizing:content-box;overflow:visible;text-align:left;font-size:18px}.ui-listview li[disabled]{opacity:.4}.ui-listview li.ui-li-subheader{margin-left:20px;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-listview li.ui-li-subheader:empty{margin-top:16px}.ui-listview li.ui-li-subheader .ui-li-text-subheader{display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;color:var(--text-secondary-color);font-family:Roboto-Medium;font-size:14px;margin-left:4px;margin-right:16px;min-height:36px;-webkit-align-items:center;-ms-flex-align:center;align-items:center;white-space:nowrap}.ui-listview li.ui-li-subheader::after{content:"";display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;width:calc(100% - 20px);border-bottom:3px dotted var(--subheader-divider-color);height:0;-webkit-align-items:center;-ms-flex-align:center;align-items:center;margin-right:20px}.ui-listview li.ui-li-anchor{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:14px 0;margin:0 24px}.ui-listview li.ui-li-has-text-input{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:18px 0 8px;margin:0 24px}.ui-listview li .ui-li-checkbox-icon{-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li .ui-li-checkbox-icon img{width:40px;height:40px;margin-right:18px;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-listview li .ui-li-icon{width:40px;height:40px;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;position:relative;-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;margin:0 12px}.ui-listview li .ui-li-icon.ui-li-icon-small,.ui-listview li .ui-li-icon.ui-li-icon-small:after{width:25px!important;height:25px!important}.ui-listview li .ui-li-icon::after,.ui-listview li .ui-li-icon *{content:"";position:absolute;width:40px;height:40px;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-position:center center;mask-position:center center}.ui-listview li .ui-li-text{display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:15px 0;margin-right:24px}.ui-listview li .ui-li-text .ui-li-text-title{font-size:18px;color:var(--text-color);line-height:21px;vertical-align:middle}.ui-listview li .ui-li-text .ui-li-text-title:only-child{padding-bottom:1px}.ui-listview li .ui-li-text .ui-li-text-title+.ui-li-text-sub::before{content:"";display:block;height:4px}.ui-listview li .ui-li-text .ui-li-text-sub{font-size:13px;color:var(--text-secondary-color);line-height:15px}.ui-listview li .ui-li-text .ui-li-text-sub+.ui-li-text-title::before{content:"";display:block;height:4px}.ui-listview li .ui-li-text .ui-li-text-sub img{width:15px;height:15px}.ui-listview li .ui-li-text .ui-li-text-value{color:var(--primary-color)}.ui-listview li>.ui-li-text:first-child{margin-left:24px}.ui-listview li.ui-li-divider::after{content:"";position:absolute;width:calc(100% - 40px);left:20px;bottom:-.75px;height:.75px;background-color:var(--divider-color);opacity:var(--divider-opacity)}.ui-listview li.ui-li-divider.ui-li-has-icon::after{width:calc(100% - 84px);left:64px}.ui-listview li.ui-li-divider.ui-li-has-checkbox::after,.ui-listview li.ui-li-divider.ui-li-has-radio::after{width:calc(100% - 92px);left:68px}.ui-listview li.ui-li-divider.ui-li-has-checkbox-icon::after{left:126px}.ui-listview li+li.ui-li-divider{margin-top:.75px}.ui-listview li .ui-li-divider{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;margin-left:12px;margin-right:9px}.ui-listview li .ui-li-divider::after{content:"";position:absolute;width:.5px;height:22px;background-color:var(--on-off-switch-divider-color)}.ui-listview li .ui-li-action{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;margin-left:auto;white-space:nowrap}.ui-listview li .ui-li-action .ui-on-off-switch-container{margin-right:24px}.ui-listview li .ui-li-right{margin-left:auto!important}.ui-listview li .ui-li-text-ellipse{min-width:0;white-space:nowrap}.ui-listview li .ui-li-text-ellipse *{text-overflow:ellipsis;overflow:hidden}.ui-listview li input[type=checkbox].ui-checkbox,.ui-listview li input[type=radio].ui-radio{-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li.ui-li-selected{background-color:var(--list-item-selected-color)}.ui-listview li,.ui-listview tau-expandable{box-shadow:none}.ui-listview li .ui-link-inherit,.ui-listview tau-expandable .ui-link-inherit{color:var(--text-color)}.ui-listview li:not(.ui-expandable).ui-li-active,.ui-listview tau-expandable:not(.ui-expandable).ui-li-active{background-color:var(--active)}.ui-listview li.ui-li-active.ui-expandable .ui-expandable-heading,.ui-listview tau-expandable.ui-li-active.ui-expandable .ui-expandable-heading{background-color:var(--active)}.ui-listview li>a:not(.ui-btn),.ui-listview tau-expandable>a:not(.ui-btn){display:block;width:100%;height:100%;margin:-16.5px -16px;padding:16.5px 16px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;color:var(--text-color);text-decoration:none;box-sizing:border-box}.ui-listview.ui-listview-focus{box-sizing:border-box;border:2px solid #00f}.ui-listview .ui-listview-item-focus{background-color:var(--ripple-color)}.ui-listview .ui-listview-item-focus a{outline:0}.ui-listview .ui-listview-background{display:block;box-sizing:border-box;position:absolute;top:0;left:0;pointer-events:none;z-index:-1}.ui-listview .ui-listview-background::before{content:"250,250,250,1::0,0,0,-0.04";display:none}.ui-listview.ui-listview-background-disabled .ui-listview-background{display:none}.ui-listview .ui-li-static{}.ui-listview .ui-li-static.ui-li-select-all{color:var(--background-color)}.ui-listview .ui-li-static.ui-li-select-all label{display:block}.ui-listview .ui-li-static.ui-li-select-all label input[type=checkbox]{float:right}.ui-listview .ui-li-static.li-has-thumb .li-thumb{position:absolute;left:16px;top:50%;margin-top:-13px;width:25px;height:25px}.ui-listview .ui-li-static.li-has-thumb .li-thumb.li-thumb-circle{border-radius:100%}.ui-listview .ui-li-static.li-has-thumb.li-thumbnail-right .li-thumb{float:right;left:auto;right:16px}.ui-listview .ui-li-static.li-has-progress{padding:12px 16px 11px}.ui-listview .ui-li-static.li-has-progress .ui-progress{margin:16px 0 10px}.ui-listview .ui-li-static .ui-btn.ui-btn-icon.ui-btn-nobg::after{width:40px;height:40px}.ui-listview li.ui-li-flex{display:-webkit-flex;display:-ms-flexbox;display:flex;padding:0;overflow-x:visible;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex.ui-li-select-all{color:var(--background-color)}.ui-listview li.ui-li-flex.ui-li-select-all label{display:block}.ui-listview li.ui-li-flex.ui-li-select-all label input[type=checkbox]{float:right}.ui-listview li.ui-li-flex .ui-li-text{display:-webkit-flex;display:-ms-flexbox;display:flex;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:18px;color:var(--text-color);max-height:24.25px;width:100%}.ui-listview li.ui-li-flex .ui-li-text>:not(.ui-li-text-sub-2){-webkit-flex:1;-ms-flex:1;flex:1;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text .ui-li-text-sub-2{-webkit-align-self:flex-end;-ms-align-self:flex-end;-o-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end}.ui-listview li.ui-li-flex .ui-li-text-2{color:var(--text-secondary-color);line-height:21.5px;font-size:13px;max-height:17.5px;display:-webkit-flex;display:-ms-flexbox;display:flex;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text-2>:not(.ui-li-text-sub-3){-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text-2 .ui-li-text-sub-3{-webkit-align-self:flex-end;-ms-align-self:flex-end;-o-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;margin:auto 0 auto auto}.ui-listview li.ui-li-flex .ui-li-text-2 span+.ui-li-text-sub-3{margin-left:16px}.ui-listview li.ui-li-flex .ui-li-text-sub{line-height:21.5px;font-size:16px;color:var(--text-secondary-color);display:-webkit-flex;display:-ms-flexbox;display:flex;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text-sub>:not(.ui-li-text-sub-3){-webkit-flex:1;-ms-flex:1;flex:1;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-listview li.ui-li-flex .ui-li-text-sub .ui-li-text-sub-3{-webkit-align-self:flex-end;-ms-align-self:flex-end;-o-align-self:flex-end;-ms-flex-item-align:end;align-self:flex-end;margin:auto 0 auto auto}.ui-listview li.ui-li-flex .ui-li-text-sub span+.ui-li-text-sub-3{margin-left:16px}.ui-listview li.ui-li-flex .ui-li-text-sub-2{line-height:27px;max-width:109px;margin-left:16px;font-size:15px;color:var(--text-secondary-color);float:right}.ui-listview li.ui-li-flex .ui-li-text-sub-3{line-height:22px;max-width:109px;margin-left:16px;font-size:16px;color:var(--text-secondary-color);float:right}.ui-listview li.ui-li-flex .ui-li-text-sub+.ui-li-text-sub-3{margin-top:-1rem}.ui-listview li.ui-li-flex .ui-li-area-a{position:relative;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-order:1;-ms-flex-order:1;order:1;min-width:1%;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;margin-top:16.5px;margin-bottom:16.5px;padding:0 24px 0 18px}.ui-listview li.ui-li-flex .ui-li-area-b{-webkit-order:0;-ms-flex-order:0;order:0;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-image,.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-circle-image,.ui-listview li.ui-li-flex .ui-li-area-b.ui-li-icon{margin-left:16px}.ui-listview li.ui-li-flex .ui-li-area-c{-webkit-order:3;-ms-flex-order:3;order:3;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-image,.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-circle-image{margin-right:16px}.ui-listview li.ui-li-flex .ui-li-area-c.ui-li-icon{margin-right:8.5px}.ui-listview li.ui-li-flex .ui-li-area-c .ui-toggle-container{margin-right:16px}.ui-listview li.ui-li-flex .ui-li-area-d{-webkit-order:2;-ms-flex-order:2;order:2;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-image,.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-circle-image{margin-right:16px}.ui-listview li.ui-li-flex .ui-li-area-d.ui-li-icon{margin-right:16px}.ui-listview li.ui-li-flex input.ui-li-area-b[type=checkbox],.ui-listview li.ui-li-flex input.ui-li-area-b[type=radio]{margin-left:18px;margin-right:0}.ui-listview li.ui-li-flex input.ui-li-area-c[type=checkbox],.ui-listview li.ui-li-flex input.ui-li-area-c[type=radio]{margin-right:16px}.ui-listview li.ui-li-flex input.ui-li-area-d[type=checkbox],.ui-listview li.ui-li-flex input.ui-li-area-d[type=radio],.ui-listview li.ui-li-flex input.ui-li-area-d .ui-li-image,.ui-listview li.ui-li-flex input.ui-li-area-d .ui-li-circle-image{margin-right:16px}.ui-listview li.ui-li-flex .ui-li-icon::after{content:"";position:absolute;width:100%;height:100%;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-position:center center;mask-position:center center;left:50%;top:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.ui-listview li.ui-li-flex .ui-li-area.ui-li-image{width:60px;height:60px}.ui-listview li.ui-li-flex .ui-li-area.ui-li-circle-image{width:49px;height:49px;border-radius:100%}.ui-listview li.ui-li-flex .ui-li-area.ui-li-icon{width:32px;height:32px;position:relative}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon{width:25px;min-width:25px;max-width:25px;height:25px;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;position:relative;margin-left:16px}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon.ui-li-icon-left{-webkit-order:-1;-ms-flex-order:-1;order:-1;margin-right:6px;margin-left:0}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-a .ui-li-icon.ui-li-icon-middle{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%)}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-c.ui-li-icon{width:40px;height:40px;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-c.ui-li-icon:after{width:25px;height:25px}.ui-listview li.ui-li-flex .ui-li-area.ui-li-area-d.ui-li-icon{width:25px;height:25px}.ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a{margin-top:12px;margin-bottom:12px;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-listview li.ui-li-flex.ui-li-multilines .ui-li-area-a>.ui-li-icon{position:absolute;right:16px}.ui-listview li.ui-li-flex.ui-li-flex-reverse .ui-li-area{-webkit-flex-direction:column-reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.ui-listview.ui-details .ui-li-static{color:var(--text-color);padding:12px 16px 11.5px;height:48.5px;line-height:27px}.ui-listview.ui-details .ui-li-static.li-has_icon{padding:64px 16px 11.5px}.ui-listview.ui-details .ui-li-static.li-has_icon img{position:absolute;top:20px;left:16px}.ui-listview.ui-details .ui-li-static .li-text-sub{color:var(--text-secondary-color);height:21.5px;position:initial;float:none;text-align:left;display:block;line-height:21.5px}.ui-listview.ui-details .ui-listview-background{display:none}.ui-listview .li-has-right-btn .ui-btn,.ui-listview .li-has-right-circle-btn .ui-btn{position:absolute;top:50%;right:16px;-webkit-transform:translate(0,-50%);-ms-transform:translate(0,-50%);transform:translate(0,-50%)}.ui-listview .li-has-right-btn .ui-toggle-container,.ui-listview .li-has-right-circle-btn .ui-toggle-container{position:absolute;top:50%;right:16px;-webkit-transform:translate(0,-50%);-ms-transform:translate(0,-50%);transform:translate(0,-50%)}.ui-listview .li-has-right-btn .ui-toggle-container:first-child:not(:only-child),.ui-listview .li-has-right-circle-btn .ui-toggle-container:first-child:not(:only-child){right:60px}.ui-listview .li-has-right-btn .ui-btn-icon.ui-btn-nobg,.ui-listview .li-has-right-circle-btn .ui-btn-icon.ui-btn-nobg{right:8.5px}.ui-listview .li-has-right-btn .ui-btn-icon.ui-btn-circle,.ui-listview .li-has-right-circle-btn .ui-btn-icon.ui-btn-circle{right:16px}.ui-listview .li-has-radio.li-has-right-radio .ui-radio{margin-top:0;position:absolute;right:13px;left:auto;top:18px}.ui-listview .li-has-radio.li-has-right-radio .ui-radio:first-child{right:60px}.ui-listview.ui-drag-mode li{}.ui-listview.ui-drag-mode li .ui-listview-handler{display:block;position:relative;width:32px;height:32px;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto;-webkit-order:10;-ms-flex-order:10;order:10;margin:auto 16px auto auto}.ui-listview.ui-drag-mode li .ui-listview-handler::after{content:"";position:absolute;width:100%;height:100%;-webkit-mask-size:100%;mask-size:100%;background-color:var(--reorder-color)}.ui-listview.ui-snapshot{height:100%}.ui-listview.ui-snapshot li{position:absolute;width:100%;box-sizing:border-box;transition:top .1s linear}.ui-listview.ui-snapshot li.ui-listview-helper{transition:none;background-color:var(--holder-reoder-background);box-sizing:border-box;border:.25px solid var(--holder-reoder-border)}.ui-listview.ui-snapshot li.ui-listview-helper::after{display:none}.ui-listview.ui-snapshot li.ui-listview-item.ui-listview-holder{background:0}.ui-listview.ui-snapshot li.ui-listview-item-moved{opacity:.75;transition:opacity .1s}.ui-listview.ui-snapshot li:nth-last-child(2){transition:none}.ui-listview.ui-activate-handlers li .ui-listview-handler{-webkit-animation:button-handler-activate 200ms linear alternate;animation:button-handler-activate 200ms linear alternate}.ui-listview.ui-deactivate-handlers li .ui-listview-handler{-webkit-animation:button-handler-deactivate 200ms linear alternate;animation:button-handler-deactivate 200ms linear alternate}.ui-listview.ui-cancel-animation li .ui-listview-handler{-webkit-animation:none;animation:none}.ui-listview[data-colored-background=false]{background-color:var(--background-area-color)}.ui-listview[data-colored-background=false] li:not(.ui-group-index){border-bottom:1px solid #e6e6e6;box-sizing:border-box}@-webkit-keyframes button-handler-activate{0%{margin-right:-40px}100%{margin-right:0}}@keyframes button-handler-activate{0%{margin-right:-40px}100%{margin-right:0}}@-webkit-keyframes button-handler-deactivate{0%{margin-right:0}100%{margin-right:-40px}}@keyframes button-handler-deactivate{0%{margin-right:0}100%{margin-right:-40px}}.ui-page-indicator{display:block;position:absolute;left:50%;bottom:10px;-webkit-transform:translate3d(-50%,0,0);-ms-transform:translate3d(-50%,0,0);transform:translate3d(-50%,0,0)}.ui-page-indicator-item{position:relative;display:inline-block;width:16px;height:16px;-webkit-mask-image:-webkit-radial-gradient(#000 4px,transparent 5.5px);-webkit-transform:scale3d(0.7,.7,1);-ms-transform:scale3d(0.7,.7,1);transform:scale3d(0.7,.7,1);background-color:var(--primary-dark-color);margin-right:10px;transition-duration:150ms}.ui-page-indicator-item:last-child{margin-right:0}.ui-page-indicator-item.ui-page-indicator-active{background-color:var(--primary-dark-color);-webkit-transform:scale3d(1,1,1);-ms-transform:scale3d(1,1,1);transform:scale3d(1,1,1);transition-duration:150ms}.ui-page-indicator-dashed .ui-page-indicator-item{position:relative;display:inline-block;width:20px;height:20px;-webkit-mask-image:url(images/core_page_indicator_off.png);mask-image:url(images/core_page_indicator_off.png);-webkit-transform:rotate(0deg);-ms-transform:rotate(0deg);transform:rotate(0deg);background-color:var(--primary-dark-color);margin-right:1px;transition-duration:150ms;-webkit-mask-size:20px;-moz-mask-size:20px;-ms-mask-size:20px;-o-mask-size:20px;mask-size:20px}.ui-page-indicator-dashed .ui-page-indicator-item::before{content:"";position:absolute;width:20px;height:20px;-webkit-mask-image:url(images/core_page_indicator_off_ef.png);mask-image:url(images/core_page_indicator_off_ef.png);-webkit-mask-size:20px;-moz-mask-size:20px;-ms-mask-size:20px;-o-mask-size:20px;mask-size:20px}.ui-page-indicator-dashed .ui-page-indicator-item:last-child{margin-right:0}.ui-page-indicator-dashed .ui-page-indicator-item.ui-page-indicator-active{background-color:var(--primary-dark-color);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg);transition-duration:150ms}tau-progress{display:block}.ui-progress-container{width:360px;height:inherit;position:absolute;top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);box-sizing:border-box}.ui-progress-bar{position:relative;min-width:12px;-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;height:32px;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-ms-grid-column-align:center;justify-items:center}.ui-progress-bar .ui-progress-current-value{font-size:36px}.ui-progress-text{padding-top:17px;display:block;font-size:15px;text-align:center;color:var(--text-color)}.ui-progress-bar-labels-top{-webkit-order:1;-ms-flex-order:1;order:1;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-progress-bar-labels-bottom{-webkit-order:3;-ms-flex-order:3;order:3;display:-webkit-flex;display:-ms-flexbox;display:flex}.ui-progress-bar-value-bg{height:3px;max-height:3px;width:100%;position:relative;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-order:2;-ms-flex-order:2;order:2;background-color:var(--progress-bar-bg-color);border-radius:1.5px}.ui-progress-bar-label span~span{margin-left:2px}.ui-progress-bar-label-left-bottom{padding:4px 0 0;color:var(--text-secondary-color);font-size:16px;-webkit-flex:1;-ms-flex:1;flex:1;text-align:left;line-height:normal}.ui-progress-bar-label-right-bottom{padding:4px 0 0;color:var(--text-secondary-color);font-size:16px;-webkit-flex:1;-ms-flex:1;flex:1;text-align:right;line-height:normal}.ui-progress-bar-label-right-top{padding:0 0 4px;color:var(--progress-bar-color);font-size:16px;-webkit-flex:1;-ms-flex:1;flex:1;text-align:right;line-height:normal}.ui-progress-bar-value{height:3px;position:absolute;left:0;top:0;background-color:var(--progress-bar-color);border-radius:1.5px}.ui-progress-circle.ui-progress-circle-full{position:fixed;top:0;left:0;width:100%;height:100%}.ui-progress-circle.ui-progress-circle-large{width:124px;height:124px}.ui-progress-circle.ui-progress-circle-medium{width:56px;height:56px}.ui-progress-circle.ui-progress-circle-small{width:44px;height:44px}.ui-progress-circle{position:relative;display:inline-block;box-sizing:border-box}.ui-progress-circle *{pointer-events:none}.ui-progress-circle .ui-progress-circle-value.ui-progress-circle-half{box-sizing:border-box;clip:rect(auto,auto,auto,auto)}.ui-progress-circle .ui-progress-circle-value.ui-progress-circle-half .ui-progress-circle-value-right{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.ui-progress-circle .ui-progress-circle-value{clip:rect(0,1em,1em,.5em);width:100%;height:100%;position:absolute;box-sizing:border-box}.ui-progress-circle .ui-progress-circle-value .ui-progress-circle-value-left{border:2px solid var(--primary-color);border-radius:50%;clip:rect(0,.5em,1em,0);height:100%;width:100%;position:absolute;box-sizing:border-box}.ui-progress-circle .ui-progress-circle-value .ui-progress-circle-value-right{border:2px solid var(--primary-color);border-radius:50%;clip:rect(0,.5em,1em,0);width:100%;height:100%;position:absolute;box-sizing:border-box}.ui-progress-circle .ui-progress-circle-bg{border:2px solid var(--progress-background-color);border-radius:50%;width:100%;height:100%;box-sizing:border-box}.ui-indeterminate-bar{overflow:hidden;position:relative;height:3px;border-radius:1.5px;background-color:var(--progress-bar-bg-color)}.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate{position:relative;top:0;height:100%;padding:0;background-color:transparent;border-radius:1.5px}.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate::before{content:"";position:absolute;width:46%;left:0;top:0;height:100%;background-color:var(--progress-bar-color);-webkit-animation:indeterminate-bar1 1200ms infinite linear;animation:indeterminate-bar1 1200ms infinite linear}.ui-indeterminate-bar .ui-indeterminate-bar-indeterminate::after{content:"";position:absolute;width:46%;left:93%;top:0;height:100%;background-color:var(--progress-bar-color);-webkit-animation:indeterminate-bar2 1200ms infinite linear;animation:indeterminate-bar2 1200ms infinite linear}@-webkit-keyframes indeterminate-bar1{0%{left:-30%}74.9%{left:100%;opacity:1}75%{left:-70%;opacity:0}75.1%{left:-70%;opacity:1}100%{left:-30%}}@keyframes indeterminate-bar1{0%{left:-30%}74.9%{left:100%;opacity:1}75%{left:-70%;opacity:0}75.1%{left:-70%;opacity:1}100%{left:-30%}}@-webkit-keyframes indeterminate-bar2{0%{left:93%}59.9%{left:232%;opacity:1}60%{left:-46%;opacity:0}60.1%{left:-46%;opacity:1}100%{left:93%}}@keyframes indeterminate-bar2{0%{left:93%}59.9%{left:232%;opacity:1}60%{left:-46%;opacity:0}60.1%{left:-46%;opacity:1}100%{left:93%}}@-webkit-keyframes rotating{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotating{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.ui-indeterminate-circle{box-sizing:border-box;margin:auto;-webkit-animation:rotating 2s linear infinite;animation:rotating 2s linear infinite}.ui-indeterminate-circle::before{content:"";border-top-style:solid;border-left-style:solid;border-color:var(--progress-circle-second-color);border-radius:100% 0 0;display:block}.ui-indeterminate-circle::after{content:"";position:relative;left:50%;border-right-style:solid;border-bottom-style:solid;border-color:var(--primary-color);display:block;border-radius:100% 0}.ui-indeterminate-circle-small-title{width:16px;height:16px}.ui-indeterminate-circle-small-title::before,.ui-indeterminate-circle-small-title::after{width:6.5px;height:6.5px}.ui-indeterminate-circle-small-title::before{border-top-width:1.5px;border-left-width:1.5px}.ui-indeterminate-circle-small-title::after{border-right-width:1.5px;border-bottom-width:1.5px}.ui-indeterminate-circle-small{width:24px;height:24px}.ui-indeterminate-circle-small::before,.ui-indeterminate-circle-small::after{width:10px;height:10px}.ui-indeterminate-circle-small::before{border-top-width:2px;border-left-width:2px}.ui-indeterminate-circle-small::after{border-right-width:2px;border-bottom-width:2px}.ui-indeterminate-circle-medium{width:48px;height:48px}.ui-indeterminate-circle-medium::before,.ui-indeterminate-circle-medium::after{width:21px;height:21px}.ui-indeterminate-circle-medium::before{border-top-width:3px;border-left-width:3px}.ui-indeterminate-circle-medium::after{border-right-width:3px;border-bottom-width:3px}.ui-indeterminate-circle-large{width:60px;height:60px}.ui-indeterminate-circle-large::before,.ui-indeterminate-circle-large::after{width:27px;height:27px}.ui-indeterminate-circle-large::before{border-top-width:3px;border-left-width:3px}.ui-indeterminate-circle-large::after{border-right-width:3px;border-bottom-width:3px}.ui-listview .ui-li-has-progress{height:4px;padding:28px 0}.ui-listview .ui-li-has-progress-with-labels{height:4px;padding:34px 0}.ui-scrollview-view>.ui-progress-container{padding-left:56px;padding-right:56px}.ui-listview .ui-group-index+.ui-li-static{padding-top:16.5px;padding-bottom:16.5px}.ui-listview .ui-group-index~.ui-li-static>input[type=checkbox]{position:absolute;right:16px;top:17.5px}tau-textenveloper{display:block}.ui-text-enveloper{z-index:1;position:relative;background-color:transparent;display:-webkit-flex;display:-ms-flexbox;display:flex;outline:0;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;overflow-x:visible}.ui-text-enveloper.ui-text-enveloper-with-container{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-align-content:stretch;-ms-flex-line-pack:stretch;align-content:stretch}.ui-text-enveloper.ui-text-enveloper-with-container .ui-text-enveloper-container{-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;white-space:pre-wrap;overflow:visible}.ui-text-enveloper .ui-text-enveloper-start{line-height:27px;height:27px;font-size:20px;margin-top:6.5px;color:var(--primary-color);margin-right:10px;display:inline-block;-webkit-flex-grow:0;-ms-flex-positive:0;flex-grow:0;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn{position:relative;line-height:27px;height:40px;border-radius:7.5px;font-size:20px;margin-top:-1px;padding:7px 6px 6px;margin-left:-6px;min-height:40px;vertical-align:top;-webkit-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;background-color:transparent;color:var(--primary-color);overflow:auto}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded::before,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn::before{top:50%;left:50%;width:100%;height:100%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);border-radius:0;opacity:0}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded::after,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn::after{position:absolute;content:"";top:50%;left:50%;width:100%;height:100%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;transition:opacity linear 200ms;-webkit-mask-box-image-source:url(images/nine-patch/core_focus_round.png);-webkit-mask-box-image-slice:20 20 fill;-moz-mask-box-image-slice:20 20 fill;-ms-mask-box-image-slice:20 20 fill;-o-mask-box-image-slice:20 20 fill;mask-box-image-slice:20 20 fill;background-color:var(--text-input-underline-active)}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-blur,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-blur{display:none}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-blur+span,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-blur+span{display:none}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-text-enveloper-btn-selected::after,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-text-enveloper-btn-selected::after{opacity:1}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-btn-active::before,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-btn-active::before{opacity:1;background-color:var(--ripple-color);-webkit-animation:navigation_press_animation linear 315ms;animation:navigation_press_animation linear 315ms}.ui-text-enveloper .ui-btn.ui-text-enveloper-btn-expanded.ui-btn-active.ui-btn-inactive::before,.ui-text-enveloper .ui-btn.ui-text-enveloper-btn.ui-btn-active.ui-btn-inactive::before{-webkit-animation:navigation_pressup_animation linear 200ms;animation:navigation_pressup_animation linear 200ms}.ui-text-enveloper .ui-text-enveloper-btn.ui-btn:not(.ui-inline){margin-left:3px;padding-left:5px;border-bottom:1px solid var(--primary-color);overflow:visible;border-radius:0;-webkit-flex:1;-ms-flex:1;flex:1;text-align:left;margin-bottom:1px}.ui-text-enveloper .ui-text-enveloper-btn.ui-btn:not(.ui-inline)+.ui-text-enveloper-input{display:block;position:absolute;width:100%;text-indent:100%;height:27px}.ui-text-enveloper .ui-text-enveloper-btn-separator{display:inline-block;margin:0 6px;width:7.5px}.ui-text-enveloper .ui-text-enveloper-btn-separator::after{content:"";display:block;position:absolute;width:7.5px;height:16.5px;margin-top:-15px;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-image:url(images/core_contact_div.png);mask-image:url(images/core_contact_div.png);background-color:var(--control-active-color);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.ui-text-enveloper .ui-text-enveloper-btn-expanded{color:var(--control-inactive-color)}.ui-text-enveloper .ui-text-enveloper-slash{margin-top:-1px;width:13.5px;height:40px;opacity:1;transition:opacity linear 200ms;display:inline-block;overflow:auto}.ui-text-enveloper .ui-text-enveloper-slash::after{content:"";width:7.5px;margin-top:12px;height:16.5px;position:absolute;-webkit-mask-size:100%;mask-size:100%;-webkit-mask-image:url(images/core_contact_div.png);mask-image:url(images/core_contact_div.png);background-color:var(--control-active-color);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.ui-text-enveloper .ui-text-enveloper-slash.ui-text-enveloper-slash-hidden{opacity:0}.ui-text-enveloper .ui-text-enveloper-input{display:inline-block;width:auto;-webkit-flex:1;-moz-flex:1;-ms-flex:1;-o-flex:1;flex:1;min-width:60px;line-height:27px;height:27px;margin-top:6px;font-size:20px;background-color:transparent;margin-left:-5px;margin-bottom:0}.ui-text-enveloper .ui-text-enveloper-input-new-line{clear:left;width:100%}.ui-text-enveloper .ui-text-enveloper-input-new-line .ui-text-enveloper-input{margin-left:0}.ui-text-enveloper .ui-text-enveloper-input-new-line.ui-text-enveloper-input-blur{display:none}.ui-text-enveloper input.ui-text-input~.ui-text-input-clear{top:auto}.ui-listview .ui-li-static .ui-text-enveloper,.ui-listview .ui-li-flex .ui-text-enveloper{margin-top:-7px;margin-bottom:-6px;margin-right:8.5px;width:100%}.ui-listview .ui-li-static .ui-text-enveloper input.ui-text-input+.ui-text-input-textline,.ui-listview .ui-li-flex .ui-text-enveloper input.ui-text-input+.ui-text-input-textline{margin-bottom:0}tau-gridview{display:block;list-style-type:disc}.ui-gridview{position:relative;width:100%;height:100%;padding:0;margin:0;list-style:none}.ui-gridview .ui-gridview-item{position:absolute;border:.25px solid var(--grid-border-color);box-sizing:border-box;opacity:0;border-radius:26px;overflow:hidden}.ui-gridview .ui-gridview-item.ui-gridview-item-active{transition:-webkit-transform .4s cubic-bezier(0.25,.46,.45,1);transition:transform .4s cubic-bezier(0.25,.46,.45,1);transition:transform .4s cubic-bezier(0.25,.46,.45,1), -webkit-transform .4s cubic-bezier(0.25,.46,.45,1);opacity:1}.ui-gridview .ui-gridview-item.ui-gridview-helper{transition:none;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.ui-gridview .ui-gridview-item .ui-gridview-handler{display:block;position:absolute;width:100%;height:100%;left:0;top:0;opacity:0}.ui-gridview .ui-gridview-item>label{position:absolute;top:0;left:0;width:100%;height:100%}.ui-gridview .ui-gridview-item>label.ui-gridview-image-checked{background-color:var(--checkbox-image-checked)}.ui-gridview .ui-gridview-item>label>input[type=checkbox]{position:absolute;margin:8px 0 0 8px;background-image:url(images/3_Controllers/gallery_btn_uncheck_bg_mtrl.svg);background-size:100%;background-repeat:no-repeat;opacity:1}.ui-gridview .ui-gridview-item>label>input[type=checkbox]:checked{background-image:url(images/3_Controllers/gallery_btn_check_bg_mtrl.svg)}.ui-gridview .ui-gridview-item>label>input[type=checkbox]::after{background-color:var(--color-white)}.ui-gridview .ui-gridview-item>label>input[type=checkbox]:disabled{opacity:.4}.ui-gridview .ui-gridview-item .ui-gridview-image{display:block;width:100%;height:auto;pointer-events:none}.ui-gridview .ui-gridview-item.ui-gridview-item-has-label .ui-gridview-image{-webkit-transform:translateY(-28.5px);-ms-transform:translateY(-28.5px);transform:translateY(-28.5px)}.ui-gridview .ui-gridview-item .ui-gridview-label{position:absolute;width:calc(100% - 30px);margin:auto;padding:0 15px;font-family:Roboto-Regular;font-size:16px;color:var(--grid-label-color);text-align:left;overflow:hidden;text-overflow:ellipsis;bottom:0;background-color:var(--background-area-color);height:57px;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-gridview .ui-gridview-item .ui-gridview-label p{margin:0;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.ui-gridview .ui-gridview-item .ui-gridview-label p:nth-child(1){font-size:16px;color:var(--grid-label-color)}.ui-gridview .ui-gridview-item .ui-gridview-label p:nth-child(2){margin-top:3px;font-size:13px;color:var(--grid-label-secondary-color)}.ui-gridview .ui-gridview-item .ui-gridview-badge{position:absolute;border-radius:25px;min-width:11px;background-color:var(--accent-badge);color:var(--color-white);top:4.5px;right:4.5px;padding:3px 7px;font-size:11px;text-align:center}.ui-gridview .ui-gridview-item.ui-focus{-webkit-filter:invert(0.2);filter:invert(0.2)}.ui-gridview.ui-gridview-label-in .ui-gridview-label{position:absolute;bottom:6px;display:block;color:var(--grid-label-color)}.ui-gridview.ui-gridview-label-out .ui-gridview-label{display:block;margin:0;color:var(--grid-label-color);margin-bottom:11.5px}.ui-gridview.ui-gridview-reorder .ui-gridview-item .ui-gridview-handler{opacity:1}.ui-gridview-cols::after{content:"2";position:absolute;width:1px;height:1px;opacity:0}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out){box-sizing:content-box}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item{display:-webkit-flex;display:-ms-flexbox;display:flex}@-webkit-keyframes grid_show_item{0%{opacity:0}100%{opacity:1}}@keyframes grid_show_item{0%{opacity:0}100%{opacity:1}}@media (orientation:portrait){.ui-content:not(.ui-popup-content-gridview) .ui-gridview{min-height:509px}}@media (orientation:portrait) and (min-width:480px) and (max-width:959px){.ui-gridview-cols::after{content:"3"}}@media (orientation:landscape){.ui-gridview-cols::after{content:"4"}}@media (min-width:960px){.ui-gridview-cols::after{content:"5"}}.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper{width:100%;height:auto;overflow:auto;border-radius:26px}.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper .ui-popup-content.ui-popup-content-gridview{padding:0;margin:0;height:135px}.ui-popup:not(.ui-ctxpopup):not(.ui-popup-activity) .ui-popup-wrapper .ui-popup-content.ui-popup-content-gridview-multiple{padding:0;margin:0;height:252px}@media (orientation:landscape){.ui-popup.ui-popup-gridview{width:360px;left:70px}.ui-gridview-image{display:block;width:90.5px;height:90.5px;pointer-events:none}}@media (min-width:1920px){.ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out{min-width:1920px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out .ui-gridview-item .ui-gridview-image{width:240px;height:238px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview.ui-gridview-label-out .ui-gridview-item .ui-gridview-label{height:39px;line-height:39px;padding:0 10px;margin:0;margin-bottom:23px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out){min-width:1920px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item{width:240px;height:238px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item .ui-gridview-image{width:240px;height:238px}.ui-content:not(.ui-popup-content-gridview) .ui-gridview:not(.ui-gridview-label-out) .ui-gridview-item .ui-gridview-label{height:39px;line-height:39px;padding:0 10px}}.ui-welcome-page .ui-content .ui-scrollview-view{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-moz-flex-direction:column;-ms-flex-direction:column;-o-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;padding-bottom:41.5px}.ui-welcome-page .ui-content .ui-welcome-icon{height:80px;width:auto;-webkit-flex:0 0 auto;-moz-flex:0 0 auto;-ms-flex:0 0 auto;-o-flex:0 0 auto;flex:0 0 auto;-webkit-align-self:center;-ms-align-self:center;-o-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.ui-welcome-page .ui-content .ui-welcome-primary-text,.ui-welcome-page .ui-content .ui-welcome-secondary-text{margin:0 20px;font-weight:400}.ui-welcome-page .ui-content .ui-welcome-primary-text{color:var(--text-color);line-height:33.5px;font-size:24.5px}.ui-welcome-page .ui-content .ui-welcome-secondary-text{color:var(--text-secondary-color);line-height:21.5px;font-size:17.5px}.ui-welcome-page .ui-content .ui-welcome-primary-text+.ui-welcome-secondary-text{margin-top:29px}.ui-welcome-page .ui-footer{height:86px;text-align:center;-webkit-justify-content:center;-moz-justify-content:center;-ms-justify-content:center;-o-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-align-items:center;-moz-align-items:center;-ms-align-items:center;-o-align-items:center;-ms-flex-align:center;align-items:center}.ui-welcome-page .ui-footer button,.ui-welcome-page .ui-footer .ui-btn-welcome{min-width:248px;height:52px;background-color:var(--primary-color);display:inline-block;width:auto;-webkit-flex:0 0 auto;-moz-flex:0 0 auto;-ms-flex:0 0 auto;-o-flex:0 0 auto;flex:0 0 auto}.ui-welcome-page .ui-footer button:active,.ui-welcome-page .ui-footer .ui-btn-welcome:active,.ui-welcome-page .ui-footer button:focus,.ui-welcome-page .ui-footer .ui-btn-welcome:focus{background-color:var(--ripple-color)}.ui-welcome-page .ui-footer button[disabled],.ui-welcome-page .ui-footer .ui-btn-welcome[disabled],.ui-welcome-page .ui-footer button.ui-disabled,.ui-welcome-page .ui-footer .ui-btn-welcome.ui-disabled{background-color:var(--control-inactive-color)}.ui-dimmer{position:relative;border:60px solid rgba(0,151,216,.5);border-radius:100%;max-width:720px}.ui-dimmer::after{display:block;content:" ";padding-bottom:100%}.ui-dimmer .ui-dimmer-hidden{display:none}.ui-dimmer .ui-dimmer-text{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.ui-dimmer.ui-dimmer-lightbulb{width:50%;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);padding-bottom:50%;border-radius:0;border:0;background-image:url(images/dimmer/lightbulb.png);background-size:contain;display:block}.ui-dimmer.ui-dimmer-lightbulb::after{display:none}.ui-dimmer.ui-dimmer-lightbulb .ui-dimmer-lightbulb-light{display:block;position:absolute;width:60%;height:60%;left:50%;top:5%;opacity:.7;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);background-color:#ff0;-webkit-filter:blur(1.3rem);filter:blur(1.3rem);border-radius:50%;border:0;transition:background-color .3s}.wrapper{-webkit-perspective:600px;perspective:600px;margin:32px auto;margin-top:15%;margin-right:5%;width:100%;height:150px}.wrapper_test{-webkit-perspective:600px;perspective:600px;white-space:nowrap}.outer{transition:.8s;-webkit-transform:rotateY(40deg);transform:rotateY(40deg);width:auto;height:auto;overflow-x:scroll;margin-top:10%;margin-left:30%}.inner{transition:.8s;-webkit-transform:rotateY(40deg);transform:rotateY(40deg);margin-left:-15%;width:auto;height:auto}.inner figure{box-shadow:-3.5px 3.5px 1px -1.5px rgba(100,100,100,.5);display:inline-block}.inner img{display:block;width:50px;height:50px;max-width:100%;box-reflect:below 0 -webkit-gradient(linear,left bottom,left top,color-stop(0.05,rgba(255,255,255,.12)),color-stop(0.35,transparent));-webkit-box-reflect:below 0 -webkit-gradient(linear,left bottom,left top,color-stop(0.05,rgba(255,255,255,.12)),color-stop(0.35,transparent))}.flipster{display:block;overflow-x:hidden;overflow-y:visible;position:relative}.flipster:focus{outline:0}.flipster__container{margin:0;padding:0;list-style-type:none;position:relative;display:block;white-space:nowrap;word-spacing:-.25em;-webkit-transform-origin:50% 50%;-ms-transform-origin:50% 50%;transform-origin:50% 50%;-webkit-backface-visibility:hidden;backface-visibility:hidden}.flipster__item{margin:0;padding:0;list-style-type:none;position:relative;display:inline-block;white-space:normal;word-spacing:normal;vertical-align:bottom}.flipster__item img{max-width:100%}.flipster--click .flipster__item--past{cursor:pointer}.flipster--click .flipster__item--future{cursor:pointer}.flipster__button{position:absolute;top:50%;display:block;-webkit-appearance:none;-moz-appearance:none;appearance:none;background:0;border:0;padding:0;z-index:999;cursor:pointer;font-size:7.5px;opacity:.5;transition:opacity 500ms ease;margin:-1em 2em}.flipster__button svg{width:2em;stroke:currentColor;fill:transparent;stroke-width:3;stroke-linecap:round}.flipster__button:hover{opacity:1}.flipster__button:focus{opacity:1}.flipster__button--prev{left:0}.flipster__button--next{right:0}.flipster__nav{list-style-type:none;margin:0;padding:0;display:block;margin:0 0 4em;text-align:center;position:relative}.flipster__nav__item{list-style-type:none;margin:0;padding:0;display:inline-block;margin:0 .25em}.flipster__nav__link{display:block;color:inherit;padding:.5em 1em;position:relative;overflow:hidden;transition:all 250ms ease-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98)}.flipster__nav__link::after{content:'';display:block;background:#232221;position:absolute;top:0;left:0;width:100%;height:100%;z-index:-1;-webkit-transform:translateY(100%) translateY(-.25em);-ms-transform:translateY(100%) translateY(-.25em);transform:translateY(100%) translateY(-.25em);transition:inherit}.flipster__nav__link:hover{color:#FFF}.flipster__nav__link:hover::after{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.flipster__nav__link:focus{color:#FFF}.flipster__nav__link:focus::after{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.flipster__nav__item--current>.flipster__nav__link{color:#FFF}.flipster__nav__item--current>.flipster__nav__link::after{-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}.flipster__nav__item--current .flipster__nav__child{display:block}.flipster__nav__child{display:none;position:absolute;top:100%;left:0;right:0;margin-top:-.5px;padding:.5em;background:#4e4441;z-index:1}.flipster__nav__child .flipster__nav__link{color:#FFF}.flipster__nav__child .flipster__nav__link::after{background:#FFF}.flipster__nav__child .flipster__nav__link:hover{color:#232221}.flipster__nav__child .flipster__nav__link:focus{color:#232221}.flipster__nav__child .flipster__nav__item--current>.flipster__nav__link{color:#232221}.flipster--carousel .flipster__container{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98)}.flipster--carousel .flipster__item{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);-webkit-perspective:400px;perspective:400px}.flipster--carousel .flipster__item__content{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98)}.flipster--carousel .flipster__item--past{opacity:0;transition-delay:115ms}.flipster--carousel .flipster__item--past .flipster__item__content{-webkit-transform:translateX(100%) rotateY(-20deg) scale(0.5);transform:translateX(100%) rotateY(-20deg) scale(0.5)}.flipster--carousel .flipster__item--future{opacity:0;transition-delay:115ms}.flipster--carousel .flipster__item--future .flipster__item__content{-webkit-transform:translateX(-100%) rotateY(20deg) scale(0.5);transform:translateX(-100%) rotateY(20deg) scale(0.5)}.flipster--carousel .flipster__item--past-2{opacity:.6;transition-delay:20ms}.flipster--carousel .flipster__item--past-2 .flipster__item__content{-webkit-transform:translateX(25%) rotateY(40deg) scale(0.65);transform:translateX(25%) rotateY(40deg) scale(0.65)}.flipster--carousel .flipster__item--future-2{opacity:.6;transition-delay:20ms}.flipster--carousel .flipster__item--future-2 .flipster__item__content{-webkit-transform:translateX(-25%) rotateY(-40deg) scale(0.65);transform:translateX(-25%) rotateY(-40deg) scale(0.65)}.flipster--carousel .flipster__item--past-1{opacity:.6;transition-delay:20ms}.flipster--carousel .flipster__item--past-1 .flipster__item__content{-webkit-transform:rotateY(45deg) scale(0.8);transform:rotateY(45deg) scale(0.8)}.flipster--carousel .flipster__item--future-1{opacity:.6;transition-delay:20ms}.flipster--carousel .flipster__item--future-1 .flipster__item__content{-webkit-transform:rotateY(-45deg) scale(0.8);transform:rotateY(-45deg) scale(0.8)}.flipster--carousel .flipster__item--current .flipster__item__content{-webkit-transform:translateX(0) rotateY(0deg) scale(1);transform:translateX(0) rotateY(0deg) scale(1);transition-delay:60ms}.flipster--carousel.no-rotate .flipster__item--past .flipster__item__content{-webkit-transform:translateX(175%) scale(0.5);-ms-transform:translateX(175%) scale(0.5);transform:translateX(175%) scale(0.5)}.flipster--carousel.no-rotate .flipster__item--past-2 .flipster__item__content{-webkit-transform:translateX(25%) scale(0.65);-ms-transform:translateX(25%) scale(0.65);transform:translateX(25%) scale(0.65)}.flipster--carousel.no-rotate .flipster__item--past-1 .flipster__item__content{-webkit-transform:translateX(0%) scale(0.8);-ms-transform:translateX(0%) scale(0.8);transform:translateX(0%) scale(0.8)}.flipster--carousel.no-rotate .flipster__item--future .flipster__item__content{-webkit-transform:translateX(-175%) scale(0.5);-ms-transform:translateX(-175%) scale(0.5);transform:translateX(-175%) scale(0.5)}.flipster--carousel.no-rotate .flipster__item--future-2 .flipster__item__content{-webkit-transform:translateX(-25%) scale(0.65);-ms-transform:translateX(-25%) scale(0.65);transform:translateX(-25%) scale(0.65)}.flipster--carousel.no-rotate .flipster__item--future-1 .flipster__item__content{-webkit-transform:translateX(0%) scale(0.8);-ms-transform:translateX(0%) scale(0.8);transform:translateX(0%) scale(0.8)}.flipster--coverflow .flipster__container{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);padding-bottom:10%}.flipster--coverflow .flipster__item{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);-webkit-perspective:400px;perspective:400px}.flipster--coverflow .flipster__item__content{transition:all 350ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);-webkit-transform-origin:50% 100%;-ms-transform-origin:50% 100%;transform-origin:50% 100%;box-reflect:below 0 -webkit-gradient(linear,left bottom,left top,color-stop(0.05,rgba(255,255,255,.12)),color-stop(0.35,transparent));-webkit-box-reflect:below 0 -webkit-gradient(linear,left bottom,left top,color-stop(0.05,rgba(255,255,255,.12)),color-stop(0.35,transparent))}.flipster--coverflow .flipster__item__content img:only-child{display:block}.flipster--coverflow .flipster__item--past .flipster__item__content{-webkit-transform-origin:0 50%;-ms-transform-origin:0 50%;transform-origin:0 50%;-webkit-transform:scale(0.75) rotateY(55deg);transform:scale(0.75) rotateY(55deg)}.flipster--coverflow .flipster__item--future .flipster__item__content{-webkit-transform-origin:100% 50%;-ms-transform-origin:100% 50%;transform-origin:100% 50%;-webkit-transform:scale(0.75) rotateY(-55deg);transform:scale(0.75) rotateY(-55deg)}.flipster--coverflow .flip-current .flipster__item__content{-webkit-transform:rotateY(0deg);transform:rotateY(0deg)}.flipster--flat .flipster__container{transition:all 400ms ease-in-out}.flipster--flat .flipster__item{transition:all 400ms ease-in-out}.flipster--flat .flipster__item__content{transition:all 400ms ease-in-out}.flipster--flat .flipster__item--past{opacity:.5}.flipster--flat .flipster__item--past .flipster__item__content{-webkit-transform:scale(0.75);-ms-transform:scale(0.75);transform:scale(0.75)}.flipster--flat .flipster__item--future{opacity:.5}.flipster--flat .flipster__item--future .flipster__item__content{-webkit-transform:scale(0.75);-ms-transform:scale(0.75);transform:scale(0.75)}.flipster--wheel{overflow:hidden}.flipster--wheel .flipster__container{transition:all 400ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);padding-bottom:20%}.flipster--wheel .flipster__item__content{transition:all 400ms ease-in-out;transition-timing-function:cubic-bezier(0.56,.12,.12,.98);-webkit-transform-origin:50% 100%;-ms-transform-origin:50% 100%;transform-origin:50% 100%}.flipster--wheel .flipster__item__content img:only-child{display:block}.flipster--wheel .flipster__item--past .flipster__item__content{-webkit-transform-origin:100% 100%;-ms-transform-origin:100% 100%;transform-origin:100% 100%;opacity:0;-webkit-transform:rotateZ(-80deg) translate(-170%,110%);-ms-transform:rotate(-80deg) translate(-170%,110%);transform:rotateZ(-80deg) translate(-170%,110%)}.flipster--wheel .flipster__item--future .flipster__item__content{-webkit-transform-origin:0 100%;-ms-transform-origin:0 100%;transform-origin:0 100%;opacity:0;-webkit-transform:rotateZ(80deg) translate(170%,110%);-ms-transform:rotate(80deg) translate(170%,110%);transform:rotateZ(80deg) translate(170%,110%)}.flipster--wheel .flipster__item--past-3 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(-60deg) translate(-70%,75%);-ms-transform:rotate(-60deg) translate(-70%,75%);transform:rotateZ(-60deg) translate(-70%,75%)}.flipster--wheel .flipster__item--future-3 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(60deg) translate(70%,75%);-ms-transform:rotate(60deg) translate(70%,75%);transform:rotateZ(60deg) translate(70%,75%)}.flipster--wheel .flipster__item--past-2 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(-40deg) translate(-17%,30%);-ms-transform:rotate(-40deg) translate(-17%,30%);transform:rotateZ(-40deg) translate(-17%,30%)}.flipster--wheel .flipster__item--future-2 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(40deg) translate(17%,30%);-ms-transform:rotate(40deg) translate(17%,30%);transform:rotateZ(40deg) translate(17%,30%)}.flipster--wheel .flipster__item--past-1 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(-20deg);-ms-transform:rotate(-20deg);transform:rotateZ(-20deg)}.flipster--wheel .flipster__item--future-1 .flipster__item__content{opacity:1;-webkit-transform:rotateZ(20deg);-ms-transform:rotate(20deg);transform:rotateZ(20deg)}.flipster--wheel .flip-current .flipster__item__content{-webkit-transform:rotateX(0deg);transform:rotateX(0deg)}.ui-graph{width:100%;height:250px}.ui-toggle-slider-container{position:relative;display:inline-block;width:50px;height:26px}.ui-toggle-slider-container input{background-color:#CCC;transition:.5s;border-radius:26px;width:50px;height:26px;-webkit-appearance:none;-moz-appearance:none;appearance:none;outline:0;margin:0;-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui-toggle-slider-container input:checked{background-color:#3695DD}.ui-toggle-slider-container input:disabled{background-color:W015L1D}.ui-toggle-slider-container .ui-toggle-slider:before{position:absolute;content:'';height:22px;width:22px;left:1px;bottom:2px;background-color:#FFF;transition:.5s;border-radius:50%;pointer-events:none}.ui-toggle-slider-container input:checked+.ui-toggle-slider:before{-webkit-transform:translateX(25.5px);-ms-transform:translateX(25.5px);transform:translateX(25.5px)}.ui-coverflow:focus{background-color:var(--ripple-color)}.ui-spin{position:relative;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;height:164px;background-color:transparent;overflow:hidden;font-size:32px;padding:0;box-sizing:content-box;width:50px}.ui-spin-item{-webkit-align-items:center;-ms-flex-align:center;align-items:center;background-color:transparent;width:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;color:var(--primary-dark-color);opacity:var(--spin-item-opacity)!important;-webkit-user-select:none;-ms-user-select:none;user-select:none;font-family:Roboto-Medium}.ui-spin-item-selected{opacity:1!important}.ui-spin-carousel-item{position:absolute;left:0;top:0;width:100%;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-spin-enabling .ui-spin-item{transition:300ms opacity linear}.ui-spin-placeholder{opacity:0;pointer-events:none;position:absolute;display:none}.ui-time-picker{display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;height:164px;-webkit-justify-content:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.ui-time-picker[data-format="12"] .ui-time-picker-container{width:28%}.ui-time-picker[data-format="12"] .ui-time-picker-container-hour::after{content:":";height:164px;width:4%;font-size:32px;color:var(--primary-dark-color);position:absolute;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-time-picker[data-format="12"] .ui-time-picker-container-format .ui-spin-item{font-size:24px;line-height:54px}.ui-time-picker[data-format="24"] .ui-time-picker-container{width:30%}.ui-time-picker[data-format="24"] .ui-time-picker-container-hour::after{content:":";height:164px;width:13.33333333%;font-size:32px;color:var(--primary-dark-color);position:absolute;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-time-picker[data-format="24"] .ui-time-picker-container-format{display:none}.ui-time-picker .ui-spin{width:100%;height:164px;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-time-picker .ui-spin .ui-time-picker-input{width:50px;height:50px;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;text-align:center;font-size:32px;color:transparent;font-family:Roboto-Regular;border-width:0;outline:unset;outline-offset:unset;text-shadow:0 0 0 var(--primary-dark-color);opacity:0;background-color:transparent}.ui-time-picker .ui-spin .ui-time-picker-input:focus{background-color:var(--primary-color-20p)}.ui-time-picker .ui-spin-item{font-family:Roboto-Regular;line-height:56px}.ui-time-picker-input-active .ui-time-picker-container-hour .ui-spin-item,.ui-time-picker-input-active .ui-time-picker-container-minute .ui-spin-item{opacity:0!important}.ui-time-picker-input-active .ui-time-picker-container-hour .ui-time-picker-input,.ui-time-picker-input-active .ui-time-picker-container-minute .ui-time-picker-input{opacity:1}.ui-calendar-view{width:100%;border-spacing:0}.ui-calendar-view tr td{height:32px;text-align:center;vertical-align:middle;font-size:15px;font-family:Roboto-Regular;color:var(--calendar-text-color);padding:0}.ui-calendar-view tr td div{border-radius:100%;width:28px;height:28px;line-height:28px;margin:0 auto}.ui-calendar-view tr td div.ui-calendar-selection{background-color:var(--primary-color);color:var(--calendar-select-text-color)}.ui-calendar-view tr td:only-child{width:100%}.ui-calendar-view tr td:nth-last-child(2){width:50%}.ui-calendar-view tr td:nth-last-child(2)+td{width:50%}.ui-calendar-view tr td:nth-last-child(3){width:33.3%}.ui-calendar-view tr td:nth-last-child(3)~td{width:33.3%}.ui-calendar-view tr td:nth-last-child(4){width:25%}.ui-calendar-view tr td:nth-last-child(4)~td{width:25%}.ui-calendar-view tr td:nth-last-child(5){width:20%}.ui-calendar-view tr td:nth-last-child(5)~td{width:20%}.ui-calendar-view tr td:nth-last-child(6){width:16.6%}.ui-calendar-view tr td:nth-last-child(6)~td{width:16.6%}.ui-calendar-view tr td:nth-last-child(7){width:14.2%}.ui-calendar-view tr td:nth-last-child(7)~td{width:14.2%}.ui-calendar-view tr td:nth-child(7){color:var(--calendar-weekend-day-color)}.ui-calendar-view .ui-calendar-one-week{height:32px}.ui-calendar-view .ui-calendar-one-week td{font-family:Roboto-Regular;font-size:11px;color:var(--text-secondary-color)}.ui-calendar-view .ui-calendar-one-week .ui-sunday{color:var(--calendar-weekend-color)}.ui-calendar-top-space{height:10px}.ui-calendar-prev-month-day{opacity:.1}.ui-calendar-next-month-day{opacity:.4}.ui-calendar-controller{width:100%;height:36px;line-height:36px;margin:0 auto;text-align:center}.ui-calendar-controller div.ui-calendar-switch{text-align:center;font-family:Roboto-Regular;font-size:17px;color:var(--calendar-text-color);line-height:36px;display:inline}.ui-calendar-arrow{width:36px;height:36px;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:100%;mask-size:100%;background-color:var(--calendar-arrow-color)}.ui-calendar-left-arrow{float:left;-webkit-mask-image:url(images/4_Dialogs/tw_numberpicker_prev_mtrl.svg);mask-image:url(images/4_Dialogs/tw_numberpicker_prev_mtrl.svg)}.ui-calendar-right-arrow{float:right;-webkit-mask-image:url(images/4_Dialogs/tw_numberpicker_next_mtrl.svg);mask-image:url(images/4_Dialogs/tw_numberpicker_next_mtrl.svg)}.ui-calendar-disabled{opacity:.1}.ui-calendar-disabled-arrow{opacity:.4}@media (min-width:361px){.ui-calendar-controller{width:328px;margin:0 auto}}.ui-content-area .ui-calendar,.ui-popup-content .ui-calendar{padding:14px 16px}.ui-date-picker{display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.ui-date-picker-header{font-family:Roboto-Regular;display:-webkit-flex;display:-ms-flexbox;display:flex;width:100%;height:36px;font-size:17px;color:var(--date-picker-header-text-color);line-height:36px;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;margin-top:14px;margin-bottom:10px}.ui-date-picker-content{display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-justify-content:space-evenly;-ms-flex-pack:space-evenly;justify-content:space-evenly}.ui-date-picker-content .ui-date-picker-container{width:28%;height:164px;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center}.ui-date-picker-content .ui-date-picker-container .ui-spin{width:100%}.ui-date-picker-content .ui-date-picker-container .ui-spin-item{font-size:32px;line-height:54px;font-family:Roboto-Regular}.ui-date-picker-content .ui-date-picker-container .ui-spin-item-selected{line-height:56px}.ui-date-picker-content .ui-date-picker-container-month .ui-spin-item{font-size:30px}.ui-datetime-picker-wheel{display:-webkit-flex;display:-ms-flexbox;display:flex;height:164px;margin-left:4%;margin-right:6%;padding-top:60px;padding-bottom:81px}.ui-datetime-picker-wheel-container{-webkit-flex:1;-ms-flex:1;flex:1;font-size:22px}.ui-datetime-picker-wheel-container-separator{position:relative}.ui-datetime-picker-wheel-container-separator::after{content:":";height:100%;width:auto;color:var(--primary-dark-color);position:absolute;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;right:0}.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-date{min-width:47%}.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-hour{min-width:14%}.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-minute{min-width:14%}.ui-datetime-picker-wheel[data-format="12"] .ui-datetime-picker-wheel-container-format{min-width:13%}.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-date{min-width:47%}.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-hour{min-width:14%}.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-minute{min-width:14%}.ui-datetime-picker-wheel[data-format="24"] .ui-datetime-picker-wheel-container-format{display:none}.ui-datetime-picker-wheel .ui-spin{width:100%;height:164px;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;white-space:nowrap;font-size:22px}.ui-datetime-picker-wheel .ui-spin .ui-datetime-picker-wheel-input{width:50px;height:50px;-webkit-align-self:center;-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;text-align:center;font-size:22px;color:transparent;font-family:Roboto-Regular;border-width:0;outline:unset;outline-offset:unset;text-shadow:0 0 0 var(--primary-dark-color);opacity:0;background-color:transparent}.ui-datetime-picker-wheel .ui-spin .ui-datetime-picker-wheel-input:focus{background-color:var(--primary-color-20p)}.ui-datetime-picker-wheel .ui-spin-item{font-family:Roboto-Regular;line-height:54px}.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-hour .ui-spin-item,.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-minute .ui-spin-item{opacity:0!important}.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-hour .ui-datetime-picker-wheel-input,.ui-datetime-picker-wheel-input-active .ui-datetime-picker-wheel-container-minute .ui-datetime-picker-wheel-input{opacity:1}.ui-datetime-picker-hidden{display:none}.ui-chip{display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;font-family:Roboto-Regular;font-size:14px;height:30px;border-radius:15px;padding:0 0 0 16px;background-color:var(--chip-background-color);border:.25px solid var(--chip-border-color);box-sizing:border-box;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.ui-chip .ui-chip-text{text-overflow:ellipsis;overflow:hidden;white-space:nowrap;-webkit-order:1;-ms-flex-order:1;order:1}.ui-chip .ui-chip-button{-webkit-order:2;-ms-flex-order:2;order:2}.ui-chip .ui-btn.ui-btn-flat{-webkit-order:2;-ms-flex-order:2;order:2;width:20px;height:20px;max-width:20px;max-height:20px;min-width:20px;min-height:20px;max-width:100%;margin:auto 5px auto 10px;padding:0;border-radius:100%;background-color:var(--chip-btn-background-color);border:.5px solid var(--chip-btn-border-color);box-sizing:border-box}.ui-chip .ui-btn.ui-btn-flat::after{width:20px;height:20px;-webkit-mask-size:20px;mask-size:20px}.ui-chip .ui-btn.ui-btn-flat::before{width:30px;height:30px}.ui-chip .ui-btn.ui-btn-flat.ui-btn-icon{background-color:var(--chip-btn-background-color)}.ui-chip .ui-btn.ui-btn-flat.ui-icon-add::after{-webkit-mask-image:url(images/3_Controllers/tw_chips_icon_add_mtrl.svg);mask-image:url(images/3_Controllers/tw_chips_icon_add_mtrl.svg)}.ui-chip .ui-btn.ui-btn-flat.ui-icon-delete::after{-webkit-mask-image:url(images/3_Controllers/tw_chips_icon_delete_mtrl.svg);mask-image:url(images/3_Controllers/tw_chips_icon_delete_mtrl.svg)}.ui-chips{display:-webkit-flex;display:-ms-flexbox;display:flex;margin:0 20px;row-gap:4px;-webkit-column-gap:7px;column-gap:7px;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;max-height:114px;overflow-y:auto}.ui-chips .ui-chip{margin-top:4px;max-width:100%}.ui-chips.ui-chips-inline{-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;overflow-x:scroll;height:44px}.tau-info-theme:after{content:"default"}
\ No newline at end of file
diff --git a/d2d_app/client/manifest.webmanifest b/d2d_app/client/manifest.webmanifest
new file mode 100644 (file)
index 0000000..5d81355
--- /dev/null
@@ -0,0 +1,13 @@
+{
+       "name": "HomeTV App",
+       "short_name": "HomeTV App",
+       "start_url": ".",
+       "display": "standalone",
+       "background_color": "#fff",
+       "icons": [
+               {
+                       "src":"/images/Icon.png",
+                       "sizes": "48x48 72x72 96x96 128x128"
+               }
+       ]
+}
\ No newline at end of file
diff --git a/d2d_app/client/pincode.html b/d2d_app/client/pincode.html
new file mode 100755 (executable)
index 0000000..054e6ac
--- /dev/null
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>PIN code</title>
+    <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
+    <link href='./css/pincode.css' rel='stylesheet' type='text/css'>
+</head>
+
+<body>
+    <form id="loginForm" action="/d2d" method="post"></form>
+        <div id="pin">
+            <div class="dots">
+                <div class="dot"></div>
+                <div class="dot"></div>
+                <div class="dot"></div>
+                <div class="dot"></div>
+            </div>
+            <p>Click the PIN code</p>
+            <div class="numbers">
+                <div class="number">1</div>
+                <div class="number">2</div>
+                <div class="number">3</div>
+                <div class="number">4</div>
+                <div class="number">5</div>
+                <div class="number">6</div>
+                <div class="number">7</div>
+                <div class="number">8</div>
+                <div class="number">9</div>
+                <div class="number" style="visibility: hidden;">N</div>
+                <div class="number">0</div>
+                <div class="number" style="visibility: hidden;">N</div>
+            </div>
+        </div>
+    </form>
+    <script src="./js/jsencrypt.js"></script>
+    <script src="./js/pincode.js"></script>
+</body>
+
+</html>
\ No newline at end of file
index 3f3ecfc..3f65f86 100755 (executable)
@@ -1,19 +1,20 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<widget xmlns="http://www.w3.org/ns/widgets" xmlns:tizen="http://tizen.org/ns/widgets" id="http://yourdomain/GlobalDeviceWebServer" version="1.0.0" viewmodes="maximized">
-    <tizen:application package="9z6IujVul3" required_version="6.0"/>
+<widget xmlns:tizen="http://tizen.org/ns/widgets" xmlns="http://www.w3.org/ns/widgets" id="http://yourdomain/GlobalDeviceWebServer" version="1.0.1" viewmodes="maximized">
+    <tizen:application package="9z6IujVul3" required_version="6.5"/>
     <feature name="http://tizen.org/feature/screen.size.all"/>
-    <icon src="icon.png"/>
-    <name>GlobalDeviceWebServer</name>
+    <name>D2DApp</name>
+    <tizen:profile name="mobile"/>
+    <tizen:privilege name="http://tizen.org/privilege/account.read"/>
     <tizen:privilege name="http://tizen.org/privilege/application.launch"/>
     <tizen:privilege name="http://tizen.org/privilege/application.info"/>
     <tizen:privilege name="http://tizen.org/privilege/package.info"/>
     <tizen:privilege name="http://tizen.org/privilege/filesystem.read"/>
     <tizen:privilege name="http://tizen.org/privilege/filesystem.write"/>
+    <tizen:privilege name="http://tizen.org/privilege/internet"/>
     <tizen:privilege name="http://tizen.org/privilege/mediastorage"/>
-    <tizen:profile name="mobile"/>
     <tizen:service id="9z6IujVul3.Service" type="global">
         <tizen:content src="service/service.js"/>
-        <tizen:name>D2DGlobalService</tizen:name>
-        <tizen:description>D2DGlobalService</tizen:description>
+        <tizen:name>D2DAppService</tizen:name>
+        <tizen:description>D2DAppService</tizen:description>
     </tizen:service>
 </widget>
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/d2d_app/node_modules/.bin/ejs b/d2d_app/node_modules/.bin/ejs
new file mode 120000 (symlink)
index 0000000..88e80d0
--- /dev/null
@@ -0,0 +1 @@
+../ejs/bin/cli.js
\ No newline at end of file
diff --git a/d2d_app/node_modules/.bin/jake b/d2d_app/node_modules/.bin/jake
new file mode 120000 (symlink)
index 0000000..3626745
--- /dev/null
@@ -0,0 +1 @@
+../jake/bin/cli.js
\ No newline at end of file
diff --git a/d2d_app/node_modules/ansi-styles/index.js b/d2d_app/node_modules/ansi-styles/index.js
new file mode 100644 (file)
index 0000000..90a871c
--- /dev/null
@@ -0,0 +1,165 @@
+'use strict';
+const colorConvert = require('color-convert');
+
+const wrapAnsi16 = (fn, offset) => function () {
+       const code = fn.apply(colorConvert, arguments);
+       return `\u001B[${code + offset}m`;
+};
+
+const wrapAnsi256 = (fn, offset) => function () {
+       const code = fn.apply(colorConvert, arguments);
+       return `\u001B[${38 + offset};5;${code}m`;
+};
+
+const wrapAnsi16m = (fn, offset) => function () {
+       const rgb = fn.apply(colorConvert, arguments);
+       return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
+};
+
+function assembleStyles() {
+       const codes = new Map();
+       const styles = {
+               modifier: {
+                       reset: [0, 0],
+                       // 21 isn't widely supported and 22 does the same thing
+                       bold: [1, 22],
+                       dim: [2, 22],
+                       italic: [3, 23],
+                       underline: [4, 24],
+                       inverse: [7, 27],
+                       hidden: [8, 28],
+                       strikethrough: [9, 29]
+               },
+               color: {
+                       black: [30, 39],
+                       red: [31, 39],
+                       green: [32, 39],
+                       yellow: [33, 39],
+                       blue: [34, 39],
+                       magenta: [35, 39],
+                       cyan: [36, 39],
+                       white: [37, 39],
+                       gray: [90, 39],
+
+                       // Bright color
+                       redBright: [91, 39],
+                       greenBright: [92, 39],
+                       yellowBright: [93, 39],
+                       blueBright: [94, 39],
+                       magentaBright: [95, 39],
+                       cyanBright: [96, 39],
+                       whiteBright: [97, 39]
+               },
+               bgColor: {
+                       bgBlack: [40, 49],
+                       bgRed: [41, 49],
+                       bgGreen: [42, 49],
+                       bgYellow: [43, 49],
+                       bgBlue: [44, 49],
+                       bgMagenta: [45, 49],
+                       bgCyan: [46, 49],
+                       bgWhite: [47, 49],
+
+                       // Bright color
+                       bgBlackBright: [100, 49],
+                       bgRedBright: [101, 49],
+                       bgGreenBright: [102, 49],
+                       bgYellowBright: [103, 49],
+                       bgBlueBright: [104, 49],
+                       bgMagentaBright: [105, 49],
+                       bgCyanBright: [106, 49],
+                       bgWhiteBright: [107, 49]
+               }
+       };
+
+       // Fix humans
+       styles.color.grey = styles.color.gray;
+
+       for (const groupName of Object.keys(styles)) {
+               const group = styles[groupName];
+
+               for (const styleName of Object.keys(group)) {
+                       const style = group[styleName];
+
+                       styles[styleName] = {
+                               open: `\u001B[${style[0]}m`,
+                               close: `\u001B[${style[1]}m`
+                       };
+
+                       group[styleName] = styles[styleName];
+
+                       codes.set(style[0], style[1]);
+               }
+
+               Object.defineProperty(styles, groupName, {
+                       value: group,
+                       enumerable: false
+               });
+
+               Object.defineProperty(styles, 'codes', {
+                       value: codes,
+                       enumerable: false
+               });
+       }
+
+       const ansi2ansi = n => n;
+       const rgb2rgb = (r, g, b) => [r, g, b];
+
+       styles.color.close = '\u001B[39m';
+       styles.bgColor.close = '\u001B[49m';
+
+       styles.color.ansi = {
+               ansi: wrapAnsi16(ansi2ansi, 0)
+       };
+       styles.color.ansi256 = {
+               ansi256: wrapAnsi256(ansi2ansi, 0)
+       };
+       styles.color.ansi16m = {
+               rgb: wrapAnsi16m(rgb2rgb, 0)
+       };
+
+       styles.bgColor.ansi = {
+               ansi: wrapAnsi16(ansi2ansi, 10)
+       };
+       styles.bgColor.ansi256 = {
+               ansi256: wrapAnsi256(ansi2ansi, 10)
+       };
+       styles.bgColor.ansi16m = {
+               rgb: wrapAnsi16m(rgb2rgb, 10)
+       };
+
+       for (let key of Object.keys(colorConvert)) {
+               if (typeof colorConvert[key] !== 'object') {
+                       continue;
+               }
+
+               const suite = colorConvert[key];
+
+               if (key === 'ansi16') {
+                       key = 'ansi';
+               }
+
+               if ('ansi16' in suite) {
+                       styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0);
+                       styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10);
+               }
+
+               if ('ansi256' in suite) {
+                       styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0);
+                       styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10);
+               }
+
+               if ('rgb' in suite) {
+                       styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0);
+                       styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10);
+               }
+       }
+
+       return styles;
+}
+
+// Make the export immutable
+Object.defineProperty(module, 'exports', {
+       enumerable: true,
+       get: assembleStyles
+});
diff --git a/d2d_app/node_modules/ansi-styles/license b/d2d_app/node_modules/ansi-styles/license
new file mode 100644 (file)
index 0000000..e7af2f7
--- /dev/null
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/ansi-styles/package.json b/d2d_app/node_modules/ansi-styles/package.json
new file mode 100644 (file)
index 0000000..6a6661b
--- /dev/null
@@ -0,0 +1,88 @@
+{
+  "_from": "ansi-styles@^3.2.1",
+  "_id": "ansi-styles@3.2.1",
+  "_inBundle": false,
+  "_integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+  "_location": "/ansi-styles",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "ansi-styles@^3.2.1",
+    "name": "ansi-styles",
+    "escapedName": "ansi-styles",
+    "rawSpec": "^3.2.1",
+    "saveSpec": null,
+    "fetchSpec": "^3.2.1"
+  },
+  "_requiredBy": [
+    "/chalk"
+  ],
+  "_resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+  "_shasum": "41fbb20243e50b12be0f04b8dedbf07520ce841d",
+  "_spec": "ansi-styles@^3.2.1",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/chalk",
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "sindresorhus@gmail.com",
+    "url": "sindresorhus.com"
+  },
+  "ava": {
+    "require": "babel-polyfill"
+  },
+  "bugs": {
+    "url": "https://github.com/chalk/ansi-styles/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "color-convert": "^1.9.0"
+  },
+  "deprecated": false,
+  "description": "ANSI escape codes for styling strings in the terminal",
+  "devDependencies": {
+    "ava": "*",
+    "babel-polyfill": "^6.23.0",
+    "svg-term-cli": "^2.1.1",
+    "xo": "*"
+  },
+  "engines": {
+    "node": ">=4"
+  },
+  "files": [
+    "index.js"
+  ],
+  "homepage": "https://github.com/chalk/ansi-styles#readme",
+  "keywords": [
+    "ansi",
+    "styles",
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "string",
+    "tty",
+    "escape",
+    "formatting",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "log",
+    "logging",
+    "command-line",
+    "text"
+  ],
+  "license": "MIT",
+  "name": "ansi-styles",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/chalk/ansi-styles.git"
+  },
+  "scripts": {
+    "screenshot": "svg-term --command='node screenshot' --out=screenshot.svg --padding=3 --width=55 --height=3 --at=1000 --no-cursor",
+    "test": "xo && ava"
+  },
+  "version": "3.2.1"
+}
diff --git a/d2d_app/node_modules/ansi-styles/readme.md b/d2d_app/node_modules/ansi-styles/readme.md
new file mode 100644 (file)
index 0000000..3158e2d
--- /dev/null
@@ -0,0 +1,147 @@
+# ansi-styles [![Build Status](https://travis-ci.org/chalk/ansi-styles.svg?branch=master)](https://travis-ci.org/chalk/ansi-styles)
+
+> [ANSI escape codes](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
+
+You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings.
+
+<img src="https://cdn.rawgit.com/chalk/ansi-styles/8261697c95bf34b6c7767e2cbe9941a851d59385/screenshot.svg" width="900">
+
+
+## Install
+
+```
+$ npm install ansi-styles
+```
+
+
+## Usage
+
+```js
+const style = require('ansi-styles');
+
+console.log(`${style.green.open}Hello world!${style.green.close}`);
+
+
+// Color conversion between 16/256/truecolor
+// NOTE: If conversion goes to 16 colors or 256 colors, the original color
+//       may be degraded to fit that color palette. This means terminals
+//       that do not support 16 million colors will best-match the
+//       original color.
+console.log(style.bgColor.ansi.hsl(120, 80, 72) + 'Hello world!' + style.bgColor.close);
+console.log(style.color.ansi256.rgb(199, 20, 250) + 'Hello world!' + style.color.close);
+console.log(style.color.ansi16m.hex('#ABCDEF') + 'Hello world!' + style.color.close);
+```
+
+## API
+
+Each style has an `open` and `close` property.
+
+
+## Styles
+
+### Modifiers
+
+- `reset`
+- `bold`
+- `dim`
+- `italic` *(Not widely supported)*
+- `underline`
+- `inverse`
+- `hidden`
+- `strikethrough` *(Not widely supported)*
+
+### Colors
+
+- `black`
+- `red`
+- `green`
+- `yellow`
+- `blue`
+- `magenta`
+- `cyan`
+- `white`
+- `gray` ("bright black")
+- `redBright`
+- `greenBright`
+- `yellowBright`
+- `blueBright`
+- `magentaBright`
+- `cyanBright`
+- `whiteBright`
+
+### Background colors
+
+- `bgBlack`
+- `bgRed`
+- `bgGreen`
+- `bgYellow`
+- `bgBlue`
+- `bgMagenta`
+- `bgCyan`
+- `bgWhite`
+- `bgBlackBright`
+- `bgRedBright`
+- `bgGreenBright`
+- `bgYellowBright`
+- `bgBlueBright`
+- `bgMagentaBright`
+- `bgCyanBright`
+- `bgWhiteBright`
+
+
+## Advanced usage
+
+By default, you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module.
+
+- `style.modifier`
+- `style.color`
+- `style.bgColor`
+
+###### Example
+
+```js
+console.log(style.color.green.open);
+```
+
+Raw escape codes (i.e. without the CSI escape prefix `\u001B[` and render mode postfix `m`) are available under `style.codes`, which returns a `Map` with the open codes as keys and close codes as values.
+
+###### Example
+
+```js
+console.log(style.codes.get(36));
+//=> 39
+```
+
+
+## [256 / 16 million (TrueColor) support](https://gist.github.com/XVilka/8346728)
+
+`ansi-styles` uses the [`color-convert`](https://github.com/Qix-/color-convert) package to allow for converting between various colors and ANSI escapes, with support for 256 and 16 million colors.
+
+To use these, call the associated conversion function with the intended output, for example:
+
+```js
+style.color.ansi.rgb(100, 200, 15); // RGB to 16 color ansi foreground code
+style.bgColor.ansi.rgb(100, 200, 15); // RGB to 16 color ansi background code
+
+style.color.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code
+style.bgColor.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code
+
+style.color.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color foreground code
+style.bgColor.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color background code
+```
+
+
+## Related
+
+- [ansi-escapes](https://github.com/sindresorhus/ansi-escapes) - ANSI escape codes for manipulating the terminal
+
+
+## Maintainers
+
+- [Sindre Sorhus](https://github.com/sindresorhus)
+- [Josh Junon](https://github.com/qix-)
+
+
+## License
+
+MIT
diff --git a/d2d_app/node_modules/async/.travis.yml b/d2d_app/node_modules/async/.travis.yml
new file mode 100644 (file)
index 0000000..6064ca0
--- /dev/null
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - "0.10"
+  - "0.12"
+  - "iojs"
similarity index 87%
rename from d2d_app/node_modules/express/node_modules/ms/license.md
rename to d2d_app/node_modules/async/LICENSE
index 69b6125..8f29698 100644 (file)
@@ -1,6 +1,4 @@
-The MIT License (MIT)
-
-Copyright (c) 2016 Zeit, Inc.
+Copyright (c) 2010-2014 Caolan McMahon
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -9,13 +7,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:
 
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
 
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/d2d_app/node_modules/async/README.md b/d2d_app/node_modules/async/README.md
new file mode 100644 (file)
index 0000000..6cfb922
--- /dev/null
@@ -0,0 +1,1647 @@
+# Async.js
+
+[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async)
+
+
+Async is a utility module which provides straight-forward, powerful functions
+for working with asynchronous JavaScript. Although originally designed for
+use with [Node.js](http://nodejs.org) and installable via `npm install async`,
+it can also be used directly in the browser.
+
+Async is also installable via:
+
+- [bower](http://bower.io/): `bower install async`
+- [component](https://github.com/component/component): `component install
+  caolan/async`
+- [jam](http://jamjs.org/): `jam install async`
+- [spm](http://spmjs.io/): `spm install async`
+
+Async provides around 20 functions that include the usual 'functional'
+suspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns
+for asynchronous control flow (`parallel`, `series`, `waterfall`…). All these
+functions assume you follow the Node.js convention of providing a single
+callback as the last argument of your `async` function.
+
+
+## Quick Examples
+
+```javascript
+async.map(['file1','file2','file3'], fs.stat, function(err, results){
+    // results is now an array of stats for each file
+});
+
+async.filter(['file1','file2','file3'], fs.exists, function(results){
+    // results now equals an array of the existing files
+});
+
+async.parallel([
+    function(){ ... },
+    function(){ ... }
+], callback);
+
+async.series([
+    function(){ ... },
+    function(){ ... }
+]);
+```
+
+There are many more functions available so take a look at the docs below for a
+full list. This module aims to be comprehensive, so if you feel anything is
+missing please create a GitHub issue for it.
+
+## Common Pitfalls
+
+### Binding a context to an iterator
+
+This section is really about `bind`, not about `async`. If you are wondering how to
+make `async` execute your iterators in a given context, or are confused as to why
+a method of another library isn't working as an iterator, study this example:
+
+```js
+// Here is a simple object with an (unnecessarily roundabout) squaring method
+var AsyncSquaringLibrary = {
+  squareExponent: 2,
+  square: function(number, callback){ 
+    var result = Math.pow(number, this.squareExponent);
+    setTimeout(function(){
+      callback(null, result);
+    }, 200);
+  }
+};
+
+async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){
+  // result is [NaN, NaN, NaN]
+  // This fails because the `this.squareExponent` expression in the square
+  // function is not evaluated in the context of AsyncSquaringLibrary, and is
+  // therefore undefined.
+});
+
+async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){
+  // result is [1, 4, 9]
+  // With the help of bind we can attach a context to the iterator before
+  // passing it to async. Now the square function will be executed in its 
+  // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent`
+  // will be as expected.
+});
+```
+
+## Download
+
+The source is available for download from
+[GitHub](http://github.com/caolan/async).
+Alternatively, you can install using Node Package Manager (`npm`):
+
+    npm install async
+
+__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed
+
+## In the Browser
+
+So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. 
+
+Usage:
+
+```html
+<script type="text/javascript" src="async.js"></script>
+<script type="text/javascript">
+
+    async.map(data, asyncProcess, function(err, results){
+        alert(results);
+    });
+
+</script>
+```
+
+## Documentation
+
+### Collections
+
+* [`each`](#each)
+* [`eachSeries`](#eachSeries)
+* [`eachLimit`](#eachLimit)
+* [`map`](#map)
+* [`mapSeries`](#mapSeries)
+* [`mapLimit`](#mapLimit)
+* [`filter`](#filter)
+* [`filterSeries`](#filterSeries)
+* [`reject`](#reject)
+* [`rejectSeries`](#rejectSeries)
+* [`reduce`](#reduce)
+* [`reduceRight`](#reduceRight)
+* [`detect`](#detect)
+* [`detectSeries`](#detectSeries)
+* [`sortBy`](#sortBy)
+* [`some`](#some)
+* [`every`](#every)
+* [`concat`](#concat)
+* [`concatSeries`](#concatSeries)
+
+### Control Flow
+
+* [`series`](#seriestasks-callback)
+* [`parallel`](#parallel)
+* [`parallelLimit`](#parallellimittasks-limit-callback)
+* [`whilst`](#whilst)
+* [`doWhilst`](#doWhilst)
+* [`until`](#until)
+* [`doUntil`](#doUntil)
+* [`forever`](#forever)
+* [`waterfall`](#waterfall)
+* [`compose`](#compose)
+* [`seq`](#seq)
+* [`applyEach`](#applyEach)
+* [`applyEachSeries`](#applyEachSeries)
+* [`queue`](#queue)
+* [`priorityQueue`](#priorityQueue)
+* [`cargo`](#cargo)
+* [`auto`](#auto)
+* [`retry`](#retry)
+* [`iterator`](#iterator)
+* [`apply`](#apply)
+* [`nextTick`](#nextTick)
+* [`times`](#times)
+* [`timesSeries`](#timesSeries)
+
+### Utils
+
+* [`memoize`](#memoize)
+* [`unmemoize`](#unmemoize)
+* [`log`](#log)
+* [`dir`](#dir)
+* [`noConflict`](#noConflict)
+
+
+## Collections
+
+<a name="forEach" />
+<a name="each" />
+### each(arr, iterator, callback)
+
+Applies the function `iterator` to each item in `arr`, in parallel.
+The `iterator` is called with an item from the list, and a callback for when it
+has finished. If the `iterator` passes an error to its `callback`, the main
+`callback` (for the `each` function) is immediately called with the error.
+
+Note, that since this function applies `iterator` to each item in parallel,
+there is no guarantee that the iterator functions will complete in order.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err)` which must be called once it has 
+  completed. If no error has occurred, the `callback` should be run without 
+  arguments or with an explicit `null` argument.
+* `callback(err)` - A callback which is called when all `iterator` functions
+  have finished, or an error occurs.
+
+__Examples__
+
+
+```js
+// assuming openFiles is an array of file names and saveFile is a function
+// to save the modified contents of that file:
+
+async.each(openFiles, saveFile, function(err){
+    // if any of the saves produced an error, err would equal that error
+});
+```
+
+```js
+// assuming openFiles is an array of file names 
+
+async.each(openFiles, function(file, callback) {
+  
+  // Perform operation on file here.
+  console.log('Processing file ' + file);
+  
+  if( file.length > 32 ) {
+    console.log('This file name is too long');
+    callback('File name too long');
+  } else {
+    // Do work to process file here
+    console.log('File processed');
+    callback();
+  }
+}, function(err){
+    // if any of the file processing produced an error, err would equal that error
+    if( err ) {
+      // One of the iterations produced an error.
+      // All processing will now stop.
+      console.log('A file failed to process');
+    } else {
+      console.log('All files have been processed successfully');
+    }
+});
+```
+
+---------------------------------------
+
+<a name="forEachSeries" />
+<a name="eachSeries" />
+### eachSeries(arr, iterator, callback)
+
+The same as [`each`](#each), only `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+This means the `iterator` functions will complete in order.
+
+
+---------------------------------------
+
+<a name="forEachLimit" />
+<a name="eachLimit" />
+### eachLimit(arr, limit, iterator, callback)
+
+The same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously 
+running at any time.
+
+Note that the items in `arr` are not processed in batches, so there is no guarantee that 
+the first `limit` `iterator` functions will complete before any others are started.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `limit` - The maximum number of `iterator`s to run at any time.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err)` which must be called once it has 
+  completed. If no error has occurred, the callback should be run without 
+  arguments or with an explicit `null` argument.
+* `callback(err)` - A callback which is called when all `iterator` functions
+  have finished, or an error occurs.
+
+__Example__
+
+```js
+// Assume documents is an array of JSON objects and requestApi is a
+// function that interacts with a rate-limited REST api.
+
+async.eachLimit(documents, 20, requestApi, function(err){
+    // if any of the saves produced an error, err would equal that error
+});
+```
+
+---------------------------------------
+
+<a name="map" />
+### map(arr, iterator, callback)
+
+Produces a new array of values by mapping each value in `arr` through
+the `iterator` function. The `iterator` is called with an item from `arr` and a
+callback for when it has finished processing. Each of these callback takes 2 arguments: 
+an `error`, and the transformed item from `arr`. If `iterator` passes an error to his 
+callback, the main `callback` (for the `map` function) is immediately called with the error.
+
+Note, that since this function applies the `iterator` to each item in parallel,
+there is no guarantee that the `iterator` functions will complete in order. 
+However, the results array will be in the same order as the original `arr`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, transformed)` which must be called once 
+  it has completed with an error (which can be `null`) and a transformed item.
+* `callback(err, results)` - A callback which is called when all `iterator`
+  functions have finished, or an error occurs. Results is an array of the
+  transformed items from the `arr`.
+
+__Example__
+
+```js
+async.map(['file1','file2','file3'], fs.stat, function(err, results){
+    // results is now an array of stats for each file
+});
+```
+
+---------------------------------------
+
+<a name="mapSeries" />
+### mapSeries(arr, iterator, callback)
+
+The same as [`map`](#map), only the `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+The results array will be in the same order as the original.
+
+
+---------------------------------------
+
+<a name="mapLimit" />
+### mapLimit(arr, limit, iterator, callback)
+
+The same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously 
+running at any time.
+
+Note that the items are not processed in batches, so there is no guarantee that 
+the first `limit` `iterator` functions will complete before any others are started.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `limit` - The maximum number of `iterator`s to run at any time.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, transformed)` which must be called once 
+  it has completed with an error (which can be `null`) and a transformed item.
+* `callback(err, results)` - A callback which is called when all `iterator`
+  calls have finished, or an error occurs. The result is an array of the
+  transformed items from the original `arr`.
+
+__Example__
+
+```js
+async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){
+    // results is now an array of stats for each file
+});
+```
+
+---------------------------------------
+
+<a name="select" />
+<a name="filter" />
+### filter(arr, iterator, callback)
+
+__Alias:__ `select`
+
+Returns a new array of all the values in `arr` which pass an async truth test.
+_The callback for each `iterator` call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`. This operation is
+performed in parallel, but the results array will be in the same order as the
+original.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in `arr`.
+  The `iterator` is passed a `callback(truthValue)`, which must be called with a 
+  boolean argument once it has completed.
+* `callback(results)` - A callback which is called after all the `iterator`
+  functions have finished.
+
+__Example__
+
+```js
+async.filter(['file1','file2','file3'], fs.exists, function(results){
+    // results now equals an array of the existing files
+});
+```
+
+---------------------------------------
+
+<a name="selectSeries" />
+<a name="filterSeries" />
+### filterSeries(arr, iterator, callback)
+
+__Alias:__ `selectSeries`
+
+The same as [`filter`](#filter) only the `iterator` is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+The results array will be in the same order as the original.
+
+---------------------------------------
+
+<a name="reject" />
+### reject(arr, iterator, callback)
+
+The opposite of [`filter`](#filter). Removes values that pass an `async` truth test.
+
+---------------------------------------
+
+<a name="rejectSeries" />
+### rejectSeries(arr, iterator, callback)
+
+The same as [`reject`](#reject), only the `iterator` is applied to each item in `arr`
+in series.
+
+
+---------------------------------------
+
+<a name="reduce" />
+### reduce(arr, memo, iterator, callback)
+
+__Aliases:__ `inject`, `foldl`
+
+Reduces `arr` into a single value using an async `iterator` to return
+each successive step. `memo` is the initial state of the reduction. 
+This function only operates in series. 
+
+For performance reasons, it may make sense to split a call to this function into 
+a parallel map, and then use the normal `Array.prototype.reduce` on the results. 
+This function is for situations where each step in the reduction needs to be async; 
+if you can get the data before reducing it, then it's probably a good idea to do so.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `memo` - The initial state of the reduction.
+* `iterator(memo, item, callback)` - A function applied to each item in the
+  array to produce the next step in the reduction. The `iterator` is passed a
+  `callback(err, reduction)` which accepts an optional error as its first 
+  argument, and the state of the reduction as the second. If an error is 
+  passed to the callback, the reduction is stopped and the main `callback` is 
+  immediately called with the error.
+* `callback(err, result)` - A callback which is called after all the `iterator`
+  functions have finished. Result is the reduced value.
+
+__Example__
+
+```js
+async.reduce([1,2,3], 0, function(memo, item, callback){
+    // pointless async:
+    process.nextTick(function(){
+        callback(null, memo + item)
+    });
+}, function(err, result){
+    // result is now equal to the last value of memo, which is 6
+});
+```
+
+---------------------------------------
+
+<a name="reduceRight" />
+### reduceRight(arr, memo, iterator, callback)
+
+__Alias:__ `foldr`
+
+Same as [`reduce`](#reduce), only operates on `arr` in reverse order.
+
+
+---------------------------------------
+
+<a name="detect" />
+### detect(arr, iterator, callback)
+
+Returns the first value in `arr` that passes an async truth test. The
+`iterator` is applied in parallel, meaning the first iterator to return `true` will
+fire the detect `callback` with that result. That means the result might not be
+the first item in the original `arr` (in terms of order) that passes the test.
+
+If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries).
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in `arr`.
+  The iterator is passed a `callback(truthValue)` which must be called with a 
+  boolean argument once it has completed.
+* `callback(result)` - A callback which is called as soon as any iterator returns
+  `true`, or after all the `iterator` functions have finished. Result will be
+  the first item in the array that passes the truth test (iterator) or the
+  value `undefined` if none passed.
+
+__Example__
+
+```js
+async.detect(['file1','file2','file3'], fs.exists, function(result){
+    // result now equals the first file in the list that exists
+});
+```
+
+---------------------------------------
+
+<a name="detectSeries" />
+### detectSeries(arr, iterator, callback)
+
+The same as [`detect`](#detect), only the `iterator` is applied to each item in `arr`
+in series. This means the result is always the first in the original `arr` (in
+terms of array order) that passes the truth test.
+
+
+---------------------------------------
+
+<a name="sortBy" />
+### sortBy(arr, iterator, callback)
+
+Sorts a list by the results of running each `arr` value through an async `iterator`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, sortValue)` which must be called once it
+  has completed with an error (which can be `null`) and a value to use as the sort
+  criteria.
+* `callback(err, results)` - A callback which is called after all the `iterator`
+  functions have finished, or an error occurs. Results is the items from
+  the original `arr` sorted by the values returned by the `iterator` calls.
+
+__Example__
+
+```js
+async.sortBy(['file1','file2','file3'], function(file, callback){
+    fs.stat(file, function(err, stats){
+        callback(err, stats.mtime);
+    });
+}, function(err, results){
+    // results is now the original array of files sorted by
+    // modified date
+});
+```
+
+__Sort Order__
+
+By modifying the callback parameter the sorting order can be influenced:
+
+```js
+//ascending order
+async.sortBy([1,9,3,5], function(x, callback){
+    callback(null, x);
+}, function(err,result){
+    //result callback
+} );
+
+//descending order
+async.sortBy([1,9,3,5], function(x, callback){
+    callback(null, x*-1);    //<- x*-1 instead of x, turns the order around
+}, function(err,result){
+    //result callback
+} );
+```
+
+---------------------------------------
+
+<a name="some" />
+### some(arr, iterator, callback)
+
+__Alias:__ `any`
+
+Returns `true` if at least one element in the `arr` satisfies an async test.
+_The callback for each iterator call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`. Once any iterator
+call returns `true`, the main `callback` is immediately called.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in the array
+  in parallel. The iterator is passed a callback(truthValue) which must be 
+  called with a boolean argument once it has completed.
+* `callback(result)` - A callback which is called as soon as any iterator returns
+  `true`, or after all the iterator functions have finished. Result will be
+  either `true` or `false` depending on the values of the async tests.
+
+__Example__
+
+```js
+async.some(['file1','file2','file3'], fs.exists, function(result){
+    // if result is true then at least one of the files exists
+});
+```
+
+---------------------------------------
+
+<a name="every" />
+### every(arr, iterator, callback)
+
+__Alias:__ `all`
+
+Returns `true` if every element in `arr` satisfies an async test.
+_The callback for each `iterator` call only accepts a single argument of `true` or
+`false`; it does not accept an error argument first!_ This is in-line with the
+way node libraries work with truth tests like `fs.exists`.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A truth test to apply to each item in the array
+  in parallel. The iterator is passed a callback(truthValue) which must be 
+  called with a  boolean argument once it has completed.
+* `callback(result)` - A callback which is called after all the `iterator`
+  functions have finished. Result will be either `true` or `false` depending on
+  the values of the async tests.
+
+__Example__
+
+```js
+async.every(['file1','file2','file3'], fs.exists, function(result){
+    // if result is true then every file exists
+});
+```
+
+---------------------------------------
+
+<a name="concat" />
+### concat(arr, iterator, callback)
+
+Applies `iterator` to each item in `arr`, concatenating the results. Returns the
+concatenated list. The `iterator`s are called in parallel, and the results are
+concatenated as they return. There is no guarantee that the results array will
+be returned in the original order of `arr` passed to the `iterator` function.
+
+__Arguments__
+
+* `arr` - An array to iterate over.
+* `iterator(item, callback)` - A function to apply to each item in `arr`.
+  The iterator is passed a `callback(err, results)` which must be called once it 
+  has completed with an error (which can be `null`) and an array of results.
+* `callback(err, results)` - A callback which is called after all the `iterator`
+  functions have finished, or an error occurs. Results is an array containing
+  the concatenated results of the `iterator` function.
+
+__Example__
+
+```js
+async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){
+    // files is now a list of filenames that exist in the 3 directories
+});
+```
+
+---------------------------------------
+
+<a name="concatSeries" />
+### concatSeries(arr, iterator, callback)
+
+Same as [`concat`](#concat), but executes in series instead of parallel.
+
+
+## Control Flow
+
+<a name="series" />
+### series(tasks, [callback])
+
+Run the functions in the `tasks` array in series, each one running once the previous
+function has completed. If any functions in the series pass an error to its
+callback, no more functions are run, and `callback` is immediately called with the value of the error. 
+Otherwise, `callback` receives an array of results when `tasks` have completed.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function, and the results will be passed to the final `callback` as an object
+instead of an array. This can be a more readable way of handling results from
+[`series`](#series).
+
+**Note** that while many implementations preserve the order of object properties, the
+[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) 
+explicitly states that
+
+> The mechanics and order of enumerating the properties is not specified.
+
+So if you rely on the order in which your series of functions are executed, and want
+this to work on all platforms, consider using an array. 
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run, each function is passed
+  a `callback(err, result)` it must call on completion with an error `err` (which can
+  be `null`) and an optional `result` value.
+* `callback(err, results)` - An optional callback to run once all the functions
+  have completed. This function gets a results array (or object) containing all 
+  the result arguments passed to the `task` callbacks.
+
+__Example__
+
+```js
+async.series([
+    function(callback){
+        // do some stuff ...
+        callback(null, 'one');
+    },
+    function(callback){
+        // do some more stuff ...
+        callback(null, 'two');
+    }
+],
+// optional callback
+function(err, results){
+    // results is now equal to ['one', 'two']
+});
+
+
+// an example using an object instead of an array
+async.series({
+    one: function(callback){
+        setTimeout(function(){
+            callback(null, 1);
+        }, 200);
+    },
+    two: function(callback){
+        setTimeout(function(){
+            callback(null, 2);
+        }, 100);
+    }
+},
+function(err, results) {
+    // results is now equal to: {one: 1, two: 2}
+});
+```
+
+---------------------------------------
+
+<a name="parallel" />
+### parallel(tasks, [callback])
+
+Run the `tasks` array of functions in parallel, without waiting until the previous
+function has completed. If any of the functions pass an error to its
+callback, the main `callback` is immediately called with the value of the error.
+Once the `tasks` have completed, the results are passed to the final `callback` as an
+array.
+
+It is also possible to use an object instead of an array. Each property will be
+run as a function and the results will be passed to the final `callback` as an object
+instead of an array. This can be a more readable way of handling results from
+[`parallel`](#parallel).
+
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run. Each function is passed 
+  a `callback(err, result)` which it must call on completion with an error `err` 
+  (which can be `null`) and an optional `result` value.
+* `callback(err, results)` - An optional callback to run once all the functions
+  have completed. This function gets a results array (or object) containing all 
+  the result arguments passed to the task callbacks.
+
+__Example__
+
+```js
+async.parallel([
+    function(callback){
+        setTimeout(function(){
+            callback(null, 'one');
+        }, 200);
+    },
+    function(callback){
+        setTimeout(function(){
+            callback(null, 'two');
+        }, 100);
+    }
+],
+// optional callback
+function(err, results){
+    // the results array will equal ['one','two'] even though
+    // the second function had a shorter timeout.
+});
+
+
+// an example using an object instead of an array
+async.parallel({
+    one: function(callback){
+        setTimeout(function(){
+            callback(null, 1);
+        }, 200);
+    },
+    two: function(callback){
+        setTimeout(function(){
+            callback(null, 2);
+        }, 100);
+    }
+},
+function(err, results) {
+    // results is now equals to: {one: 1, two: 2}
+});
+```
+
+---------------------------------------
+
+<a name="parallelLimit" />
+### parallelLimit(tasks, limit, [callback])
+
+The same as [`parallel`](#parallel), only `tasks` are executed in parallel 
+with a maximum of `limit` tasks executing at any time.
+
+Note that the `tasks` are not executed in batches, so there is no guarantee that 
+the first `limit` tasks will complete before any others are started.
+
+__Arguments__
+
+* `tasks` - An array or object containing functions to run, each function is passed 
+  a `callback(err, result)` it must call on completion with an error `err` (which can
+  be `null`) and an optional `result` value.
+* `limit` - The maximum number of `tasks` to run at any time.
+* `callback(err, results)` - An optional callback to run once all the functions
+  have completed. This function gets a results array (or object) containing all 
+  the result arguments passed to the `task` callbacks.
+
+---------------------------------------
+
+<a name="whilst" />
+### whilst(test, fn, callback)
+
+Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped,
+or an error occurs.
+
+__Arguments__
+
+* `test()` - synchronous truth test to perform before each execution of `fn`.
+* `fn(callback)` - A function which is called each time `test` passes. The function is
+  passed a `callback(err)`, which must be called once it has completed with an 
+  optional `err` argument.
+* `callback(err)` - A callback which is called after the test fails and repeated
+  execution of `fn` has stopped.
+
+__Example__
+
+```js
+var count = 0;
+
+async.whilst(
+    function () { return count < 5; },
+    function (callback) {
+        count++;
+        setTimeout(callback, 1000);
+    },
+    function (err) {
+        // 5 seconds have passed
+    }
+);
+```
+
+---------------------------------------
+
+<a name="doWhilst" />
+### doWhilst(fn, test, callback)
+
+The post-check version of [`whilst`](#whilst). To reflect the difference in 
+the order of operations, the arguments `test` and `fn` are switched. 
+
+`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
+
+---------------------------------------
+
+<a name="until" />
+### until(test, fn, callback)
+
+Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped,
+or an error occurs.
+
+The inverse of [`whilst`](#whilst).
+
+---------------------------------------
+
+<a name="doUntil" />
+### doUntil(fn, test, callback)
+
+Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`.
+
+---------------------------------------
+
+<a name="forever" />
+### forever(fn, errback)
+
+Calls the asynchronous function `fn` with a callback parameter that allows it to
+call itself again, in series, indefinitely.
+
+If an error is passed to the callback then `errback` is called with the
+error, and execution stops, otherwise it will never be called.
+
+```js
+async.forever(
+    function(next) {
+        // next is suitable for passing to things that need a callback(err [, whatever]);
+        // it will result in this function being called again.
+    },
+    function(err) {
+        // if next is called with a value in its first parameter, it will appear
+        // in here as 'err', and execution will stop.
+    }
+);
+```
+
+---------------------------------------
+
+<a name="waterfall" />
+### waterfall(tasks, [callback])
+
+Runs the `tasks` array of functions in series, each passing their results to the next in
+the array. However, if any of the `tasks` pass an error to their own callback, the
+next function is not executed, and the main `callback` is immediately called with
+the error.
+
+__Arguments__
+
+* `tasks` - An array of functions to run, each function is passed a 
+  `callback(err, result1, result2, ...)` it must call on completion. The first
+  argument is an error (which can be `null`) and any further arguments will be 
+  passed as arguments in order to the next task.
+* `callback(err, [results])` - An optional callback to run once all the functions
+  have completed. This will be passed the results of the last task's callback.
+
+
+
+__Example__
+
+```js
+async.waterfall([
+    function(callback) {
+        callback(null, 'one', 'two');
+    },
+    function(arg1, arg2, callback) {
+      // arg1 now equals 'one' and arg2 now equals 'two'
+        callback(null, 'three');
+    },
+    function(arg1, callback) {
+        // arg1 now equals 'three'
+        callback(null, 'done');
+    }
+], function (err, result) {
+    // result now equals 'done'    
+});
+```
+
+---------------------------------------
+<a name="compose" />
+### compose(fn1, fn2...)
+
+Creates a function which is a composition of the passed asynchronous
+functions. Each function consumes the return value of the function that
+follows. Composing functions `f()`, `g()`, and `h()` would produce the result of
+`f(g(h()))`, only this version uses callbacks to obtain the return values.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* `functions...` - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+function add1(n, callback) {
+    setTimeout(function () {
+        callback(null, n + 1);
+    }, 10);
+}
+
+function mul3(n, callback) {
+    setTimeout(function () {
+        callback(null, n * 3);
+    }, 10);
+}
+
+var add1mul3 = async.compose(mul3, add1);
+
+add1mul3(4, function (err, result) {
+   // result now equals 15
+});
+```
+
+---------------------------------------
+<a name="seq" />
+### seq(fn1, fn2...)
+
+Version of the compose function that is more natural to read.
+Each function consumes the return value of the previous function.
+It is the equivalent of [`compose`](#compose) with the arguments reversed.
+
+Each function is executed with the `this` binding of the composed function.
+
+__Arguments__
+
+* functions... - the asynchronous functions to compose
+
+
+__Example__
+
+```js
+// Requires lodash (or underscore), express3 and dresende's orm2.
+// Part of an app, that fetches cats of the logged user.
+// This example uses `seq` function to avoid overnesting and error 
+// handling clutter.
+app.get('/cats', function(request, response) {
+  var User = request.models.User;
+  async.seq(
+    _.bind(User.get, User),  // 'User.get' has signature (id, callback(err, data))
+    function(user, fn) {
+      user.getCats(fn);      // 'getCats' has signature (callback(err, data))
+    }
+  )(req.session.user_id, function (err, cats) {
+    if (err) {
+      console.error(err);
+      response.json({ status: 'error', message: err.message });
+    } else {
+      response.json({ status: 'ok', message: 'Cats found', data: cats });
+    }
+  });
+});
+```
+
+---------------------------------------
+<a name="applyEach" />
+### applyEach(fns, args..., callback)
+
+Applies the provided arguments to each function in the array, calling 
+`callback` after all functions have completed. If you only provide the first
+argument, then it will return a function which lets you pass in the
+arguments as if it were a single function call.
+
+__Arguments__
+
+* `fns` - the asynchronous functions to all call with the same arguments
+* `args...` - any number of separate arguments to pass to the function
+* `callback` - the final argument should be the callback, called when all
+  functions have completed processing
+
+
+__Example__
+
+```js
+async.applyEach([enableSearch, updateSchema], 'bucket', callback);
+
+// partial application example:
+async.each(
+    buckets,
+    async.applyEach([enableSearch, updateSchema]),
+    callback
+);
+```
+
+---------------------------------------
+
+<a name="applyEachSeries" />
+### applyEachSeries(arr, iterator, callback)
+
+The same as [`applyEach`](#applyEach) only the functions are applied in series.
+
+---------------------------------------
+
+<a name="queue" />
+### queue(worker, concurrency)
+
+Creates a `queue` object with the specified `concurrency`. Tasks added to the
+`queue` are processed in parallel (up to the `concurrency` limit). If all
+`worker`s are in progress, the task is queued until one becomes available. 
+Once a `worker` completes a `task`, that `task`'s callback is called.
+
+__Arguments__
+
+* `worker(task, callback)` - An asynchronous function for processing a queued
+  task, which must call its `callback(err)` argument when finished, with an 
+  optional `error` as an argument.
+* `concurrency` - An `integer` for determining how many `worker` functions should be
+  run in parallel.
+
+__Queue objects__
+
+The `queue` object returned by this function has the following properties and
+methods:
+
+* `length()` - a function returning the number of items waiting to be processed.
+* `started` - a function returning whether or not any items have been pushed and processed by the queue
+* `running()` - a function returning the number of items currently being processed.
+* `idle()` - a function returning false if there are items waiting or being processed, or true if not.
+* `concurrency` - an integer for determining how many `worker` functions should be
+  run in parallel. This property can be changed after a `queue` is created to
+  alter the concurrency on-the-fly.
+* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once 
+  the `worker` has finished processing the task. Instead of a single task, a `tasks` array
+  can be submitted. The respective callback is used for every task in the list.
+* `unshift(task, [callback])` - add a new task to the front of the `queue`.
+* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, 
+   and further tasks will be queued.
+* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`.
+* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`.
+* `paused` - a boolean for determining whether the queue is in a paused state
+* `pause()` - a function that pauses the processing of tasks until `resume()` is called.
+* `resume()` - a function that resumes the processing of queued tasks when the queue is paused.
+* `kill()` - a function that removes the `drain` callback and empties remaining tasks from the queue forcing it to go idle.
+
+__Example__
+
+```js
+// create a queue object with concurrency 2
+
+var q = async.queue(function (task, callback) {
+    console.log('hello ' + task.name);
+    callback();
+}, 2);
+
+
+// assign a callback
+q.drain = function() {
+    console.log('all items have been processed');
+}
+
+// add some items to the queue
+
+q.push({name: 'foo'}, function (err) {
+    console.log('finished processing foo');
+});
+q.push({name: 'bar'}, function (err) {
+    console.log('finished processing bar');
+});
+
+// add some items to the queue (batch-wise)
+
+q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) {
+    console.log('finished processing item');
+});
+
+// add some items to the front of the queue
+
+q.unshift({name: 'bar'}, function (err) {
+    console.log('finished processing bar');
+});
+```
+
+
+---------------------------------------
+
+<a name="priorityQueue" />
+### priorityQueue(worker, concurrency)
+
+The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects:
+
+* `push(task, priority, [callback])` - `priority` should be a number. If an array of
+  `tasks` is given, all tasks will be assigned the same priority.
+* The `unshift` method was removed.
+
+---------------------------------------
+
+<a name="cargo" />
+### cargo(worker, [payload])
+
+Creates a `cargo` object with the specified payload. Tasks added to the
+cargo will be processed altogether (up to the `payload` limit). If the
+`worker` is in progress, the task is queued until it becomes available. Once
+the `worker` has completed some tasks, each callback of those tasks is called.
+Check out [this animation](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) for how `cargo` and `queue` work.
+
+While [queue](#queue) passes only one task to one of a group of workers
+at a time, cargo passes an array of tasks to a single worker, repeating
+when the worker is finished.
+
+__Arguments__
+
+* `worker(tasks, callback)` - An asynchronous function for processing an array of
+  queued tasks, which must call its `callback(err)` argument when finished, with 
+  an optional `err` argument.
+* `payload` - An optional `integer` for determining how many tasks should be
+  processed per round; if omitted, the default is unlimited.
+
+__Cargo objects__
+
+The `cargo` object returned by this function has the following properties and
+methods:
+
+* `length()` - A function returning the number of items waiting to be processed.
+* `payload` - An `integer` for determining how many tasks should be
+  process per round. This property can be changed after a `cargo` is created to
+  alter the payload on-the-fly.
+* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called
+  once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` 
+  can be submitted. The respective callback is used for every task in the list.
+* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued.
+* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`.
+* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`.
+
+__Example__
+
+```js
+// create a cargo object with payload 2
+
+var cargo = async.cargo(function (tasks, callback) {
+    for(var i=0; i<tasks.length; i++){
+      console.log('hello ' + tasks[i].name);
+    }
+    callback();
+}, 2);
+
+
+// add some items
+
+cargo.push({name: 'foo'}, function (err) {
+    console.log('finished processing foo');
+});
+cargo.push({name: 'bar'}, function (err) {
+    console.log('finished processing bar');
+});
+cargo.push({name: 'baz'}, function (err) {
+    console.log('finished processing baz');
+});
+```
+
+---------------------------------------
+
+<a name="auto" />
+### auto(tasks, [callback])
+
+Determines the best order for running the functions in `tasks`, based on their 
+requirements. Each function can optionally depend on other functions being completed 
+first, and each function is run as soon as its requirements are satisfied. 
+
+If any of the functions pass an error to their callback, it will not 
+complete (so any other functions depending on it will not run), and the main 
+`callback` is immediately called with the error. Functions also receive an 
+object containing the results of functions which have completed so far.
+
+Note, all functions are called with a `results` object as a second argument, 
+so it is unsafe to pass functions in the `tasks` object which cannot handle the
+extra argument. 
+
+For example, this snippet of code:
+
+```js
+async.auto({
+  readData: async.apply(fs.readFile, 'data.txt', 'utf-8')
+}, callback);
+```
+
+will have the effect of calling `readFile` with the results object as the last
+argument, which will fail:
+
+```js
+fs.readFile('data.txt', 'utf-8', cb, {});
+```
+
+Instead, wrap the call to `readFile` in a function which does not forward the 
+`results` object:
+
+```js
+async.auto({
+  readData: function(cb, results){
+    fs.readFile('data.txt', 'utf-8', cb);
+  }
+}, callback);
+```
+
+__Arguments__
+
+* `tasks` - An object. Each of its properties is either a function or an array of
+  requirements, with the function itself the last item in the array. The object's key
+  of a property serves as the name of the task defined by that property,
+  i.e. can be used when specifying requirements for other tasks.
+  The function receives two arguments: (1) a `callback(err, result)` which must be 
+  called when finished, passing an `error` (which can be `null`) and the result of 
+  the function's execution, and (2) a `results` object, containing the results of
+  the previously executed functions.
+* `callback(err, results)` - An optional callback which is called when all the
+  tasks have been completed. It receives the `err` argument if any `tasks` 
+  pass an error to their callback. Results are always returned; however, if 
+  an error occurs, no further `tasks` will be performed, and the results
+  object will only contain partial results.
+
+
+__Example__
+
+```js
+async.auto({
+    get_data: function(callback){
+        console.log('in get_data');
+        // async code to get some data
+        callback(null, 'data', 'converted to array');
+    },
+    make_folder: function(callback){
+        console.log('in make_folder');
+        // async code to create a directory to store a file in
+        // this is run at the same time as getting the data
+        callback(null, 'folder');
+    },
+    write_file: ['get_data', 'make_folder', function(callback, results){
+        console.log('in write_file', JSON.stringify(results));
+        // once there is some data and the directory exists,
+        // write the data to a file in the directory
+        callback(null, 'filename');
+    }],
+    email_link: ['write_file', function(callback, results){
+        console.log('in email_link', JSON.stringify(results));
+        // once the file is written let's email a link to it...
+        // results.write_file contains the filename returned by write_file.
+        callback(null, {'file':results.write_file, 'email':'user@example.com'});
+    }]
+}, function(err, results) {
+    console.log('err = ', err);
+    console.log('results = ', results);
+});
+```
+
+This is a fairly trivial example, but to do this using the basic parallel and
+series functions would look like this:
+
+```js
+async.parallel([
+    function(callback){
+        console.log('in get_data');
+        // async code to get some data
+        callback(null, 'data', 'converted to array');
+    },
+    function(callback){
+        console.log('in make_folder');
+        // async code to create a directory to store a file in
+        // this is run at the same time as getting the data
+        callback(null, 'folder');
+    }
+],
+function(err, results){
+    async.series([
+        function(callback){
+            console.log('in write_file', JSON.stringify(results));
+            // once there is some data and the directory exists,
+            // write the data to a file in the directory
+            results.push('filename');
+            callback(null);
+        },
+        function(callback){
+            console.log('in email_link', JSON.stringify(results));
+            // once the file is written let's email a link to it...
+            callback(null, {'file':results.pop(), 'email':'user@example.com'});
+        }
+    ]);
+});
+```
+
+For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding
+new tasks much easier (and the code more readable).
+
+
+---------------------------------------
+
+<a name="retry" />
+### retry([times = 5], task, [callback])
+
+Attempts to get a successful response from `task` no more than `times` times before
+returning an error. If the task is successful, the `callback` will be passed the result
+of the successful task. If all attempts fail, the callback will be passed the error and
+result (if any) of the final attempt.
+
+__Arguments__
+
+* `times` - An integer indicating how many times to attempt the `task` before giving up. Defaults to 5.
+* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)`
+  which must be called when finished, passing `err` (which can be `null`) and the `result` of 
+  the function's execution, and (2) a `results` object, containing the results of
+  the previously executed functions (if nested inside another control flow).
+* `callback(err, results)` - An optional callback which is called when the
+  task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`.
+
+The [`retry`](#retry) function can be used as a stand-alone control flow by passing a
+callback, as shown below:
+
+```js
+async.retry(3, apiMethod, function(err, result) {
+    // do something with the result
+});
+```
+
+It can also be embeded within other control flow functions to retry individual methods
+that are not as reliable, like this:
+
+```js
+async.auto({
+    users: api.getUsers.bind(api),
+    payments: async.retry(3, api.getPayments.bind(api))
+}, function(err, results) {
+  // do something with the results
+});
+```
+
+
+---------------------------------------
+
+<a name="iterator" />
+### iterator(tasks)
+
+Creates an iterator function which calls the next function in the `tasks` array,
+returning a continuation to call the next one after that. It's also possible to
+“peek” at the next iterator with `iterator.next()`.
+
+This function is used internally by the `async` module, but can be useful when
+you want to manually control the flow of functions in series.
+
+__Arguments__
+
+* `tasks` - An array of functions to run.
+
+__Example__
+
+```js
+var iterator = async.iterator([
+    function(){ sys.p('one'); },
+    function(){ sys.p('two'); },
+    function(){ sys.p('three'); }
+]);
+
+node> var iterator2 = iterator();
+'one'
+node> var iterator3 = iterator2();
+'two'
+node> iterator3();
+'three'
+node> var nextfn = iterator2.next();
+node> nextfn();
+'three'
+```
+
+---------------------------------------
+
+<a name="apply" />
+### apply(function, arguments..)
+
+Creates a continuation function with some arguments already applied. 
+
+Useful as a shorthand when combined with other control flow functions. Any arguments
+passed to the returned function are added to the arguments originally passed
+to apply.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to automatically apply when the
+  continuation is called.
+
+__Example__
+
+```js
+// using apply
+
+async.parallel([
+    async.apply(fs.writeFile, 'testfile1', 'test1'),
+    async.apply(fs.writeFile, 'testfile2', 'test2'),
+]);
+
+
+// the same process without using apply
+
+async.parallel([
+    function(callback){
+        fs.writeFile('testfile1', 'test1', callback);
+    },
+    function(callback){
+        fs.writeFile('testfile2', 'test2', callback);
+    }
+]);
+```
+
+It's possible to pass any number of additional arguments when calling the
+continuation:
+
+```js
+node> var fn = async.apply(sys.puts, 'one');
+node> fn('two', 'three');
+one
+two
+three
+```
+
+---------------------------------------
+
+<a name="nextTick" />
+### nextTick(callback), setImmediate(callback)
+
+Calls `callback` on a later loop around the event loop. In Node.js this just
+calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)`
+if available, otherwise `setTimeout(callback, 0)`, which means other higher priority
+events may precede the execution of `callback`.
+
+This is used internally for browser-compatibility purposes.
+
+__Arguments__
+
+* `callback` - The function to call on a later loop around the event loop.
+
+__Example__
+
+```js
+var call_order = [];
+async.nextTick(function(){
+    call_order.push('two');
+    // call_order now equals ['one','two']
+});
+call_order.push('one')
+```
+
+<a name="times" />
+### times(n, callback)
+
+Calls the `callback` function `n` times, and accumulates results in the same manner
+you would use with [`map`](#map).
+
+__Arguments__
+
+* `n` - The number of times to run the function.
+* `callback` - The function to call `n` times.
+
+__Example__
+
+```js
+// Pretend this is some complicated async factory
+var createUser = function(id, callback) {
+  callback(null, {
+    id: 'user' + id
+  })
+}
+// generate 5 users
+async.times(5, function(n, next){
+    createUser(n, function(err, user) {
+      next(err, user)
+    })
+}, function(err, users) {
+  // we should now have 5 users
+});
+```
+
+<a name="timesSeries" />
+### timesSeries(n, callback)
+
+The same as [`times`](#times), only the iterator is applied to each item in `arr` in
+series. The next `iterator` is only called once the current one has completed. 
+The results array will be in the same order as the original.
+
+
+## Utils
+
+<a name="memoize" />
+### memoize(fn, [hasher])
+
+Caches the results of an `async` function. When creating a hash to store function
+results against, the callback is omitted from the hash and an optional hash
+function can be used.
+
+The cache of results is exposed as the `memo` property of the function returned
+by `memoize`.
+
+__Arguments__
+
+* `fn` - The function to proxy and cache results from.
+* `hasher` - Tn optional function for generating a custom hash for storing
+  results. It has all the arguments applied to it apart from the callback, and
+  must be synchronous.
+
+__Example__
+
+```js
+var slow_fn = function (name, callback) {
+    // do something
+    callback(null, result);
+};
+var fn = async.memoize(slow_fn);
+
+// fn can now be used as if it were slow_fn
+fn('some name', function () {
+    // callback
+});
+```
+
+<a name="unmemoize" />
+### unmemoize(fn)
+
+Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized
+form. Handy for testing.
+
+__Arguments__
+
+* `fn` - the memoized function
+
+<a name="log" />
+### log(function, arguments)
+
+Logs the result of an `async` function to the `console`. Only works in Node.js or
+in browsers that support `console.log` and `console.error` (such as FF and Chrome).
+If multiple arguments are returned from the async function, `console.log` is
+called on each argument in order.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to apply to the function.
+
+__Example__
+
+```js
+var hello = function(name, callback){
+    setTimeout(function(){
+        callback(null, 'hello ' + name);
+    }, 1000);
+};
+```
+```js
+node> async.log(hello, 'world');
+'hello world'
+```
+
+---------------------------------------
+
+<a name="dir" />
+### dir(function, arguments)
+
+Logs the result of an `async` function to the `console` using `console.dir` to
+display the properties of the resulting object. Only works in Node.js or
+in browsers that support `console.dir` and `console.error` (such as FF and Chrome).
+If multiple arguments are returned from the async function, `console.dir` is
+called on each argument in order.
+
+__Arguments__
+
+* `function` - The function you want to eventually apply all arguments to.
+* `arguments...` - Any number of arguments to apply to the function.
+
+__Example__
+
+```js
+var hello = function(name, callback){
+    setTimeout(function(){
+        callback(null, {hello: name});
+    }, 1000);
+};
+```
+```js
+node> async.dir(hello, 'world');
+{hello: 'world'}
+```
+
+---------------------------------------
+
+<a name="noConflict" />
+### noConflict()
+
+Changes the value of `async` back to its original value, returning a reference to the
+`async` object.
diff --git a/d2d_app/node_modules/async/bower.json b/d2d_app/node_modules/async/bower.json
new file mode 100644 (file)
index 0000000..1817688
--- /dev/null
@@ -0,0 +1,38 @@
+{
+  "name": "async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "version": "0.9.2",
+  "main": "lib/async.js",
+  "keywords": [
+    "async",
+    "callback",
+    "utility",
+    "module"
+  ],
+  "license": "MIT",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/caolan/async.git"
+  },
+  "devDependencies": {
+    "nodeunit": ">0.0.0",
+    "uglify-js": "1.2.x",
+    "nodelint": ">0.0.0",
+    "lodash": ">=2.4.1"
+  },
+  "moduleType": [
+    "amd",
+    "globals",
+    "node"
+  ],
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ],
+  "authors": [
+    "Caolan McMahon"
+  ]
+}
\ No newline at end of file
diff --git a/d2d_app/node_modules/async/component.json b/d2d_app/node_modules/async/component.json
new file mode 100644 (file)
index 0000000..5003a7c
--- /dev/null
@@ -0,0 +1,16 @@
+{
+  "name": "async",
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "version": "0.9.2",
+  "keywords": [
+    "async",
+    "callback",
+    "utility",
+    "module"
+  ],
+  "license": "MIT",
+  "repository": "caolan/async",
+  "scripts": [
+    "lib/async.js"
+  ]
+}
\ No newline at end of file
diff --git a/d2d_app/node_modules/async/lib/async.js b/d2d_app/node_modules/async/lib/async.js
new file mode 100644 (file)
index 0000000..394c41c
--- /dev/null
@@ -0,0 +1,1123 @@
+/*!
+ * async
+ * https://github.com/caolan/async
+ *
+ * Copyright 2010-2014 Caolan McMahon
+ * Released under the MIT license
+ */
+/*jshint onevar: false, indent:4 */
+/*global setImmediate: false, setTimeout: false, console: false */
+(function () {
+
+    var async = {};
+
+    // global on the server, window in the browser
+    var root, previous_async;
+
+    root = this;
+    if (root != null) {
+      previous_async = root.async;
+    }
+
+    async.noConflict = function () {
+        root.async = previous_async;
+        return async;
+    };
+
+    function only_once(fn) {
+        var called = false;
+        return function() {
+            if (called) throw new Error("Callback was already called.");
+            called = true;
+            fn.apply(root, arguments);
+        }
+    }
+
+    //// cross-browser compatiblity functions ////
+
+    var _toString = Object.prototype.toString;
+
+    var _isArray = Array.isArray || function (obj) {
+        return _toString.call(obj) === '[object Array]';
+    };
+
+    var _each = function (arr, iterator) {
+        for (var i = 0; i < arr.length; i += 1) {
+            iterator(arr[i], i, arr);
+        }
+    };
+
+    var _map = function (arr, iterator) {
+        if (arr.map) {
+            return arr.map(iterator);
+        }
+        var results = [];
+        _each(arr, function (x, i, a) {
+            results.push(iterator(x, i, a));
+        });
+        return results;
+    };
+
+    var _reduce = function (arr, iterator, memo) {
+        if (arr.reduce) {
+            return arr.reduce(iterator, memo);
+        }
+        _each(arr, function (x, i, a) {
+            memo = iterator(memo, x, i, a);
+        });
+        return memo;
+    };
+
+    var _keys = function (obj) {
+        if (Object.keys) {
+            return Object.keys(obj);
+        }
+        var keys = [];
+        for (var k in obj) {
+            if (obj.hasOwnProperty(k)) {
+                keys.push(k);
+            }
+        }
+        return keys;
+    };
+
+    //// exported async module functions ////
+
+    //// nextTick implementation with browser-compatible fallback ////
+    if (typeof process === 'undefined' || !(process.nextTick)) {
+        if (typeof setImmediate === 'function') {
+            async.nextTick = function (fn) {
+                // not a direct alias for IE10 compatibility
+                setImmediate(fn);
+            };
+            async.setImmediate = async.nextTick;
+        }
+        else {
+            async.nextTick = function (fn) {
+                setTimeout(fn, 0);
+            };
+            async.setImmediate = async.nextTick;
+        }
+    }
+    else {
+        async.nextTick = process.nextTick;
+        if (typeof setImmediate !== 'undefined') {
+            async.setImmediate = function (fn) {
+              // not a direct alias for IE10 compatibility
+              setImmediate(fn);
+            };
+        }
+        else {
+            async.setImmediate = async.nextTick;
+        }
+    }
+
+    async.each = function (arr, iterator, callback) {
+        callback = callback || function () {};
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        _each(arr, function (x) {
+            iterator(x, only_once(done) );
+        });
+        function done(err) {
+          if (err) {
+              callback(err);
+              callback = function () {};
+          }
+          else {
+              completed += 1;
+              if (completed >= arr.length) {
+                  callback();
+              }
+          }
+        }
+    };
+    async.forEach = async.each;
+
+    async.eachSeries = function (arr, iterator, callback) {
+        callback = callback || function () {};
+        if (!arr.length) {
+            return callback();
+        }
+        var completed = 0;
+        var iterate = function () {
+            iterator(arr[completed], function (err) {
+                if (err) {
+                    callback(err);
+                    callback = function () {};
+                }
+                else {
+                    completed += 1;
+                    if (completed >= arr.length) {
+                        callback();
+                    }
+                    else {
+                        iterate();
+                    }
+                }
+            });
+        };
+        iterate();
+    };
+    async.forEachSeries = async.eachSeries;
+
+    async.eachLimit = function (arr, limit, iterator, callback) {
+        var fn = _eachLimit(limit);
+        fn.apply(null, [arr, iterator, callback]);
+    };
+    async.forEachLimit = async.eachLimit;
+
+    var _eachLimit = function (limit) {
+
+        return function (arr, iterator, callback) {
+            callback = callback || function () {};
+            if (!arr.length || limit <= 0) {
+                return callback();
+            }
+            var completed = 0;
+            var started = 0;
+            var running = 0;
+
+            (function replenish () {
+                if (completed >= arr.length) {
+                    return callback();
+                }
+
+                while (running < limit && started < arr.length) {
+                    started += 1;
+                    running += 1;
+                    iterator(arr[started - 1], function (err) {
+                        if (err) {
+                            callback(err);
+                            callback = function () {};
+                        }
+                        else {
+                            completed += 1;
+                            running -= 1;
+                            if (completed >= arr.length) {
+                                callback();
+                            }
+                            else {
+                                replenish();
+                            }
+                        }
+                    });
+                }
+            })();
+        };
+    };
+
+
+    var doParallel = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.each].concat(args));
+        };
+    };
+    var doParallelLimit = function(limit, fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [_eachLimit(limit)].concat(args));
+        };
+    };
+    var doSeries = function (fn) {
+        return function () {
+            var args = Array.prototype.slice.call(arguments);
+            return fn.apply(null, [async.eachSeries].concat(args));
+        };
+    };
+
+
+    var _asyncMap = function (eachfn, arr, iterator, callback) {
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        if (!callback) {
+            eachfn(arr, function (x, callback) {
+                iterator(x.value, function (err) {
+                    callback(err);
+                });
+            });
+        } else {
+            var results = [];
+            eachfn(arr, function (x, callback) {
+                iterator(x.value, function (err, v) {
+                    results[x.index] = v;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+    async.map = doParallel(_asyncMap);
+    async.mapSeries = doSeries(_asyncMap);
+    async.mapLimit = function (arr, limit, iterator, callback) {
+        return _mapLimit(limit)(arr, iterator, callback);
+    };
+
+    var _mapLimit = function(limit) {
+        return doParallelLimit(limit, _asyncMap);
+    };
+
+    // reduce only has a series version, as doing reduce in parallel won't
+    // work in many situations.
+    async.reduce = function (arr, memo, iterator, callback) {
+        async.eachSeries(arr, function (x, callback) {
+            iterator(memo, x, function (err, v) {
+                memo = v;
+                callback(err);
+            });
+        }, function (err) {
+            callback(err, memo);
+        });
+    };
+    // inject alias
+    async.inject = async.reduce;
+    // foldl alias
+    async.foldl = async.reduce;
+
+    async.reduceRight = function (arr, memo, iterator, callback) {
+        var reversed = _map(arr, function (x) {
+            return x;
+        }).reverse();
+        async.reduce(reversed, memo, iterator, callback);
+    };
+    // foldr alias
+    async.foldr = async.reduceRight;
+
+    var _filter = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.filter = doParallel(_filter);
+    async.filterSeries = doSeries(_filter);
+    // select alias
+    async.select = async.filter;
+    async.selectSeries = async.filterSeries;
+
+    var _reject = function (eachfn, arr, iterator, callback) {
+        var results = [];
+        arr = _map(arr, function (x, i) {
+            return {index: i, value: x};
+        });
+        eachfn(arr, function (x, callback) {
+            iterator(x.value, function (v) {
+                if (!v) {
+                    results.push(x);
+                }
+                callback();
+            });
+        }, function (err) {
+            callback(_map(results.sort(function (a, b) {
+                return a.index - b.index;
+            }), function (x) {
+                return x.value;
+            }));
+        });
+    };
+    async.reject = doParallel(_reject);
+    async.rejectSeries = doSeries(_reject);
+
+    var _detect = function (eachfn, arr, iterator, main_callback) {
+        eachfn(arr, function (x, callback) {
+            iterator(x, function (result) {
+                if (result) {
+                    main_callback(x);
+                    main_callback = function () {};
+                }
+                else {
+                    callback();
+                }
+            });
+        }, function (err) {
+            main_callback();
+        });
+    };
+    async.detect = doParallel(_detect);
+    async.detectSeries = doSeries(_detect);
+
+    async.some = function (arr, iterator, main_callback) {
+        async.each(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (v) {
+                    main_callback(true);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(false);
+        });
+    };
+    // any alias
+    async.any = async.some;
+
+    async.every = function (arr, iterator, main_callback) {
+        async.each(arr, function (x, callback) {
+            iterator(x, function (v) {
+                if (!v) {
+                    main_callback(false);
+                    main_callback = function () {};
+                }
+                callback();
+            });
+        }, function (err) {
+            main_callback(true);
+        });
+    };
+    // all alias
+    async.all = async.every;
+
+    async.sortBy = function (arr, iterator, callback) {
+        async.map(arr, function (x, callback) {
+            iterator(x, function (err, criteria) {
+                if (err) {
+                    callback(err);
+                }
+                else {
+                    callback(null, {value: x, criteria: criteria});
+                }
+            });
+        }, function (err, results) {
+            if (err) {
+                return callback(err);
+            }
+            else {
+                var fn = function (left, right) {
+                    var a = left.criteria, b = right.criteria;
+                    return a < b ? -1 : a > b ? 1 : 0;
+                };
+                callback(null, _map(results.sort(fn), function (x) {
+                    return x.value;
+                }));
+            }
+        });
+    };
+
+    async.auto = function (tasks, callback) {
+        callback = callback || function () {};
+        var keys = _keys(tasks);
+        var remainingTasks = keys.length
+        if (!remainingTasks) {
+            return callback();
+        }
+
+        var results = {};
+
+        var listeners = [];
+        var addListener = function (fn) {
+            listeners.unshift(fn);
+        };
+        var removeListener = function (fn) {
+            for (var i = 0; i < listeners.length; i += 1) {
+                if (listeners[i] === fn) {
+                    listeners.splice(i, 1);
+                    return;
+                }
+            }
+        };
+        var taskComplete = function () {
+            remainingTasks--
+            _each(listeners.slice(0), function (fn) {
+                fn();
+            });
+        };
+
+        addListener(function () {
+            if (!remainingTasks) {
+                var theCallback = callback;
+                // prevent final callback from calling itself if it errors
+                callback = function () {};
+
+                theCallback(null, results);
+            }
+        });
+
+        _each(keys, function (k) {
+            var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
+            var taskCallback = function (err) {
+                var args = Array.prototype.slice.call(arguments, 1);
+                if (args.length <= 1) {
+                    args = args[0];
+                }
+                if (err) {
+                    var safeResults = {};
+                    _each(_keys(results), function(rkey) {
+                        safeResults[rkey] = results[rkey];
+                    });
+                    safeResults[k] = args;
+                    callback(err, safeResults);
+                    // stop subsequent errors hitting callback multiple times
+                    callback = function () {};
+                }
+                else {
+                    results[k] = args;
+                    async.setImmediate(taskComplete);
+                }
+            };
+            var requires = task.slice(0, Math.abs(task.length - 1)) || [];
+            var ready = function () {
+                return _reduce(requires, function (a, x) {
+                    return (a && results.hasOwnProperty(x));
+                }, true) && !results.hasOwnProperty(k);
+            };
+            if (ready()) {
+                task[task.length - 1](taskCallback, results);
+            }
+            else {
+                var listener = function () {
+                    if (ready()) {
+                        removeListener(listener);
+                        task[task.length - 1](taskCallback, results);
+                    }
+                };
+                addListener(listener);
+            }
+        });
+    };
+
+    async.retry = function(times, task, callback) {
+        var DEFAULT_TIMES = 5;
+        var attempts = [];
+        // Use defaults if times not passed
+        if (typeof times === 'function') {
+            callback = task;
+            task = times;
+            times = DEFAULT_TIMES;
+        }
+        // Make sure times is a number
+        times = parseInt(times, 10) || DEFAULT_TIMES;
+        var wrappedTask = function(wrappedCallback, wrappedResults) {
+            var retryAttempt = function(task, finalAttempt) {
+                return function(seriesCallback) {
+                    task(function(err, result){
+                        seriesCallback(!err || finalAttempt, {err: err, result: result});
+                    }, wrappedResults);
+                };
+            };
+            while (times) {
+                attempts.push(retryAttempt(task, !(times-=1)));
+            }
+            async.series(attempts, function(done, data){
+                data = data[data.length - 1];
+                (wrappedCallback || callback)(data.err, data.result);
+            });
+        }
+        // If a callback is passed, run this as a controll flow
+        return callback ? wrappedTask() : wrappedTask
+    };
+
+    async.waterfall = function (tasks, callback) {
+        callback = callback || function () {};
+        if (!_isArray(tasks)) {
+          var err = new Error('First argument to waterfall must be an array of functions');
+          return callback(err);
+        }
+        if (!tasks.length) {
+            return callback();
+        }
+        var wrapIterator = function (iterator) {
+            return function (err) {
+                if (err) {
+                    callback.apply(null, arguments);
+                    callback = function () {};
+                }
+                else {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    var next = iterator.next();
+                    if (next) {
+                        args.push(wrapIterator(next));
+                    }
+                    else {
+                        args.push(callback);
+                    }
+                    async.setImmediate(function () {
+                        iterator.apply(null, args);
+                    });
+                }
+            };
+        };
+        wrapIterator(async.iterator(tasks))();
+    };
+
+    var _parallel = function(eachfn, tasks, callback) {
+        callback = callback || function () {};
+        if (_isArray(tasks)) {
+            eachfn.map(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            eachfn.each(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.parallel = function (tasks, callback) {
+        _parallel({ map: async.map, each: async.each }, tasks, callback);
+    };
+
+    async.parallelLimit = function(tasks, limit, callback) {
+        _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
+    };
+
+    async.series = function (tasks, callback) {
+        callback = callback || function () {};
+        if (_isArray(tasks)) {
+            async.mapSeries(tasks, function (fn, callback) {
+                if (fn) {
+                    fn(function (err) {
+                        var args = Array.prototype.slice.call(arguments, 1);
+                        if (args.length <= 1) {
+                            args = args[0];
+                        }
+                        callback.call(null, err, args);
+                    });
+                }
+            }, callback);
+        }
+        else {
+            var results = {};
+            async.eachSeries(_keys(tasks), function (k, callback) {
+                tasks[k](function (err) {
+                    var args = Array.prototype.slice.call(arguments, 1);
+                    if (args.length <= 1) {
+                        args = args[0];
+                    }
+                    results[k] = args;
+                    callback(err);
+                });
+            }, function (err) {
+                callback(err, results);
+            });
+        }
+    };
+
+    async.iterator = function (tasks) {
+        var makeCallback = function (index) {
+            var fn = function () {
+                if (tasks.length) {
+                    tasks[index].apply(null, arguments);
+                }
+                return fn.next();
+            };
+            fn.next = function () {
+                return (index < tasks.length - 1) ? makeCallback(index + 1): null;
+            };
+            return fn;
+        };
+        return makeCallback(0);
+    };
+
+    async.apply = function (fn) {
+        var args = Array.prototype.slice.call(arguments, 1);
+        return function () {
+            return fn.apply(
+                null, args.concat(Array.prototype.slice.call(arguments))
+            );
+        };
+    };
+
+    var _concat = function (eachfn, arr, fn, callback) {
+        var r = [];
+        eachfn(arr, function (x, cb) {
+            fn(x, function (err, y) {
+                r = r.concat(y || []);
+                cb(err);
+            });
+        }, function (err) {
+            callback(err, r);
+        });
+    };
+    async.concat = doParallel(_concat);
+    async.concatSeries = doSeries(_concat);
+
+    async.whilst = function (test, iterator, callback) {
+        if (test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.whilst(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.doWhilst = function (iterator, test, callback) {
+        iterator(function (err) {
+            if (err) {
+                return callback(err);
+            }
+            var args = Array.prototype.slice.call(arguments, 1);
+            if (test.apply(null, args)) {
+                async.doWhilst(iterator, test, callback);
+            }
+            else {
+                callback();
+            }
+        });
+    };
+
+    async.until = function (test, iterator, callback) {
+        if (!test()) {
+            iterator(function (err) {
+                if (err) {
+                    return callback(err);
+                }
+                async.until(test, iterator, callback);
+            });
+        }
+        else {
+            callback();
+        }
+    };
+
+    async.doUntil = function (iterator, test, callback) {
+        iterator(function (err) {
+            if (err) {
+                return callback(err);
+            }
+            var args = Array.prototype.slice.call(arguments, 1);
+            if (!test.apply(null, args)) {
+                async.doUntil(iterator, test, callback);
+            }
+            else {
+                callback();
+            }
+        });
+    };
+
+    async.queue = function (worker, concurrency) {
+        if (concurrency === undefined) {
+            concurrency = 1;
+        }
+        function _insert(q, data, pos, callback) {
+          if (!q.started){
+            q.started = true;
+          }
+          if (!_isArray(data)) {
+              data = [data];
+          }
+          if(data.length == 0) {
+             // call drain immediately if there are no tasks
+             return async.setImmediate(function() {
+                 if (q.drain) {
+                     q.drain();
+                 }
+             });
+          }
+          _each(data, function(task) {
+              var item = {
+                  data: task,
+                  callback: typeof callback === 'function' ? callback : null
+              };
+
+              if (pos) {
+                q.tasks.unshift(item);
+              } else {
+                q.tasks.push(item);
+              }
+
+              if (q.saturated && q.tasks.length === q.concurrency) {
+                  q.saturated();
+              }
+              async.setImmediate(q.process);
+          });
+        }
+
+        var workers = 0;
+        var q = {
+            tasks: [],
+            concurrency: concurrency,
+            saturated: null,
+            empty: null,
+            drain: null,
+            started: false,
+            paused: false,
+            push: function (data, callback) {
+              _insert(q, data, false, callback);
+            },
+            kill: function () {
+              q.drain = null;
+              q.tasks = [];
+            },
+            unshift: function (data, callback) {
+              _insert(q, data, true, callback);
+            },
+            process: function () {
+                if (!q.paused && workers < q.concurrency && q.tasks.length) {
+                    var task = q.tasks.shift();
+                    if (q.empty && q.tasks.length === 0) {
+                        q.empty();
+                    }
+                    workers += 1;
+                    var next = function () {
+                        workers -= 1;
+                        if (task.callback) {
+                            task.callback.apply(task, arguments);
+                        }
+                        if (q.drain && q.tasks.length + workers === 0) {
+                            q.drain();
+                        }
+                        q.process();
+                    };
+                    var cb = only_once(next);
+                    worker(task.data, cb);
+                }
+            },
+            length: function () {
+                return q.tasks.length;
+            },
+            running: function () {
+                return workers;
+            },
+            idle: function() {
+                return q.tasks.length + workers === 0;
+            },
+            pause: function () {
+                if (q.paused === true) { return; }
+                q.paused = true;
+            },
+            resume: function () {
+                if (q.paused === false) { return; }
+                q.paused = false;
+                // Need to call q.process once per concurrent
+                // worker to preserve full concurrency after pause
+                for (var w = 1; w <= q.concurrency; w++) {
+                    async.setImmediate(q.process);
+                }
+            }
+        };
+        return q;
+    };
+
+    async.priorityQueue = function (worker, concurrency) {
+
+        function _compareTasks(a, b){
+          return a.priority - b.priority;
+        };
+
+        function _binarySearch(sequence, item, compare) {
+          var beg = -1,
+              end = sequence.length - 1;
+          while (beg < end) {
+            var mid = beg + ((end - beg + 1) >>> 1);
+            if (compare(item, sequence[mid]) >= 0) {
+              beg = mid;
+            } else {
+              end = mid - 1;
+            }
+          }
+          return beg;
+        }
+
+        function _insert(q, data, priority, callback) {
+          if (!q.started){
+            q.started = true;
+          }
+          if (!_isArray(data)) {
+              data = [data];
+          }
+          if(data.length == 0) {
+             // call drain immediately if there are no tasks
+             return async.setImmediate(function() {
+                 if (q.drain) {
+                     q.drain();
+                 }
+             });
+          }
+          _each(data, function(task) {
+              var item = {
+                  data: task,
+                  priority: priority,
+                  callback: typeof callback === 'function' ? callback : null
+              };
+
+              q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
+
+              if (q.saturated && q.tasks.length === q.concurrency) {
+                  q.saturated();
+              }
+              async.setImmediate(q.process);
+          });
+        }
+
+        // Start with a normal queue
+        var q = async.queue(worker, concurrency);
+
+        // Override push to accept second parameter representing priority
+        q.push = function (data, priority, callback) {
+          _insert(q, data, priority, callback);
+        };
+
+        // Remove unshift function
+        delete q.unshift;
+
+        return q;
+    };
+
+    async.cargo = function (worker, payload) {
+        var working     = false,
+            tasks       = [];
+
+        var cargo = {
+            tasks: tasks,
+            payload: payload,
+            saturated: null,
+            empty: null,
+            drain: null,
+            drained: true,
+            push: function (data, callback) {
+                if (!_isArray(data)) {
+                    data = [data];
+                }
+                _each(data, function(task) {
+                    tasks.push({
+                        data: task,
+                        callback: typeof callback === 'function' ? callback : null
+                    });
+                    cargo.drained = false;
+                    if (cargo.saturated && tasks.length === payload) {
+                        cargo.saturated();
+                    }
+                });
+                async.setImmediate(cargo.process);
+            },
+            process: function process() {
+                if (working) return;
+                if (tasks.length === 0) {
+                    if(cargo.drain && !cargo.drained) cargo.drain();
+                    cargo.drained = true;
+                    return;
+                }
+
+                var ts = typeof payload === 'number'
+                            ? tasks.splice(0, payload)
+                            : tasks.splice(0, tasks.length);
+
+                var ds = _map(ts, function (task) {
+                    return task.data;
+                });
+
+                if(cargo.empty) cargo.empty();
+                working = true;
+                worker(ds, function () {
+                    working = false;
+
+                    var args = arguments;
+                    _each(ts, function (data) {
+                        if (data.callback) {
+                            data.callback.apply(null, args);
+                        }
+                    });
+
+                    process();
+                });
+            },
+            length: function () {
+                return tasks.length;
+            },
+            running: function () {
+                return working;
+            }
+        };
+        return cargo;
+    };
+
+    var _console_fn = function (name) {
+        return function (fn) {
+            var args = Array.prototype.slice.call(arguments, 1);
+            fn.apply(null, args.concat([function (err) {
+                var args = Array.prototype.slice.call(arguments, 1);
+                if (typeof console !== 'undefined') {
+                    if (err) {
+                        if (console.error) {
+                            console.error(err);
+                        }
+                    }
+                    else if (console[name]) {
+                        _each(args, function (x) {
+                            console[name](x);
+                        });
+                    }
+                }
+            }]));
+        };
+    };
+    async.log = _console_fn('log');
+    async.dir = _console_fn('dir');
+    /*async.info = _console_fn('info');
+    async.warn = _console_fn('warn');
+    async.error = _console_fn('error');*/
+
+    async.memoize = function (fn, hasher) {
+        var memo = {};
+        var queues = {};
+        hasher = hasher || function (x) {
+            return x;
+        };
+        var memoized = function () {
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            var key = hasher.apply(null, args);
+            if (key in memo) {
+                async.nextTick(function () {
+                    callback.apply(null, memo[key]);
+                });
+            }
+            else if (key in queues) {
+                queues[key].push(callback);
+            }
+            else {
+                queues[key] = [callback];
+                fn.apply(null, args.concat([function () {
+                    memo[key] = arguments;
+                    var q = queues[key];
+                    delete queues[key];
+                    for (var i = 0, l = q.length; i < l; i++) {
+                      q[i].apply(null, arguments);
+                    }
+                }]));
+            }
+        };
+        memoized.memo = memo;
+        memoized.unmemoized = fn;
+        return memoized;
+    };
+
+    async.unmemoize = function (fn) {
+      return function () {
+        return (fn.unmemoized || fn).apply(null, arguments);
+      };
+    };
+
+    async.times = function (count, iterator, callback) {
+        var counter = [];
+        for (var i = 0; i < count; i++) {
+            counter.push(i);
+        }
+        return async.map(counter, iterator, callback);
+    };
+
+    async.timesSeries = function (count, iterator, callback) {
+        var counter = [];
+        for (var i = 0; i < count; i++) {
+            counter.push(i);
+        }
+        return async.mapSeries(counter, iterator, callback);
+    };
+
+    async.seq = function (/* functions... */) {
+        var fns = arguments;
+        return function () {
+            var that = this;
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            async.reduce(fns, args, function (newargs, fn, cb) {
+                fn.apply(that, newargs.concat([function () {
+                    var err = arguments[0];
+                    var nextargs = Array.prototype.slice.call(arguments, 1);
+                    cb(err, nextargs);
+                }]))
+            },
+            function (err, results) {
+                callback.apply(that, [err].concat(results));
+            });
+        };
+    };
+
+    async.compose = function (/* functions... */) {
+      return async.seq.apply(null, Array.prototype.reverse.call(arguments));
+    };
+
+    var _applyEach = function (eachfn, fns /*args...*/) {
+        var go = function () {
+            var that = this;
+            var args = Array.prototype.slice.call(arguments);
+            var callback = args.pop();
+            return eachfn(fns, function (fn, cb) {
+                fn.apply(that, args.concat([cb]));
+            },
+            callback);
+        };
+        if (arguments.length > 2) {
+            var args = Array.prototype.slice.call(arguments, 2);
+            return go.apply(this, args);
+        }
+        else {
+            return go;
+        }
+    };
+    async.applyEach = doParallel(_applyEach);
+    async.applyEachSeries = doSeries(_applyEach);
+
+    async.forever = function (fn, callback) {
+        function next(err) {
+            if (err) {
+                if (callback) {
+                    return callback(err);
+                }
+                throw err;
+            }
+            fn(next);
+        }
+        next();
+    };
+
+    // Node.js
+    if (typeof module !== 'undefined' && module.exports) {
+        module.exports = async;
+    }
+    // AMD / RequireJS
+    else if (typeof define !== 'undefined' && define.amd) {
+        define([], function () {
+            return async;
+        });
+    }
+    // included directly via <script> tag
+    else {
+        root.async = async;
+    }
+
+}());
diff --git a/d2d_app/node_modules/async/package.json b/d2d_app/node_modules/async/package.json
new file mode 100644 (file)
index 0000000..bad95a5
--- /dev/null
@@ -0,0 +1,82 @@
+{
+  "_from": "async@0.9.x",
+  "_id": "async@0.9.2",
+  "_inBundle": false,
+  "_integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
+  "_location": "/async",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "async@0.9.x",
+    "name": "async",
+    "escapedName": "async",
+    "rawSpec": "0.9.x",
+    "saveSpec": null,
+    "fetchSpec": "0.9.x"
+  },
+  "_requiredBy": [
+    "/jake"
+  ],
+  "_resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+  "_shasum": "aea74d5e61c1f899613bf64bda66d4c78f2fd17d",
+  "_spec": "async@0.9.x",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/jake",
+  "author": {
+    "name": "Caolan McMahon"
+  },
+  "bugs": {
+    "url": "https://github.com/caolan/async/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Higher-order functions and common patterns for asynchronous code",
+  "devDependencies": {
+    "lodash": ">=2.4.1",
+    "nodelint": ">0.0.0",
+    "nodeunit": ">0.0.0",
+    "uglify-js": "1.2.x"
+  },
+  "homepage": "https://github.com/caolan/async#readme",
+  "jam": {
+    "main": "lib/async.js",
+    "include": [
+      "lib/async.js",
+      "README.md",
+      "LICENSE"
+    ],
+    "categories": [
+      "Utilities"
+    ]
+  },
+  "keywords": [
+    "async",
+    "callback",
+    "utility",
+    "module"
+  ],
+  "license": "MIT",
+  "main": "lib/async.js",
+  "name": "async",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/caolan/async.git"
+  },
+  "scripts": {
+    "test": "nodeunit test/test-async.js"
+  },
+  "spm": {
+    "main": "lib/async.js"
+  },
+  "version": "0.9.2",
+  "volo": {
+    "main": "lib/async.js",
+    "ignore": [
+      "**/.*",
+      "node_modules",
+      "bower_components",
+      "test",
+      "tests"
+    ]
+  }
+}
diff --git a/d2d_app/node_modules/async/support/sync-package-managers.js b/d2d_app/node_modules/async/support/sync-package-managers.js
new file mode 100755 (executable)
index 0000000..30cb7c2
--- /dev/null
@@ -0,0 +1,53 @@
+#!/usr/bin/env node
+
+// This should probably be its own module but complaints about bower/etc.
+// support keep coming up and I'd rather just enable the workflow here for now
+// and figure out where this should live later. -- @beaugunderson
+
+var fs = require('fs');
+var _ = require('lodash');
+
+var packageJson = require('../package.json');
+
+var IGNORES = ['**/.*', 'node_modules', 'bower_components', 'test', 'tests'];
+var INCLUDES = ['lib/async.js', 'README.md', 'LICENSE'];
+var REPOSITORY_NAME = 'caolan/async';
+
+packageJson.jam = {
+  main: packageJson.main,
+  include: INCLUDES,
+  categories: ['Utilities']
+};
+
+packageJson.spm = {
+  main: packageJson.main
+};
+
+packageJson.volo = {
+  main: packageJson.main,
+  ignore: IGNORES
+};
+
+var bowerSpecific = {
+  moduleType: ['amd', 'globals', 'node'],
+  ignore: IGNORES,
+  authors: [packageJson.author]
+};
+
+var bowerInclude = ['name', 'description', 'version', 'main', 'keywords',
+  'license', 'homepage', 'repository', 'devDependencies'];
+
+var componentSpecific = {
+  repository: REPOSITORY_NAME,
+  scripts: [packageJson.main]
+};
+
+var componentInclude = ['name', 'description', 'version', 'keywords',
+  'license'];
+
+var bowerJson = _.merge({}, _.pick(packageJson, bowerInclude), bowerSpecific);
+var componentJson = _.merge({}, _.pick(packageJson, componentInclude), componentSpecific);
+
+fs.writeFileSync('./bower.json', JSON.stringify(bowerJson, null, 2));
+fs.writeFileSync('./component.json', JSON.stringify(componentJson, null, 2));
+fs.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2));
diff --git a/d2d_app/node_modules/balanced-match/.npmignore b/d2d_app/node_modules/balanced-match/.npmignore
new file mode 100644 (file)
index 0000000..ae5d8c3
--- /dev/null
@@ -0,0 +1,5 @@
+test
+.gitignore
+.travis.yml
+Makefile
+example.js
diff --git a/d2d_app/node_modules/balanced-match/LICENSE.md b/d2d_app/node_modules/balanced-match/LICENSE.md
new file mode 100644 (file)
index 0000000..2cdc8e4
--- /dev/null
@@ -0,0 +1,21 @@
+(MIT)
+
+Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/d2d_app/node_modules/balanced-match/README.md b/d2d_app/node_modules/balanced-match/README.md
new file mode 100644 (file)
index 0000000..08e918c
--- /dev/null
@@ -0,0 +1,91 @@
+# balanced-match
+
+Match balanced string pairs, like `{` and `}` or `<b>` and `</b>`. Supports regular expressions as well!
+
+[![build status](https://secure.travis-ci.org/juliangruber/balanced-match.svg)](http://travis-ci.org/juliangruber/balanced-match)
+[![downloads](https://img.shields.io/npm/dm/balanced-match.svg)](https://www.npmjs.org/package/balanced-match)
+
+[![testling badge](https://ci.testling.com/juliangruber/balanced-match.png)](https://ci.testling.com/juliangruber/balanced-match)
+
+## Example
+
+Get the first matching pair of braces:
+
+```js
+var balanced = require('balanced-match');
+
+console.log(balanced('{', '}', 'pre{in{nested}}post'));
+console.log(balanced('{', '}', 'pre{first}between{second}post'));
+console.log(balanced(/\s+\{\s+/, /\s+\}\s+/, 'pre  {   in{nest}   }  post'));
+```
+
+The matches are:
+
+```bash
+$ node example.js
+{ start: 3, end: 14, pre: 'pre', body: 'in{nested}', post: 'post' }
+{ start: 3,
+  end: 9,
+  pre: 'pre',
+  body: 'first',
+  post: 'between{second}post' }
+{ start: 3, end: 17, pre: 'pre', body: 'in{nest}', post: 'post' }
+```
+
+## API
+
+### var m = balanced(a, b, str)
+
+For the first non-nested matching pair of `a` and `b` in `str`, return an
+object with those keys:
+
+* **start** the index of the first match of `a`
+* **end** the index of the matching `b`
+* **pre** the preamble, `a` and `b` not included
+* **body** the match, `a` and `b` not included
+* **post** the postscript, `a` and `b` not included
+
+If there's no match, `undefined` will be returned.
+
+If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `['{', 'a', '']` and `{a}}` will match `['', 'a', '}']`.
+
+### var r = balanced.range(a, b, str)
+
+For the first non-nested matching pair of `a` and `b` in `str`, return an
+array with indexes: `[ <a index>, <b index> ]`.
+
+If there's no match, `undefined` will be returned.
+
+If the `str` contains more `a` than `b` / there are unmatched pairs, the first match that was closed will be used. For example, `{{a}` will match `[ 1, 3 ]` and `{a}}` will match `[0, 2]`.
+
+## Installation
+
+With [npm](https://npmjs.org) do:
+
+```bash
+npm install balanced-match
+```
+
+## License
+
+(MIT)
+
+Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/d2d_app/node_modules/balanced-match/index.js b/d2d_app/node_modules/balanced-match/index.js
new file mode 100644 (file)
index 0000000..1685a76
--- /dev/null
@@ -0,0 +1,59 @@
+'use strict';
+module.exports = balanced;
+function balanced(a, b, str) {
+  if (a instanceof RegExp) a = maybeMatch(a, str);
+  if (b instanceof RegExp) b = maybeMatch(b, str);
+
+  var r = range(a, b, str);
+
+  return r && {
+    start: r[0],
+    end: r[1],
+    pre: str.slice(0, r[0]),
+    body: str.slice(r[0] + a.length, r[1]),
+    post: str.slice(r[1] + b.length)
+  };
+}
+
+function maybeMatch(reg, str) {
+  var m = str.match(reg);
+  return m ? m[0] : null;
+}
+
+balanced.range = range;
+function range(a, b, str) {
+  var begs, beg, left, right, result;
+  var ai = str.indexOf(a);
+  var bi = str.indexOf(b, ai + 1);
+  var i = ai;
+
+  if (ai >= 0 && bi > 0) {
+    begs = [];
+    left = str.length;
+
+    while (i >= 0 && !result) {
+      if (i == ai) {
+        begs.push(i);
+        ai = str.indexOf(a, i + 1);
+      } else if (begs.length == 1) {
+        result = [ begs.pop(), bi ];
+      } else {
+        beg = begs.pop();
+        if (beg < left) {
+          left = beg;
+          right = bi;
+        }
+
+        bi = str.indexOf(b, i + 1);
+      }
+
+      i = ai < bi && ai >= 0 ? ai : bi;
+    }
+
+    if (begs.length) {
+      result = [ left, right ];
+    }
+  }
+
+  return result;
+}
diff --git a/d2d_app/node_modules/balanced-match/package.json b/d2d_app/node_modules/balanced-match/package.json
new file mode 100644 (file)
index 0000000..7ba0b98
--- /dev/null
@@ -0,0 +1,77 @@
+{
+  "_from": "balanced-match@^1.0.0",
+  "_id": "balanced-match@1.0.0",
+  "_inBundle": false,
+  "_integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+  "_location": "/balanced-match",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "balanced-match@^1.0.0",
+    "name": "balanced-match",
+    "escapedName": "balanced-match",
+    "rawSpec": "^1.0.0",
+    "saveSpec": null,
+    "fetchSpec": "^1.0.0"
+  },
+  "_requiredBy": [
+    "/brace-expansion"
+  ],
+  "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+  "_shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767",
+  "_spec": "balanced-match@^1.0.0",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/brace-expansion",
+  "author": {
+    "name": "Julian Gruber",
+    "email": "mail@juliangruber.com",
+    "url": "http://juliangruber.com"
+  },
+  "bugs": {
+    "url": "https://github.com/juliangruber/balanced-match/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {},
+  "deprecated": false,
+  "description": "Match balanced character pairs, like \"{\" and \"}\"",
+  "devDependencies": {
+    "matcha": "^0.7.0",
+    "tape": "^4.6.0"
+  },
+  "homepage": "https://github.com/juliangruber/balanced-match",
+  "keywords": [
+    "match",
+    "regexp",
+    "test",
+    "balanced",
+    "parse"
+  ],
+  "license": "MIT",
+  "main": "index.js",
+  "name": "balanced-match",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/juliangruber/balanced-match.git"
+  },
+  "scripts": {
+    "bench": "make bench",
+    "test": "make test"
+  },
+  "testling": {
+    "files": "test/*.js",
+    "browsers": [
+      "ie/8..latest",
+      "firefox/20..latest",
+      "firefox/nightly",
+      "chrome/25..latest",
+      "chrome/canary",
+      "opera/12..latest",
+      "opera/next",
+      "safari/5.1..latest",
+      "ipad/6.0..latest",
+      "iphone/6.0..latest",
+      "android-browser/4.2..latest"
+    ]
+  },
+  "version": "1.0.0"
+}
@@ -1,6 +1,6 @@
-The MIT License (MIT)
+MIT License
 
-Copyright (c) 2016 Zeit, Inc.
+Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/d2d_app/node_modules/brace-expansion/README.md b/d2d_app/node_modules/brace-expansion/README.md
new file mode 100644 (file)
index 0000000..6b4e0e1
--- /dev/null
@@ -0,0 +1,129 @@
+# brace-expansion
+
+[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html), 
+as known from sh/bash, in JavaScript.
+
+[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion)
+[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion)
+[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/)
+
+[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion)
+
+## Example
+
+```js
+var expand = require('brace-expansion');
+
+expand('file-{a,b,c}.jpg')
+// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
+
+expand('-v{,,}')
+// => ['-v', '-v', '-v']
+
+expand('file{0..2}.jpg')
+// => ['file0.jpg', 'file1.jpg', 'file2.jpg']
+
+expand('file-{a..c}.jpg')
+// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
+
+expand('file{2..0}.jpg')
+// => ['file2.jpg', 'file1.jpg', 'file0.jpg']
+
+expand('file{0..4..2}.jpg')
+// => ['file0.jpg', 'file2.jpg', 'file4.jpg']
+
+expand('file-{a..e..2}.jpg')
+// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg']
+
+expand('file{00..10..5}.jpg')
+// => ['file00.jpg', 'file05.jpg', 'file10.jpg']
+
+expand('{{A..C},{a..c}}')
+// => ['A', 'B', 'C', 'a', 'b', 'c']
+
+expand('ppp{,config,oe{,conf}}')
+// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf']
+```
+
+## API
+
+```js
+var expand = require('brace-expansion');
+```
+
+### var expanded = expand(str)
+
+Return an array of all possible and valid expansions of `str`. If none are
+found, `[str]` is returned.
+
+Valid expansions are:
+
+```js
+/^(.*,)+(.+)?$/
+// {a,b,...}
+```
+
+A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`.
+
+```js
+/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
+// {x..y[..incr]}
+```
+
+A numeric sequence from `x` to `y` inclusive, with optional increment.
+If `x` or `y` start with a leading `0`, all the numbers will be padded
+to have equal length. Negative numbers and backwards iteration work too.
+
+```js
+/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
+// {x..y[..incr]}
+```
+
+An alphabetic sequence from `x` to `y` inclusive, with optional increment.
+`x` and `y` must be exactly one character, and if given, `incr` must be a
+number.
+
+For compatibility reasons, the string `${` is not eligible for brace expansion.
+
+## Installation
+
+With [npm](https://npmjs.org) do:
+
+```bash
+npm install brace-expansion
+```
+
+## Contributors
+
+- [Julian Gruber](https://github.com/juliangruber)
+- [Isaac Z. Schlueter](https://github.com/isaacs)
+
+## Sponsors
+
+This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)!
+
+Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)!
+
+## License
+
+(MIT)
+
+Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/d2d_app/node_modules/brace-expansion/index.js b/d2d_app/node_modules/brace-expansion/index.js
new file mode 100644 (file)
index 0000000..0478be8
--- /dev/null
@@ -0,0 +1,201 @@
+var concatMap = require('concat-map');
+var balanced = require('balanced-match');
+
+module.exports = expandTop;
+
+var escSlash = '\0SLASH'+Math.random()+'\0';
+var escOpen = '\0OPEN'+Math.random()+'\0';
+var escClose = '\0CLOSE'+Math.random()+'\0';
+var escComma = '\0COMMA'+Math.random()+'\0';
+var escPeriod = '\0PERIOD'+Math.random()+'\0';
+
+function numeric(str) {
+  return parseInt(str, 10) == str
+    ? parseInt(str, 10)
+    : str.charCodeAt(0);
+}
+
+function escapeBraces(str) {
+  return str.split('\\\\').join(escSlash)
+            .split('\\{').join(escOpen)
+            .split('\\}').join(escClose)
+            .split('\\,').join(escComma)
+            .split('\\.').join(escPeriod);
+}
+
+function unescapeBraces(str) {
+  return str.split(escSlash).join('\\')
+            .split(escOpen).join('{')
+            .split(escClose).join('}')
+            .split(escComma).join(',')
+            .split(escPeriod).join('.');
+}
+
+
+// Basically just str.split(","), but handling cases
+// where we have nested braced sections, which should be
+// treated as individual members, like {a,{b,c},d}
+function parseCommaParts(str) {
+  if (!str)
+    return [''];
+
+  var parts = [];
+  var m = balanced('{', '}', str);
+
+  if (!m)
+    return str.split(',');
+
+  var pre = m.pre;
+  var body = m.body;
+  var post = m.post;
+  var p = pre.split(',');
+
+  p[p.length-1] += '{' + body + '}';
+  var postParts = parseCommaParts(post);
+  if (post.length) {
+    p[p.length-1] += postParts.shift();
+    p.push.apply(p, postParts);
+  }
+
+  parts.push.apply(parts, p);
+
+  return parts;
+}
+
+function expandTop(str) {
+  if (!str)
+    return [];
+
+  // I don't know why Bash 4.3 does this, but it does.
+  // Anything starting with {} will have the first two bytes preserved
+  // but *only* at the top level, so {},a}b will not expand to anything,
+  // but a{},b}c will be expanded to [a}c,abc].
+  // One could argue that this is a bug in Bash, but since the goal of
+  // this module is to match Bash's rules, we escape a leading {}
+  if (str.substr(0, 2) === '{}') {
+    str = '\\{\\}' + str.substr(2);
+  }
+
+  return expand(escapeBraces(str), true).map(unescapeBraces);
+}
+
+function identity(e) {
+  return e;
+}
+
+function embrace(str) {
+  return '{' + str + '}';
+}
+function isPadded(el) {
+  return /^-?0\d/.test(el);
+}
+
+function lte(i, y) {
+  return i <= y;
+}
+function gte(i, y) {
+  return i >= y;
+}
+
+function expand(str, isTop) {
+  var expansions = [];
+
+  var m = balanced('{', '}', str);
+  if (!m || /\$$/.test(m.pre)) return [str];
+
+  var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
+  var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
+  var isSequence = isNumericSequence || isAlphaSequence;
+  var isOptions = m.body.indexOf(',') >= 0;
+  if (!isSequence && !isOptions) {
+    // {a},b}
+    if (m.post.match(/,.*\}/)) {
+      str = m.pre + '{' + m.body + escClose + m.post;
+      return expand(str);
+    }
+    return [str];
+  }
+
+  var n;
+  if (isSequence) {
+    n = m.body.split(/\.\./);
+  } else {
+    n = parseCommaParts(m.body);
+    if (n.length === 1) {
+      // x{{a,b}}y ==> x{a}y x{b}y
+      n = expand(n[0], false).map(embrace);
+      if (n.length === 1) {
+        var post = m.post.length
+          ? expand(m.post, false)
+          : [''];
+        return post.map(function(p) {
+          return m.pre + n[0] + p;
+        });
+      }
+    }
+  }
+
+  // at this point, n is the parts, and we know it's not a comma set
+  // with a single entry.
+
+  // no need to expand pre, since it is guaranteed to be free of brace-sets
+  var pre = m.pre;
+  var post = m.post.length
+    ? expand(m.post, false)
+    : [''];
+
+  var N;
+
+  if (isSequence) {
+    var x = numeric(n[0]);
+    var y = numeric(n[1]);
+    var width = Math.max(n[0].length, n[1].length)
+    var incr = n.length == 3
+      ? Math.abs(numeric(n[2]))
+      : 1;
+    var test = lte;
+    var reverse = y < x;
+    if (reverse) {
+      incr *= -1;
+      test = gte;
+    }
+    var pad = n.some(isPadded);
+
+    N = [];
+
+    for (var i = x; test(i, y); i += incr) {
+      var c;
+      if (isAlphaSequence) {
+        c = String.fromCharCode(i);
+        if (c === '\\')
+          c = '';
+      } else {
+        c = String(i);
+        if (pad) {
+          var need = width - c.length;
+          if (need > 0) {
+            var z = new Array(need + 1).join('0');
+            if (i < 0)
+              c = '-' + z + c.slice(1);
+            else
+              c = z + c;
+          }
+        }
+      }
+      N.push(c);
+    }
+  } else {
+    N = concatMap(n, function(el) { return expand(el, false) });
+  }
+
+  for (var j = 0; j < N.length; j++) {
+    for (var k = 0; k < post.length; k++) {
+      var expansion = pre + N[j] + post[k];
+      if (!isTop || isSequence || expansion)
+        expansions.push(expansion);
+    }
+  }
+
+  return expansions;
+}
+
diff --git a/d2d_app/node_modules/brace-expansion/package.json b/d2d_app/node_modules/brace-expansion/package.json
new file mode 100644 (file)
index 0000000..9bf5e54
--- /dev/null
@@ -0,0 +1,75 @@
+{
+  "_from": "brace-expansion@^1.1.7",
+  "_id": "brace-expansion@1.1.11",
+  "_inBundle": false,
+  "_integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+  "_location": "/brace-expansion",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "brace-expansion@^1.1.7",
+    "name": "brace-expansion",
+    "escapedName": "brace-expansion",
+    "rawSpec": "^1.1.7",
+    "saveSpec": null,
+    "fetchSpec": "^1.1.7"
+  },
+  "_requiredBy": [
+    "/minimatch"
+  ],
+  "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+  "_shasum": "3c7fcbf529d87226f3d2f52b966ff5271eb441dd",
+  "_spec": "brace-expansion@^1.1.7",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/minimatch",
+  "author": {
+    "name": "Julian Gruber",
+    "email": "mail@juliangruber.com",
+    "url": "http://juliangruber.com"
+  },
+  "bugs": {
+    "url": "https://github.com/juliangruber/brace-expansion/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "balanced-match": "^1.0.0",
+    "concat-map": "0.0.1"
+  },
+  "deprecated": false,
+  "description": "Brace expansion as known from sh/bash",
+  "devDependencies": {
+    "matcha": "^0.7.0",
+    "tape": "^4.6.0"
+  },
+  "homepage": "https://github.com/juliangruber/brace-expansion",
+  "keywords": [],
+  "license": "MIT",
+  "main": "index.js",
+  "name": "brace-expansion",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/juliangruber/brace-expansion.git"
+  },
+  "scripts": {
+    "bench": "matcha test/perf/bench.js",
+    "gentest": "bash test/generate.sh",
+    "test": "tape test/*.js"
+  },
+  "testling": {
+    "files": "test/*.js",
+    "browsers": [
+      "ie/8..latest",
+      "firefox/20..latest",
+      "firefox/nightly",
+      "chrome/25..latest",
+      "chrome/canary",
+      "opera/12..latest",
+      "opera/next",
+      "safari/5.1..latest",
+      "ipad/6.0..latest",
+      "iphone/6.0..latest",
+      "android-browser/4.2..latest"
+    ]
+  },
+  "version": "1.1.11"
+}
diff --git a/d2d_app/node_modules/chalk/index.js b/d2d_app/node_modules/chalk/index.js
new file mode 100644 (file)
index 0000000..1cc5fa8
--- /dev/null
@@ -0,0 +1,228 @@
+'use strict';
+const escapeStringRegexp = require('escape-string-regexp');
+const ansiStyles = require('ansi-styles');
+const stdoutColor = require('supports-color').stdout;
+
+const template = require('./templates.js');
+
+const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm');
+
+// `supportsColor.level` → `ansiStyles.color[name]` mapping
+const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m'];
+
+// `color-convert` models to exclude from the Chalk API due to conflicts and such
+const skipModels = new Set(['gray']);
+
+const styles = Object.create(null);
+
+function applyOptions(obj, options) {
+       options = options || {};
+
+       // Detect level if not set manually
+       const scLevel = stdoutColor ? stdoutColor.level : 0;
+       obj.level = options.level === undefined ? scLevel : options.level;
+       obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0;
+}
+
+function Chalk(options) {
+       // We check for this.template here since calling `chalk.constructor()`
+       // by itself will have a `this` of a previously constructed chalk object
+       if (!this || !(this instanceof Chalk) || this.template) {
+               const chalk = {};
+               applyOptions(chalk, options);
+
+               chalk.template = function () {
+                       const args = [].slice.call(arguments);
+                       return chalkTag.apply(null, [chalk.template].concat(args));
+               };
+
+               Object.setPrototypeOf(chalk, Chalk.prototype);
+               Object.setPrototypeOf(chalk.template, chalk);
+
+               chalk.template.constructor = Chalk;
+
+               return chalk.template;
+       }
+
+       applyOptions(this, options);
+}
+
+// Use bright blue on Windows as the normal blue color is illegible
+if (isSimpleWindowsTerm) {
+       ansiStyles.blue.open = '\u001B[94m';
+}
+
+for (const key of Object.keys(ansiStyles)) {
+       ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g');
+
+       styles[key] = {
+               get() {
+                       const codes = ansiStyles[key];
+                       return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key);
+               }
+       };
+}
+
+styles.visible = {
+       get() {
+               return build.call(this, this._styles || [], true, 'visible');
+       }
+};
+
+ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g');
+for (const model of Object.keys(ansiStyles.color.ansi)) {
+       if (skipModels.has(model)) {
+               continue;
+       }
+
+       styles[model] = {
+               get() {
+                       const level = this.level;
+                       return function () {
+                               const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments);
+                               const codes = {
+                                       open,
+                                       close: ansiStyles.color.close,
+                                       closeRe: ansiStyles.color.closeRe
+                               };
+                               return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
+                       };
+               }
+       };
+}
+
+ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g');
+for (const model of Object.keys(ansiStyles.bgColor.ansi)) {
+       if (skipModels.has(model)) {
+               continue;
+       }
+
+       const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
+       styles[bgModel] = {
+               get() {
+                       const level = this.level;
+                       return function () {
+                               const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments);
+                               const codes = {
+                                       open,
+                                       close: ansiStyles.bgColor.close,
+                                       closeRe: ansiStyles.bgColor.closeRe
+                               };
+                               return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model);
+                       };
+               }
+       };
+}
+
+const proto = Object.defineProperties(() => {}, styles);
+
+function build(_styles, _empty, key) {
+       const builder = function () {
+               return applyStyle.apply(builder, arguments);
+       };
+
+       builder._styles = _styles;
+       builder._empty = _empty;
+
+       const self = this;
+
+       Object.defineProperty(builder, 'level', {
+               enumerable: true,
+               get() {
+                       return self.level;
+               },
+               set(level) {
+                       self.level = level;
+               }
+       });
+
+       Object.defineProperty(builder, 'enabled', {
+               enumerable: true,
+               get() {
+                       return self.enabled;
+               },
+               set(enabled) {
+                       self.enabled = enabled;
+               }
+       });
+
+       // See below for fix regarding invisible grey/dim combination on Windows
+       builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey';
+
+       // `__proto__` is used because we must return a function, but there is
+       // no way to create a function with a different prototype
+       builder.__proto__ = proto; // eslint-disable-line no-proto
+
+       return builder;
+}
+
+function applyStyle() {
+       // Support varags, but simply cast to string in case there's only one arg
+       const args = arguments;
+       const argsLen = args.length;
+       let str = String(arguments[0]);
+
+       if (argsLen === 0) {
+               return '';
+       }
+
+       if (argsLen > 1) {
+               // Don't slice `arguments`, it prevents V8 optimizations
+               for (let a = 1; a < argsLen; a++) {
+                       str += ' ' + args[a];
+               }
+       }
+
+       if (!this.enabled || this.level <= 0 || !str) {
+               return this._empty ? '' : str;
+       }
+
+       // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe,
+       // see https://github.com/chalk/chalk/issues/58
+       // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop.
+       const originalDim = ansiStyles.dim.open;
+       if (isSimpleWindowsTerm && this.hasGrey) {
+               ansiStyles.dim.open = '';
+       }
+
+       for (const code of this._styles.slice().reverse()) {
+               // Replace any instances already present with a re-opening code
+               // otherwise only the part of the string until said closing code
+               // will be colored, and the rest will simply be 'plain'.
+               str = code.open + str.replace(code.closeRe, code.open) + code.close;
+
+               // Close the styling before a linebreak and reopen
+               // after next line to fix a bleed issue on macOS
+               // https://github.com/chalk/chalk/pull/92
+               str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`);
+       }
+
+       // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue
+       ansiStyles.dim.open = originalDim;
+
+       return str;
+}
+
+function chalkTag(chalk, strings) {
+       if (!Array.isArray(strings)) {
+               // If chalk() was called by itself or with a string,
+               // return the string itself as a string.
+               return [].slice.call(arguments, 1).join(' ');
+       }
+
+       const args = [].slice.call(arguments, 2);
+       const parts = [strings.raw[0]];
+
+       for (let i = 1; i < strings.length; i++) {
+               parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&'));
+               parts.push(String(strings.raw[i]));
+       }
+
+       return template(chalk, parts.join(''));
+}
+
+Object.defineProperties(Chalk.prototype, styles);
+
+module.exports = Chalk(); // eslint-disable-line new-cap
+module.exports.supportsColor = stdoutColor;
+module.exports.default = module.exports; // For TypeScript
diff --git a/d2d_app/node_modules/chalk/index.js.flow b/d2d_app/node_modules/chalk/index.js.flow
new file mode 100644 (file)
index 0000000..622caaa
--- /dev/null
@@ -0,0 +1,93 @@
+// @flow strict
+
+type TemplateStringsArray = $ReadOnlyArray<string>;
+
+export type Level = $Values<{
+       None: 0,
+       Basic: 1,
+       Ansi256: 2,
+       TrueColor: 3
+}>;
+
+export type ChalkOptions = {|
+       enabled?: boolean,
+       level?: Level
+|};
+
+export type ColorSupport = {|
+       level: Level,
+       hasBasic: boolean,
+       has256: boolean,
+       has16m: boolean
+|};
+
+export interface Chalk {
+       (...text: string[]): string,
+       (text: TemplateStringsArray, ...placeholders: string[]): string,
+       constructor(options?: ChalkOptions): Chalk,
+       enabled: boolean,
+       level: Level,
+       rgb(r: number, g: number, b: number): Chalk,
+       hsl(h: number, s: number, l: number): Chalk,
+       hsv(h: number, s: number, v: number): Chalk,
+       hwb(h: number, w: number, b: number): Chalk,
+       bgHex(color: string): Chalk,
+       bgKeyword(color: string): Chalk,
+       bgRgb(r: number, g: number, b: number): Chalk,
+       bgHsl(h: number, s: number, l: number): Chalk,
+       bgHsv(h: number, s: number, v: number): Chalk,
+       bgHwb(h: number, w: number, b: number): Chalk,
+       hex(color: string): Chalk,
+       keyword(color: string): Chalk,
+
+       +reset: Chalk,
+       +bold: Chalk,
+       +dim: Chalk,
+       +italic: Chalk,
+       +underline: Chalk,
+       +inverse: Chalk,
+       +hidden: Chalk,
+       +strikethrough: Chalk,
+
+       +visible: Chalk,
+
+       +black: Chalk,
+       +red: Chalk,
+       +green: Chalk,
+       +yellow: Chalk,
+       +blue: Chalk,
+       +magenta: Chalk,
+       +cyan: Chalk,
+       +white: Chalk,
+       +gray: Chalk,
+       +grey: Chalk,
+       +blackBright: Chalk,
+       +redBright: Chalk,
+       +greenBright: Chalk,
+       +yellowBright: Chalk,
+       +blueBright: Chalk,
+       +magentaBright: Chalk,
+       +cyanBright: Chalk,
+       +whiteBright: Chalk,
+
+       +bgBlack: Chalk,
+       +bgRed: Chalk,
+       +bgGreen: Chalk,
+       +bgYellow: Chalk,
+       +bgBlue: Chalk,
+       +bgMagenta: Chalk,
+       +bgCyan: Chalk,
+       +bgWhite: Chalk,
+       +bgBlackBright: Chalk,
+       +bgRedBright: Chalk,
+       +bgGreenBright: Chalk,
+       +bgYellowBright: Chalk,
+       +bgBlueBright: Chalk,
+       +bgMagentaBright: Chalk,
+       +bgCyanBright: Chalk,
+       +bgWhiteBrigh: Chalk,
+
+       supportsColor: ColorSupport
+};
+
+declare module.exports: Chalk;
diff --git a/d2d_app/node_modules/chalk/license b/d2d_app/node_modules/chalk/license
new file mode 100644 (file)
index 0000000..e7af2f7
--- /dev/null
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/chalk/package.json b/d2d_app/node_modules/chalk/package.json
new file mode 100644 (file)
index 0000000..a8ae929
--- /dev/null
@@ -0,0 +1,103 @@
+{
+  "_from": "chalk@^2.4.2",
+  "_id": "chalk@2.4.2",
+  "_inBundle": false,
+  "_integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+  "_location": "/chalk",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "chalk@^2.4.2",
+    "name": "chalk",
+    "escapedName": "chalk",
+    "rawSpec": "^2.4.2",
+    "saveSpec": null,
+    "fetchSpec": "^2.4.2"
+  },
+  "_requiredBy": [
+    "/jake"
+  ],
+  "_resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+  "_shasum": "cd42541677a54333cf541a49108c1432b44c9424",
+  "_spec": "chalk@^2.4.2",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/jake",
+  "bugs": {
+    "url": "https://github.com/chalk/chalk/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "ansi-styles": "^3.2.1",
+    "escape-string-regexp": "^1.0.5",
+    "supports-color": "^5.3.0"
+  },
+  "deprecated": false,
+  "description": "Terminal string styling done right",
+  "devDependencies": {
+    "ava": "*",
+    "coveralls": "^3.0.0",
+    "execa": "^0.9.0",
+    "flow-bin": "^0.68.0",
+    "import-fresh": "^2.0.0",
+    "matcha": "^0.7.0",
+    "nyc": "^11.0.2",
+    "resolve-from": "^4.0.0",
+    "typescript": "^2.5.3",
+    "xo": "*"
+  },
+  "engines": {
+    "node": ">=4"
+  },
+  "files": [
+    "index.js",
+    "templates.js",
+    "types/index.d.ts",
+    "index.js.flow"
+  ],
+  "homepage": "https://github.com/chalk/chalk#readme",
+  "keywords": [
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "string",
+    "str",
+    "ansi",
+    "style",
+    "styles",
+    "tty",
+    "formatting",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "log",
+    "logging",
+    "command-line",
+    "text"
+  ],
+  "license": "MIT",
+  "name": "chalk",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/chalk/chalk.git"
+  },
+  "scripts": {
+    "bench": "matcha benchmark.js",
+    "coveralls": "nyc report --reporter=text-lcov | coveralls",
+    "test": "xo && tsc --project types && flow --max-warnings=0 && nyc ava"
+  },
+  "types": "types/index.d.ts",
+  "version": "2.4.2",
+  "xo": {
+    "envs": [
+      "node",
+      "mocha"
+    ],
+    "ignores": [
+      "test/_flow.js"
+    ]
+  }
+}
diff --git a/d2d_app/node_modules/chalk/readme.md b/d2d_app/node_modules/chalk/readme.md
new file mode 100644 (file)
index 0000000..d298e2c
--- /dev/null
@@ -0,0 +1,314 @@
+<h1 align="center">
+       <br>
+       <br>
+       <img width="320" src="media/logo.svg" alt="Chalk">
+       <br>
+       <br>
+       <br>
+</h1>
+
+> Terminal string styling done right
+
+[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs)
+
+### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0)
+
+<img src="https://cdn.rawgit.com/chalk/ansi-styles/8261697c95bf34b6c7767e2cbe9941a851d59385/screenshot.svg" alt="" width="900">
+
+
+## Highlights
+
+- Expressive API
+- Highly performant
+- Ability to nest styles
+- [256/Truecolor color support](#256-and-truecolor-color-support)
+- Auto-detects color support
+- Doesn't extend `String.prototype`
+- Clean and focused
+- Actively maintained
+- [Used by ~23,000 packages](https://www.npmjs.com/browse/depended/chalk) as of December 31, 2017
+
+
+## Install
+
+```console
+$ npm install chalk
+```
+
+<a href="https://www.patreon.com/sindresorhus">
+       <img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160">
+</a>
+
+
+## Usage
+
+```js
+const chalk = require('chalk');
+
+console.log(chalk.blue('Hello world!'));
+```
+
+Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
+
+```js
+const chalk = require('chalk');
+const log = console.log;
+
+// Combine styled and normal strings
+log(chalk.blue('Hello') + ' World' + chalk.red('!'));
+
+// Compose multiple styles using the chainable API
+log(chalk.blue.bgRed.bold('Hello world!'));
+
+// Pass in multiple arguments
+log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'));
+
+// Nest styles
+log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!'));
+
+// Nest styles of the same type even (color, underline, background)
+log(chalk.green(
+       'I am a green line ' +
+       chalk.blue.underline.bold('with a blue substring') +
+       ' that becomes green again!'
+));
+
+// ES2015 template literal
+log(`
+CPU: ${chalk.red('90%')}
+RAM: ${chalk.green('40%')}
+DISK: ${chalk.yellow('70%')}
+`);
+
+// ES2015 tagged template literal
+log(chalk`
+CPU: {red ${cpu.totalPercent}%}
+RAM: {green ${ram.used / ram.total * 100}%}
+DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%}
+`);
+
+// Use RGB colors in terminal emulators that support it.
+log(chalk.keyword('orange')('Yay for orange colored text!'));
+log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
+log(chalk.hex('#DEADED').bold('Bold gray!'));
+```
+
+Easily define your own themes:
+
+```js
+const chalk = require('chalk');
+
+const error = chalk.bold.red;
+const warning = chalk.keyword('orange');
+
+console.log(error('Error!'));
+console.log(warning('Warning!'));
+```
+
+Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args):
+
+```js
+const name = 'Sindre';
+console.log(chalk.green('Hello %s'), name);
+//=> 'Hello Sindre'
+```
+
+
+## API
+
+### chalk.`<style>[.<style>...](string, [string...])`
+
+Example: `chalk.red.bold.underline('Hello', 'world');`
+
+Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`.
+
+Multiple arguments will be separated by space.
+
+### chalk.enabled
+
+Color support is automatically detected, as is the level (see `chalk.level`). However, if you'd like to simply enable/disable Chalk, you can do so via the `.enabled` property.
+
+Chalk is enabled by default unless explicitly disabled via the constructor or `chalk.level` is `0`.
+
+If you need to change this in a reusable module, create a new instance:
+
+```js
+const ctx = new chalk.constructor({enabled: false});
+```
+
+### chalk.level
+
+Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers.
+
+If you need to change this in a reusable module, create a new instance:
+
+```js
+const ctx = new chalk.constructor({level: 0});
+```
+
+Levels are as follows:
+
+0. All colors disabled
+1. Basic color support (16 colors)
+2. 256 color support
+3. Truecolor support (16 million colors)
+
+### chalk.supportsColor
+
+Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience.
+
+Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add the environment variable `FORCE_COLOR=1` to forcefully enable color or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks.
+
+Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively.
+
+
+## Styles
+
+### Modifiers
+
+- `reset`
+- `bold`
+- `dim`
+- `italic` *(Not widely supported)*
+- `underline`
+- `inverse`
+- `hidden`
+- `strikethrough` *(Not widely supported)*
+- `visible` (Text is emitted only if enabled)
+
+### Colors
+
+- `black`
+- `red`
+- `green`
+- `yellow`
+- `blue` *(On Windows the bright version is used since normal blue is illegible)*
+- `magenta`
+- `cyan`
+- `white`
+- `gray` ("bright black")
+- `redBright`
+- `greenBright`
+- `yellowBright`
+- `blueBright`
+- `magentaBright`
+- `cyanBright`
+- `whiteBright`
+
+### Background colors
+
+- `bgBlack`
+- `bgRed`
+- `bgGreen`
+- `bgYellow`
+- `bgBlue`
+- `bgMagenta`
+- `bgCyan`
+- `bgWhite`
+- `bgBlackBright`
+- `bgRedBright`
+- `bgGreenBright`
+- `bgYellowBright`
+- `bgBlueBright`
+- `bgMagentaBright`
+- `bgCyanBright`
+- `bgWhiteBright`
+
+
+## Tagged template literal
+
+Chalk can be used as a [tagged template literal](http://exploringjs.com/es6/ch_template-literals.html#_tagged-template-literals).
+
+```js
+const chalk = require('chalk');
+
+const miles = 18;
+const calculateFeet = miles => miles * 5280;
+
+console.log(chalk`
+  There are {bold 5280 feet} in a mile.
+  In {bold ${miles} miles}, there are {green.bold ${calculateFeet(miles)} feet}.
+`);
+```
+
+Blocks are delimited by an opening curly brace (`{`), a style, some content, and a closing curly brace (`}`).
+
+Template styles are chained exactly like normal Chalk styles. The following two statements are equivalent:
+
+```js
+console.log(chalk.bold.rgb(10, 100, 200)('Hello!'));
+console.log(chalk`{bold.rgb(10,100,200) Hello!}`);
+```
+
+Note that function styles (`rgb()`, `hsl()`, `keyword()`, etc.) may not contain spaces between parameters.
+
+All interpolated values (`` chalk`${foo}` ``) are converted to strings via the `.toString()` method. All curly braces (`{` and `}`) in interpolated value strings are escaped.
+
+
+## 256 and Truecolor color support
+
+Chalk supports 256 colors and [Truecolor](https://gist.github.com/XVilka/8346728) (16 million colors) on supported terminal apps.
+
+Colors are downsampled from 16 million RGB values to an ANSI color format that is supported by the terminal emulator (or by specifying `{level: n}` as a Chalk option). For example, Chalk configured to run at level 1 (basic color support) will downsample an RGB value of #FF0000 (red) to 31 (ANSI escape for red).
+
+Examples:
+
+- `chalk.hex('#DEADED').underline('Hello, world!')`
+- `chalk.keyword('orange')('Some orange text')`
+- `chalk.rgb(15, 100, 204).inverse('Hello!')`
+
+Background versions of these models are prefixed with `bg` and the first level of the module capitalized (e.g. `keyword` for foreground colors and `bgKeyword` for background colors).
+
+- `chalk.bgHex('#DEADED').underline('Hello, world!')`
+- `chalk.bgKeyword('orange')('Some orange text')`
+- `chalk.bgRgb(15, 100, 204).inverse('Hello!')`
+
+The following color models can be used:
+
+- [`rgb`](https://en.wikipedia.org/wiki/RGB_color_model) - Example: `chalk.rgb(255, 136, 0).bold('Orange!')`
+- [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')`
+- [`keyword`](https://www.w3.org/wiki/CSS/Properties/color/keywords) (CSS keywords) - Example: `chalk.keyword('orange').bold('Orange!')`
+- [`hsl`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 100, 50).bold('Orange!')`
+- [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsv(32, 100, 100).bold('Orange!')`
+- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model)  - Example: `chalk.hwb(32, 0, 50).bold('Orange!')`
+- `ansi16`
+- `ansi256`
+
+
+## Windows
+
+If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) instead of `cmd.exe`.
+
+
+## Origin story
+
+[colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68) and the package is unmaintained. Although there are other packages, they either do too much or not enough. Chalk is a clean and focused alternative.
+
+
+## Related
+
+- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module
+- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
+- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color
+- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes
+- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Strip ANSI escape codes from a stream
+- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
+- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
+- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes
+- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes
+- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models
+- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal
+- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings
+- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings
+- [terminal-link](https://github.com/sindresorhus/terminal-link) - Create clickable links in the terminal
+
+
+## Maintainers
+
+- [Sindre Sorhus](https://github.com/sindresorhus)
+- [Josh Junon](https://github.com/qix-)
+
+
+## License
+
+MIT
diff --git a/d2d_app/node_modules/chalk/templates.js b/d2d_app/node_modules/chalk/templates.js
new file mode 100644 (file)
index 0000000..dbdf9b2
--- /dev/null
@@ -0,0 +1,128 @@
+'use strict';
+const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
+const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
+const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
+const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi;
+
+const ESCAPES = new Map([
+       ['n', '\n'],
+       ['r', '\r'],
+       ['t', '\t'],
+       ['b', '\b'],
+       ['f', '\f'],
+       ['v', '\v'],
+       ['0', '\0'],
+       ['\\', '\\'],
+       ['e', '\u001B'],
+       ['a', '\u0007']
+]);
+
+function unescape(c) {
+       if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) {
+               return String.fromCharCode(parseInt(c.slice(1), 16));
+       }
+
+       return ESCAPES.get(c) || c;
+}
+
+function parseArguments(name, args) {
+       const results = [];
+       const chunks = args.trim().split(/\s*,\s*/g);
+       let matches;
+
+       for (const chunk of chunks) {
+               if (!isNaN(chunk)) {
+                       results.push(Number(chunk));
+               } else if ((matches = chunk.match(STRING_REGEX))) {
+                       results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr));
+               } else {
+                       throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
+               }
+       }
+
+       return results;
+}
+
+function parseStyle(style) {
+       STYLE_REGEX.lastIndex = 0;
+
+       const results = [];
+       let matches;
+
+       while ((matches = STYLE_REGEX.exec(style)) !== null) {
+               const name = matches[1];
+
+               if (matches[2]) {
+                       const args = parseArguments(name, matches[2]);
+                       results.push([name].concat(args));
+               } else {
+                       results.push([name]);
+               }
+       }
+
+       return results;
+}
+
+function buildStyle(chalk, styles) {
+       const enabled = {};
+
+       for (const layer of styles) {
+               for (const style of layer.styles) {
+                       enabled[style[0]] = layer.inverse ? null : style.slice(1);
+               }
+       }
+
+       let current = chalk;
+       for (const styleName of Object.keys(enabled)) {
+               if (Array.isArray(enabled[styleName])) {
+                       if (!(styleName in current)) {
+                               throw new Error(`Unknown Chalk style: ${styleName}`);
+                       }
+
+                       if (enabled[styleName].length > 0) {
+                               current = current[styleName].apply(current, enabled[styleName]);
+                       } else {
+                               current = current[styleName];
+                       }
+               }
+       }
+
+       return current;
+}
+
+module.exports = (chalk, tmp) => {
+       const styles = [];
+       const chunks = [];
+       let chunk = [];
+
+       // eslint-disable-next-line max-params
+       tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => {
+               if (escapeChar) {
+                       chunk.push(unescape(escapeChar));
+               } else if (style) {
+                       const str = chunk.join('');
+                       chunk = [];
+                       chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str));
+                       styles.push({inverse, styles: parseStyle(style)});
+               } else if (close) {
+                       if (styles.length === 0) {
+                               throw new Error('Found extraneous } in Chalk template literal');
+                       }
+
+                       chunks.push(buildStyle(chalk, styles)(chunk.join('')));
+                       chunk = [];
+                       styles.pop();
+               } else {
+                       chunk.push(chr);
+               }
+       });
+
+       chunks.push(chunk.join(''));
+
+       if (styles.length > 0) {
+               const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`;
+               throw new Error(errMsg);
+       }
+
+       return chunks.join('');
+};
diff --git a/d2d_app/node_modules/chalk/types/index.d.ts b/d2d_app/node_modules/chalk/types/index.d.ts
new file mode 100644 (file)
index 0000000..b4e4dc5
--- /dev/null
@@ -0,0 +1,97 @@
+// Type definitions for Chalk
+// Definitions by: Thomas Sauer <https://github.com/t-sauer>
+
+export const enum Level {
+       None = 0,
+       Basic = 1,
+       Ansi256 = 2,
+       TrueColor = 3
+}
+
+export interface ChalkOptions {
+       enabled?: boolean;
+       level?: Level;
+}
+
+export interface ChalkConstructor {
+       new (options?: ChalkOptions): Chalk;
+       (options?: ChalkOptions): Chalk;
+}
+
+export interface ColorSupport {
+       level: Level;
+       hasBasic: boolean;
+       has256: boolean;
+       has16m: boolean;
+}
+
+export interface Chalk {
+       (...text: string[]): string;
+       (text: TemplateStringsArray, ...placeholders: string[]): string;
+       constructor: ChalkConstructor;
+       enabled: boolean;
+       level: Level;
+       rgb(r: number, g: number, b: number): this;
+       hsl(h: number, s: number, l: number): this;
+       hsv(h: number, s: number, v: number): this;
+       hwb(h: number, w: number, b: number): this;
+       bgHex(color: string): this;
+       bgKeyword(color: string): this;
+       bgRgb(r: number, g: number, b: number): this;
+       bgHsl(h: number, s: number, l: number): this;
+       bgHsv(h: number, s: number, v: number): this;
+       bgHwb(h: number, w: number, b: number): this;
+       hex(color: string): this;
+       keyword(color: string): this;
+
+       readonly reset: this;
+       readonly bold: this;
+       readonly dim: this;
+       readonly italic: this;
+       readonly underline: this;
+       readonly inverse: this;
+       readonly hidden: this;
+       readonly strikethrough: this;
+
+       readonly visible: this;
+
+       readonly black: this;
+       readonly red: this;
+       readonly green: this;
+       readonly yellow: this;
+       readonly blue: this;
+       readonly magenta: this;
+       readonly cyan: this;
+       readonly white: this;
+       readonly gray: this;
+       readonly grey: this;
+       readonly blackBright: this;
+       readonly redBright: this;
+       readonly greenBright: this;
+       readonly yellowBright: this;
+       readonly blueBright: this;
+       readonly magentaBright: this;
+       readonly cyanBright: this;
+       readonly whiteBright: this;
+
+       readonly bgBlack: this;
+       readonly bgRed: this;
+       readonly bgGreen: this;
+       readonly bgYellow: this;
+       readonly bgBlue: this;
+       readonly bgMagenta: this;
+       readonly bgCyan: this;
+       readonly bgWhite: this;
+       readonly bgBlackBright: this;
+       readonly bgRedBright: this;
+       readonly bgGreenBright: this;
+       readonly bgYellowBright: this;
+       readonly bgBlueBright: this;
+       readonly bgMagentaBright: this;
+       readonly bgCyanBright: this;
+       readonly bgWhiteBright: this;
+}
+
+declare const chalk: Chalk & { supportsColor: ColorSupport };
+
+export default chalk
diff --git a/d2d_app/node_modules/color-convert/CHANGELOG.md b/d2d_app/node_modules/color-convert/CHANGELOG.md
new file mode 100644 (file)
index 0000000..0a7bce4
--- /dev/null
@@ -0,0 +1,54 @@
+# 1.0.0 - 2016-01-07
+
+- Removed: unused speed test
+- Added: Automatic routing between previously unsupported conversions
+([#27](https://github.com/Qix-/color-convert/pull/27))
+- Removed: `xxx2xxx()` and `xxx2xxxRaw()` functions
+([#27](https://github.com/Qix-/color-convert/pull/27))
+- Removed: `convert()` class
+([#27](https://github.com/Qix-/color-convert/pull/27))
+- Changed: all functions to lookup dictionary
+([#27](https://github.com/Qix-/color-convert/pull/27))
+- Changed: `ansi` to `ansi256`
+([#27](https://github.com/Qix-/color-convert/pull/27))
+- Fixed: argument grouping for functions requiring only one argument
+([#27](https://github.com/Qix-/color-convert/pull/27))
+
+# 0.6.0 - 2015-07-23
+
+- Added: methods to handle
+[ANSI](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) 16/256 colors:
+  - rgb2ansi16
+  - rgb2ansi
+  - hsl2ansi16
+  - hsl2ansi
+  - hsv2ansi16
+  - hsv2ansi
+  - hwb2ansi16
+  - hwb2ansi
+  - cmyk2ansi16
+  - cmyk2ansi
+  - keyword2ansi16
+  - keyword2ansi
+  - ansi162rgb
+  - ansi162hsl
+  - ansi162hsv
+  - ansi162hwb
+  - ansi162cmyk
+  - ansi162keyword
+  - ansi2rgb
+  - ansi2hsl
+  - ansi2hsv
+  - ansi2hwb
+  - ansi2cmyk
+  - ansi2keyword
+([#18](https://github.com/harthur/color-convert/pull/18))
+
+# 0.5.3 - 2015-06-02
+
+- Fixed: hsl2hsv does not return `NaN` anymore when using `[0,0,0]`
+([#15](https://github.com/harthur/color-convert/issues/15))
+
+---
+
+Check out commit logs for older releases
diff --git a/d2d_app/node_modules/color-convert/LICENSE b/d2d_app/node_modules/color-convert/LICENSE
new file mode 100644 (file)
index 0000000..5b4c386
--- /dev/null
@@ -0,0 +1,21 @@
+Copyright (c) 2011-2016 Heather Arthur <fayearthur@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
diff --git a/d2d_app/node_modules/color-convert/README.md b/d2d_app/node_modules/color-convert/README.md
new file mode 100644 (file)
index 0000000..d4b08fc
--- /dev/null
@@ -0,0 +1,68 @@
+# color-convert
+
+[![Build Status](https://travis-ci.org/Qix-/color-convert.svg?branch=master)](https://travis-ci.org/Qix-/color-convert)
+
+Color-convert is a color conversion library for JavaScript and node.
+It converts all ways between `rgb`, `hsl`, `hsv`, `hwb`, `cmyk`, `ansi`, `ansi16`, `hex` strings, and CSS `keyword`s (will round to closest):
+
+```js
+var convert = require('color-convert');
+
+convert.rgb.hsl(140, 200, 100);             // [96, 48, 59]
+convert.keyword.rgb('blue');                // [0, 0, 255]
+
+var rgbChannels = convert.rgb.channels;     // 3
+var cmykChannels = convert.cmyk.channels;   // 4
+var ansiChannels = convert.ansi16.channels; // 1
+```
+
+# Install
+
+```console
+$ npm install color-convert
+```
+
+# API
+
+Simply get the property of the _from_ and _to_ conversion that you're looking for.
+
+All functions have a rounded and unrounded variant. By default, return values are rounded. To get the unrounded (raw) results, simply tack on `.raw` to the function.
+
+All 'from' functions have a hidden property called `.channels` that indicates the number of channels the function expects (not including alpha).
+
+```js
+var convert = require('color-convert');
+
+// Hex to LAB
+convert.hex.lab('DEADBF');         // [ 76, 21, -2 ]
+convert.hex.lab.raw('DEADBF');     // [ 75.56213190997677, 20.653827952644754, -2.290532499330533 ]
+
+// RGB to CMYK
+convert.rgb.cmyk(167, 255, 4);     // [ 35, 0, 98, 0 ]
+convert.rgb.cmyk.raw(167, 255, 4); // [ 34.509803921568626, 0, 98.43137254901961, 0 ]
+```
+
+### Arrays
+All functions that accept multiple arguments also support passing an array.
+
+Note that this does **not** apply to functions that convert from a color that only requires one value (e.g. `keyword`, `ansi256`, `hex`, etc.)
+
+```js
+var convert = require('color-convert');
+
+convert.rgb.hex(123, 45, 67);      // '7B2D43'
+convert.rgb.hex([123, 45, 67]);    // '7B2D43'
+```
+
+## Routing
+
+Conversions that don't have an _explicitly_ defined conversion (in [conversions.js](conversions.js)), but can be converted by means of sub-conversions (e.g. XYZ -> **RGB** -> CMYK), are automatically routed together. This allows just about any color model supported by `color-convert` to be converted to any other model, so long as a sub-conversion path exists. This is also true for conversions requiring more than one step in between (e.g. LCH -> **LAB** -> **XYZ** -> **RGB** -> Hex).
+
+Keep in mind that extensive conversions _may_ result in a loss of precision, and exist only to be complete. For a list of "direct" (single-step) conversions, see [conversions.js](conversions.js).
+
+# Contribute
+
+If there is a new model you would like to support, or want to add a direct conversion between two existing models, please send us a pull request.
+
+# License
+Copyright &copy; 2011-2016, Heather Arthur and Josh Junon. Licensed under the [MIT License](LICENSE).
diff --git a/d2d_app/node_modules/color-convert/conversions.js b/d2d_app/node_modules/color-convert/conversions.js
new file mode 100644 (file)
index 0000000..3217200
--- /dev/null
@@ -0,0 +1,868 @@
+/* MIT license */
+var cssKeywords = require('color-name');
+
+// NOTE: conversions should only return primitive values (i.e. arrays, or
+//       values that give correct `typeof` results).
+//       do not use box values types (i.e. Number(), String(), etc.)
+
+var reverseKeywords = {};
+for (var key in cssKeywords) {
+       if (cssKeywords.hasOwnProperty(key)) {
+               reverseKeywords[cssKeywords[key]] = key;
+       }
+}
+
+var convert = module.exports = {
+       rgb: {channels: 3, labels: 'rgb'},
+       hsl: {channels: 3, labels: 'hsl'},
+       hsv: {channels: 3, labels: 'hsv'},
+       hwb: {channels: 3, labels: 'hwb'},
+       cmyk: {channels: 4, labels: 'cmyk'},
+       xyz: {channels: 3, labels: 'xyz'},
+       lab: {channels: 3, labels: 'lab'},
+       lch: {channels: 3, labels: 'lch'},
+       hex: {channels: 1, labels: ['hex']},
+       keyword: {channels: 1, labels: ['keyword']},
+       ansi16: {channels: 1, labels: ['ansi16']},
+       ansi256: {channels: 1, labels: ['ansi256']},
+       hcg: {channels: 3, labels: ['h', 'c', 'g']},
+       apple: {channels: 3, labels: ['r16', 'g16', 'b16']},
+       gray: {channels: 1, labels: ['gray']}
+};
+
+// hide .channels and .labels properties
+for (var model in convert) {
+       if (convert.hasOwnProperty(model)) {
+               if (!('channels' in convert[model])) {
+                       throw new Error('missing channels property: ' + model);
+               }
+
+               if (!('labels' in convert[model])) {
+                       throw new Error('missing channel labels property: ' + model);
+               }
+
+               if (convert[model].labels.length !== convert[model].channels) {
+                       throw new Error('channel and label counts mismatch: ' + model);
+               }
+
+               var channels = convert[model].channels;
+               var labels = convert[model].labels;
+               delete convert[model].channels;
+               delete convert[model].labels;
+               Object.defineProperty(convert[model], 'channels', {value: channels});
+               Object.defineProperty(convert[model], 'labels', {value: labels});
+       }
+}
+
+convert.rgb.hsl = function (rgb) {
+       var r = rgb[0] / 255;
+       var g = rgb[1] / 255;
+       var b = rgb[2] / 255;
+       var min = Math.min(r, g, b);
+       var max = Math.max(r, g, b);
+       var delta = max - min;
+       var h;
+       var s;
+       var l;
+
+       if (max === min) {
+               h = 0;
+       } else if (r === max) {
+               h = (g - b) / delta;
+       } else if (g === max) {
+               h = 2 + (b - r) / delta;
+       } else if (b === max) {
+               h = 4 + (r - g) / delta;
+       }
+
+       h = Math.min(h * 60, 360);
+
+       if (h < 0) {
+               h += 360;
+       }
+
+       l = (min + max) / 2;
+
+       if (max === min) {
+               s = 0;
+       } else if (l <= 0.5) {
+               s = delta / (max + min);
+       } else {
+               s = delta / (2 - max - min);
+       }
+
+       return [h, s * 100, l * 100];
+};
+
+convert.rgb.hsv = function (rgb) {
+       var rdif;
+       var gdif;
+       var bdif;
+       var h;
+       var s;
+
+       var r = rgb[0] / 255;
+       var g = rgb[1] / 255;
+       var b = rgb[2] / 255;
+       var v = Math.max(r, g, b);
+       var diff = v - Math.min(r, g, b);
+       var diffc = function (c) {
+               return (v - c) / 6 / diff + 1 / 2;
+       };
+
+       if (diff === 0) {
+               h = s = 0;
+       } else {
+               s = diff / v;
+               rdif = diffc(r);
+               gdif = diffc(g);
+               bdif = diffc(b);
+
+               if (r === v) {
+                       h = bdif - gdif;
+               } else if (g === v) {
+                       h = (1 / 3) + rdif - bdif;
+               } else if (b === v) {
+                       h = (2 / 3) + gdif - rdif;
+               }
+               if (h < 0) {
+                       h += 1;
+               } else if (h > 1) {
+                       h -= 1;
+               }
+       }
+
+       return [
+               h * 360,
+               s * 100,
+               v * 100
+       ];
+};
+
+convert.rgb.hwb = function (rgb) {
+       var r = rgb[0];
+       var g = rgb[1];
+       var b = rgb[2];
+       var h = convert.rgb.hsl(rgb)[0];
+       var w = 1 / 255 * Math.min(r, Math.min(g, b));
+
+       b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
+
+       return [h, w * 100, b * 100];
+};
+
+convert.rgb.cmyk = function (rgb) {
+       var r = rgb[0] / 255;
+       var g = rgb[1] / 255;
+       var b = rgb[2] / 255;
+       var c;
+       var m;
+       var y;
+       var k;
+
+       k = Math.min(1 - r, 1 - g, 1 - b);
+       c = (1 - r - k) / (1 - k) || 0;
+       m = (1 - g - k) / (1 - k) || 0;
+       y = (1 - b - k) / (1 - k) || 0;
+
+       return [c * 100, m * 100, y * 100, k * 100];
+};
+
+/**
+ * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance
+ * */
+function comparativeDistance(x, y) {
+       return (
+               Math.pow(x[0] - y[0], 2) +
+               Math.pow(x[1] - y[1], 2) +
+               Math.pow(x[2] - y[2], 2)
+       );
+}
+
+convert.rgb.keyword = function (rgb) {
+       var reversed = reverseKeywords[rgb];
+       if (reversed) {
+               return reversed;
+       }
+
+       var currentClosestDistance = Infinity;
+       var currentClosestKeyword;
+
+       for (var keyword in cssKeywords) {
+               if (cssKeywords.hasOwnProperty(keyword)) {
+                       var value = cssKeywords[keyword];
+
+                       // Compute comparative distance
+                       var distance = comparativeDistance(rgb, value);
+
+                       // Check if its less, if so set as closest
+                       if (distance < currentClosestDistance) {
+                               currentClosestDistance = distance;
+                               currentClosestKeyword = keyword;
+                       }
+               }
+       }
+
+       return currentClosestKeyword;
+};
+
+convert.keyword.rgb = function (keyword) {
+       return cssKeywords[keyword];
+};
+
+convert.rgb.xyz = function (rgb) {
+       var r = rgb[0] / 255;
+       var g = rgb[1] / 255;
+       var b = rgb[2] / 255;
+
+       // assume sRGB
+       r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);
+       g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);
+       b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);
+
+       var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);
+       var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);
+       var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);
+
+       return [x * 100, y * 100, z * 100];
+};
+
+convert.rgb.lab = function (rgb) {
+       var xyz = convert.rgb.xyz(rgb);
+       var x = xyz[0];
+       var y = xyz[1];
+       var z = xyz[2];
+       var l;
+       var a;
+       var b;
+
+       x /= 95.047;
+       y /= 100;
+       z /= 108.883;
+
+       x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
+       y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
+       z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
+
+       l = (116 * y) - 16;
+       a = 500 * (x - y);
+       b = 200 * (y - z);
+
+       return [l, a, b];
+};
+
+convert.hsl.rgb = function (hsl) {
+       var h = hsl[0] / 360;
+       var s = hsl[1] / 100;
+       var l = hsl[2] / 100;
+       var t1;
+       var t2;
+       var t3;
+       var rgb;
+       var val;
+
+       if (s === 0) {
+               val = l * 255;
+               return [val, val, val];
+       }
+
+       if (l < 0.5) {
+               t2 = l * (1 + s);
+       } else {
+               t2 = l + s - l * s;
+       }
+
+       t1 = 2 * l - t2;
+
+       rgb = [0, 0, 0];
+       for (var i = 0; i < 3; i++) {
+               t3 = h + 1 / 3 * -(i - 1);
+               if (t3 < 0) {
+                       t3++;
+               }
+               if (t3 > 1) {
+                       t3--;
+               }
+
+               if (6 * t3 < 1) {
+                       val = t1 + (t2 - t1) * 6 * t3;
+               } else if (2 * t3 < 1) {
+                       val = t2;
+               } else if (3 * t3 < 2) {
+                       val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
+               } else {
+                       val = t1;
+               }
+
+               rgb[i] = val * 255;
+       }
+
+       return rgb;
+};
+
+convert.hsl.hsv = function (hsl) {
+       var h = hsl[0];
+       var s = hsl[1] / 100;
+       var l = hsl[2] / 100;
+       var smin = s;
+       var lmin = Math.max(l, 0.01);
+       var sv;
+       var v;
+
+       l *= 2;
+       s *= (l <= 1) ? l : 2 - l;
+       smin *= lmin <= 1 ? lmin : 2 - lmin;
+       v = (l + s) / 2;
+       sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
+
+       return [h, sv * 100, v * 100];
+};
+
+convert.hsv.rgb = function (hsv) {
+       var h = hsv[0] / 60;
+       var s = hsv[1] / 100;
+       var v = hsv[2] / 100;
+       var hi = Math.floor(h) % 6;
+
+       var f = h - Math.floor(h);
+       var p = 255 * v * (1 - s);
+       var q = 255 * v * (1 - (s * f));
+       var t = 255 * v * (1 - (s * (1 - f)));
+       v *= 255;
+
+       switch (hi) {
+               case 0:
+                       return [v, t, p];
+               case 1:
+                       return [q, v, p];
+               case 2:
+                       return [p, v, t];
+               case 3:
+                       return [p, q, v];
+               case 4:
+                       return [t, p, v];
+               case 5:
+                       return [v, p, q];
+       }
+};
+
+convert.hsv.hsl = function (hsv) {
+       var h = hsv[0];
+       var s = hsv[1] / 100;
+       var v = hsv[2] / 100;
+       var vmin = Math.max(v, 0.01);
+       var lmin;
+       var sl;
+       var l;
+
+       l = (2 - s) * v;
+       lmin = (2 - s) * vmin;
+       sl = s * vmin;
+       sl /= (lmin <= 1) ? lmin : 2 - lmin;
+       sl = sl || 0;
+       l /= 2;
+
+       return [h, sl * 100, l * 100];
+};
+
+// http://dev.w3.org/csswg/css-color/#hwb-to-rgb
+convert.hwb.rgb = function (hwb) {
+       var h = hwb[0] / 360;
+       var wh = hwb[1] / 100;
+       var bl = hwb[2] / 100;
+       var ratio = wh + bl;
+       var i;
+       var v;
+       var f;
+       var n;
+
+       // wh + bl cant be > 1
+       if (ratio > 1) {
+               wh /= ratio;
+               bl /= ratio;
+       }
+
+       i = Math.floor(6 * h);
+       v = 1 - bl;
+       f = 6 * h - i;
+
+       if ((i & 0x01) !== 0) {
+               f = 1 - f;
+       }
+
+       n = wh + f * (v - wh); // linear interpolation
+
+       var r;
+       var g;
+       var b;
+       switch (i) {
+               default:
+               case 6:
+               case 0: r = v; g = n; b = wh; break;
+               case 1: r = n; g = v; b = wh; break;
+               case 2: r = wh; g = v; b = n; break;
+               case 3: r = wh; g = n; b = v; break;
+               case 4: r = n; g = wh; b = v; break;
+               case 5: r = v; g = wh; b = n; break;
+       }
+
+       return [r * 255, g * 255, b * 255];
+};
+
+convert.cmyk.rgb = function (cmyk) {
+       var c = cmyk[0] / 100;
+       var m = cmyk[1] / 100;
+       var y = cmyk[2] / 100;
+       var k = cmyk[3] / 100;
+       var r;
+       var g;
+       var b;
+
+       r = 1 - Math.min(1, c * (1 - k) + k);
+       g = 1 - Math.min(1, m * (1 - k) + k);
+       b = 1 - Math.min(1, y * (1 - k) + k);
+
+       return [r * 255, g * 255, b * 255];
+};
+
+convert.xyz.rgb = function (xyz) {
+       var x = xyz[0] / 100;
+       var y = xyz[1] / 100;
+       var z = xyz[2] / 100;
+       var r;
+       var g;
+       var b;
+
+       r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);
+       g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);
+       b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);
+
+       // assume sRGB
+       r = r > 0.0031308
+               ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)
+               : r * 12.92;
+
+       g = g > 0.0031308
+               ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)
+               : g * 12.92;
+
+       b = b > 0.0031308
+               ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)
+               : b * 12.92;
+
+       r = Math.min(Math.max(0, r), 1);
+       g = Math.min(Math.max(0, g), 1);
+       b = Math.min(Math.max(0, b), 1);
+
+       return [r * 255, g * 255, b * 255];
+};
+
+convert.xyz.lab = function (xyz) {
+       var x = xyz[0];
+       var y = xyz[1];
+       var z = xyz[2];
+       var l;
+       var a;
+       var b;
+
+       x /= 95.047;
+       y /= 100;
+       z /= 108.883;
+
+       x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);
+       y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);
+       z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);
+
+       l = (116 * y) - 16;
+       a = 500 * (x - y);
+       b = 200 * (y - z);
+
+       return [l, a, b];
+};
+
+convert.lab.xyz = function (lab) {
+       var l = lab[0];
+       var a = lab[1];
+       var b = lab[2];
+       var x;
+       var y;
+       var z;
+
+       y = (l + 16) / 116;
+       x = a / 500 + y;
+       z = y - b / 200;
+
+       var y2 = Math.pow(y, 3);
+       var x2 = Math.pow(x, 3);
+       var z2 = Math.pow(z, 3);
+       y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;
+       x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;
+       z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;
+
+       x *= 95.047;
+       y *= 100;
+       z *= 108.883;
+
+       return [x, y, z];
+};
+
+convert.lab.lch = function (lab) {
+       var l = lab[0];
+       var a = lab[1];
+       var b = lab[2];
+       var hr;
+       var h;
+       var c;
+
+       hr = Math.atan2(b, a);
+       h = hr * 360 / 2 / Math.PI;
+
+       if (h < 0) {
+               h += 360;
+       }
+
+       c = Math.sqrt(a * a + b * b);
+
+       return [l, c, h];
+};
+
+convert.lch.lab = function (lch) {
+       var l = lch[0];
+       var c = lch[1];
+       var h = lch[2];
+       var a;
+       var b;
+       var hr;
+
+       hr = h / 360 * 2 * Math.PI;
+       a = c * Math.cos(hr);
+       b = c * Math.sin(hr);
+
+       return [l, a, b];
+};
+
+convert.rgb.ansi16 = function (args) {
+       var r = args[0];
+       var g = args[1];
+       var b = args[2];
+       var value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization
+
+       value = Math.round(value / 50);
+
+       if (value === 0) {
+               return 30;
+       }
+
+       var ansi = 30
+               + ((Math.round(b / 255) << 2)
+               | (Math.round(g / 255) << 1)
+               | Math.round(r / 255));
+
+       if (value === 2) {
+               ansi += 60;
+       }
+
+       return ansi;
+};
+
+convert.hsv.ansi16 = function (args) {
+       // optimization here; we already know the value and don't need to get
+       // it converted for us.
+       return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
+};
+
+convert.rgb.ansi256 = function (args) {
+       var r = args[0];
+       var g = args[1];
+       var b = args[2];
+
+       // we use the extended greyscale palette here, with the exception of
+       // black and white. normal palette only has 4 greyscale shades.
+       if (r === g && g === b) {
+               if (r < 8) {
+                       return 16;
+               }
+
+               if (r > 248) {
+                       return 231;
+               }
+
+               return Math.round(((r - 8) / 247) * 24) + 232;
+       }
+
+       var ansi = 16
+               + (36 * Math.round(r / 255 * 5))
+               + (6 * Math.round(g / 255 * 5))
+               + Math.round(b / 255 * 5);
+
+       return ansi;
+};
+
+convert.ansi16.rgb = function (args) {
+       var color = args % 10;
+
+       // handle greyscale
+       if (color === 0 || color === 7) {
+               if (args > 50) {
+                       color += 3.5;
+               }
+
+               color = color / 10.5 * 255;
+
+               return [color, color, color];
+       }
+
+       var mult = (~~(args > 50) + 1) * 0.5;
+       var r = ((color & 1) * mult) * 255;
+       var g = (((color >> 1) & 1) * mult) * 255;
+       var b = (((color >> 2) & 1) * mult) * 255;
+
+       return [r, g, b];
+};
+
+convert.ansi256.rgb = function (args) {
+       // handle greyscale
+       if (args >= 232) {
+               var c = (args - 232) * 10 + 8;
+               return [c, c, c];
+       }
+
+       args -= 16;
+
+       var rem;
+       var r = Math.floor(args / 36) / 5 * 255;
+       var g = Math.floor((rem = args % 36) / 6) / 5 * 255;
+       var b = (rem % 6) / 5 * 255;
+
+       return [r, g, b];
+};
+
+convert.rgb.hex = function (args) {
+       var integer = ((Math.round(args[0]) & 0xFF) << 16)
+               + ((Math.round(args[1]) & 0xFF) << 8)
+               + (Math.round(args[2]) & 0xFF);
+
+       var string = integer.toString(16).toUpperCase();
+       return '000000'.substring(string.length) + string;
+};
+
+convert.hex.rgb = function (args) {
+       var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
+       if (!match) {
+               return [0, 0, 0];
+       }
+
+       var colorString = match[0];
+
+       if (match[0].length === 3) {
+               colorString = colorString.split('').map(function (char) {
+                       return char + char;
+               }).join('');
+       }
+
+       var integer = parseInt(colorString, 16);
+       var r = (integer >> 16) & 0xFF;
+       var g = (integer >> 8) & 0xFF;
+       var b = integer & 0xFF;
+
+       return [r, g, b];
+};
+
+convert.rgb.hcg = function (rgb) {
+       var r = rgb[0] / 255;
+       var g = rgb[1] / 255;
+       var b = rgb[2] / 255;
+       var max = Math.max(Math.max(r, g), b);
+       var min = Math.min(Math.min(r, g), b);
+       var chroma = (max - min);
+       var grayscale;
+       var hue;
+
+       if (chroma < 1) {
+               grayscale = min / (1 - chroma);
+       } else {
+               grayscale = 0;
+       }
+
+       if (chroma <= 0) {
+               hue = 0;
+       } else
+       if (max === r) {
+               hue = ((g - b) / chroma) % 6;
+       } else
+       if (max === g) {
+               hue = 2 + (b - r) / chroma;
+       } else {
+               hue = 4 + (r - g) / chroma + 4;
+       }
+
+       hue /= 6;
+       hue %= 1;
+
+       return [hue * 360, chroma * 100, grayscale * 100];
+};
+
+convert.hsl.hcg = function (hsl) {
+       var s = hsl[1] / 100;
+       var l = hsl[2] / 100;
+       var c = 1;
+       var f = 0;
+
+       if (l < 0.5) {
+               c = 2.0 * s * l;
+       } else {
+               c = 2.0 * s * (1.0 - l);
+       }
+
+       if (c < 1.0) {
+               f = (l - 0.5 * c) / (1.0 - c);
+       }
+
+       return [hsl[0], c * 100, f * 100];
+};
+
+convert.hsv.hcg = function (hsv) {
+       var s = hsv[1] / 100;
+       var v = hsv[2] / 100;
+
+       var c = s * v;
+       var f = 0;
+
+       if (c < 1.0) {
+               f = (v - c) / (1 - c);
+       }
+
+       return [hsv[0], c * 100, f * 100];
+};
+
+convert.hcg.rgb = function (hcg) {
+       var h = hcg[0] / 360;
+       var c = hcg[1] / 100;
+       var g = hcg[2] / 100;
+
+       if (c === 0.0) {
+               return [g * 255, g * 255, g * 255];
+       }
+
+       var pure = [0, 0, 0];
+       var hi = (h % 1) * 6;
+       var v = hi % 1;
+       var w = 1 - v;
+       var mg = 0;
+
+       switch (Math.floor(hi)) {
+               case 0:
+                       pure[0] = 1; pure[1] = v; pure[2] = 0; break;
+               case 1:
+                       pure[0] = w; pure[1] = 1; pure[2] = 0; break;
+               case 2:
+                       pure[0] = 0; pure[1] = 1; pure[2] = v; break;
+               case 3:
+                       pure[0] = 0; pure[1] = w; pure[2] = 1; break;
+               case 4:
+                       pure[0] = v; pure[1] = 0; pure[2] = 1; break;
+               default:
+                       pure[0] = 1; pure[1] = 0; pure[2] = w;
+       }
+
+       mg = (1.0 - c) * g;
+
+       return [
+               (c * pure[0] + mg) * 255,
+               (c * pure[1] + mg) * 255,
+               (c * pure[2] + mg) * 255
+       ];
+};
+
+convert.hcg.hsv = function (hcg) {
+       var c = hcg[1] / 100;
+       var g = hcg[2] / 100;
+
+       var v = c + g * (1.0 - c);
+       var f = 0;
+
+       if (v > 0.0) {
+               f = c / v;
+       }
+
+       return [hcg[0], f * 100, v * 100];
+};
+
+convert.hcg.hsl = function (hcg) {
+       var c = hcg[1] / 100;
+       var g = hcg[2] / 100;
+
+       var l = g * (1.0 - c) + 0.5 * c;
+       var s = 0;
+
+       if (l > 0.0 && l < 0.5) {
+               s = c / (2 * l);
+       } else
+       if (l >= 0.5 && l < 1.0) {
+               s = c / (2 * (1 - l));
+       }
+
+       return [hcg[0], s * 100, l * 100];
+};
+
+convert.hcg.hwb = function (hcg) {
+       var c = hcg[1] / 100;
+       var g = hcg[2] / 100;
+       var v = c + g * (1.0 - c);
+       return [hcg[0], (v - c) * 100, (1 - v) * 100];
+};
+
+convert.hwb.hcg = function (hwb) {
+       var w = hwb[1] / 100;
+       var b = hwb[2] / 100;
+       var v = 1 - b;
+       var c = v - w;
+       var g = 0;
+
+       if (c < 1) {
+               g = (v - c) / (1 - c);
+       }
+
+       return [hwb[0], c * 100, g * 100];
+};
+
+convert.apple.rgb = function (apple) {
+       return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];
+};
+
+convert.rgb.apple = function (rgb) {
+       return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];
+};
+
+convert.gray.rgb = function (args) {
+       return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];
+};
+
+convert.gray.hsl = convert.gray.hsv = function (args) {
+       return [0, 0, args[0]];
+};
+
+convert.gray.hwb = function (gray) {
+       return [0, 100, gray[0]];
+};
+
+convert.gray.cmyk = function (gray) {
+       return [0, 0, 0, gray[0]];
+};
+
+convert.gray.lab = function (gray) {
+       return [gray[0], 0, 0];
+};
+
+convert.gray.hex = function (gray) {
+       var val = Math.round(gray[0] / 100 * 255) & 0xFF;
+       var integer = (val << 16) + (val << 8) + val;
+
+       var string = integer.toString(16).toUpperCase();
+       return '000000'.substring(string.length) + string;
+};
+
+convert.rgb.gray = function (rgb) {
+       var val = (rgb[0] + rgb[1] + rgb[2]) / 3;
+       return [val / 255 * 100];
+};
diff --git a/d2d_app/node_modules/color-convert/index.js b/d2d_app/node_modules/color-convert/index.js
new file mode 100644 (file)
index 0000000..e65b5d7
--- /dev/null
@@ -0,0 +1,78 @@
+var conversions = require('./conversions');
+var route = require('./route');
+
+var convert = {};
+
+var models = Object.keys(conversions);
+
+function wrapRaw(fn) {
+       var wrappedFn = function (args) {
+               if (args === undefined || args === null) {
+                       return args;
+               }
+
+               if (arguments.length > 1) {
+                       args = Array.prototype.slice.call(arguments);
+               }
+
+               return fn(args);
+       };
+
+       // preserve .conversion property if there is one
+       if ('conversion' in fn) {
+               wrappedFn.conversion = fn.conversion;
+       }
+
+       return wrappedFn;
+}
+
+function wrapRounded(fn) {
+       var wrappedFn = function (args) {
+               if (args === undefined || args === null) {
+                       return args;
+               }
+
+               if (arguments.length > 1) {
+                       args = Array.prototype.slice.call(arguments);
+               }
+
+               var result = fn(args);
+
+               // we're assuming the result is an array here.
+               // see notice in conversions.js; don't use box types
+               // in conversion functions.
+               if (typeof result === 'object') {
+                       for (var len = result.length, i = 0; i < len; i++) {
+                               result[i] = Math.round(result[i]);
+                       }
+               }
+
+               return result;
+       };
+
+       // preserve .conversion property if there is one
+       if ('conversion' in fn) {
+               wrappedFn.conversion = fn.conversion;
+       }
+
+       return wrappedFn;
+}
+
+models.forEach(function (fromModel) {
+       convert[fromModel] = {};
+
+       Object.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});
+       Object.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});
+
+       var routes = route(fromModel);
+       var routeModels = Object.keys(routes);
+
+       routeModels.forEach(function (toModel) {
+               var fn = routes[toModel];
+
+               convert[fromModel][toModel] = wrapRounded(fn);
+               convert[fromModel][toModel].raw = wrapRaw(fn);
+       });
+});
+
+module.exports = convert;
diff --git a/d2d_app/node_modules/color-convert/package.json b/d2d_app/node_modules/color-convert/package.json
new file mode 100644 (file)
index 0000000..9aedb91
--- /dev/null
@@ -0,0 +1,81 @@
+{
+  "_from": "color-convert@^1.9.0",
+  "_id": "color-convert@1.9.3",
+  "_inBundle": false,
+  "_integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+  "_location": "/color-convert",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "color-convert@^1.9.0",
+    "name": "color-convert",
+    "escapedName": "color-convert",
+    "rawSpec": "^1.9.0",
+    "saveSpec": null,
+    "fetchSpec": "^1.9.0"
+  },
+  "_requiredBy": [
+    "/ansi-styles"
+  ],
+  "_resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+  "_shasum": "bb71850690e1f136567de629d2d5471deda4c1e8",
+  "_spec": "color-convert@^1.9.0",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/ansi-styles",
+  "author": {
+    "name": "Heather Arthur",
+    "email": "fayearthur@gmail.com"
+  },
+  "bugs": {
+    "url": "https://github.com/Qix-/color-convert/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "color-name": "1.1.3"
+  },
+  "deprecated": false,
+  "description": "Plain color conversion functions",
+  "devDependencies": {
+    "chalk": "1.1.1",
+    "xo": "0.11.2"
+  },
+  "files": [
+    "index.js",
+    "conversions.js",
+    "css-keywords.js",
+    "route.js"
+  ],
+  "homepage": "https://github.com/Qix-/color-convert#readme",
+  "keywords": [
+    "color",
+    "colour",
+    "convert",
+    "converter",
+    "conversion",
+    "rgb",
+    "hsl",
+    "hsv",
+    "hwb",
+    "cmyk",
+    "ansi",
+    "ansi16"
+  ],
+  "license": "MIT",
+  "name": "color-convert",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/Qix-/color-convert.git"
+  },
+  "scripts": {
+    "pretest": "xo",
+    "test": "node test/basic.js"
+  },
+  "version": "1.9.3",
+  "xo": {
+    "rules": {
+      "default-case": 0,
+      "no-inline-comments": 0,
+      "operator-linebreak": 0
+    }
+  }
+}
diff --git a/d2d_app/node_modules/color-convert/route.js b/d2d_app/node_modules/color-convert/route.js
new file mode 100644 (file)
index 0000000..0a1fdea
--- /dev/null
@@ -0,0 +1,97 @@
+var conversions = require('./conversions');
+
+/*
+       this function routes a model to all other models.
+
+       all functions that are routed have a property `.conversion` attached
+       to the returned synthetic function. This property is an array
+       of strings, each with the steps in between the 'from' and 'to'
+       color models (inclusive).
+
+       conversions that are not possible simply are not included.
+*/
+
+function buildGraph() {
+       var graph = {};
+       // https://jsperf.com/object-keys-vs-for-in-with-closure/3
+       var models = Object.keys(conversions);
+
+       for (var len = models.length, i = 0; i < len; i++) {
+               graph[models[i]] = {
+                       // http://jsperf.com/1-vs-infinity
+                       // micro-opt, but this is simple.
+                       distance: -1,
+                       parent: null
+               };
+       }
+
+       return graph;
+}
+
+// https://en.wikipedia.org/wiki/Breadth-first_search
+function deriveBFS(fromModel) {
+       var graph = buildGraph();
+       var queue = [fromModel]; // unshift -> queue -> pop
+
+       graph[fromModel].distance = 0;
+
+       while (queue.length) {
+               var current = queue.pop();
+               var adjacents = Object.keys(conversions[current]);
+
+               for (var len = adjacents.length, i = 0; i < len; i++) {
+                       var adjacent = adjacents[i];
+                       var node = graph[adjacent];
+
+                       if (node.distance === -1) {
+                               node.distance = graph[current].distance + 1;
+                               node.parent = current;
+                               queue.unshift(adjacent);
+                       }
+               }
+       }
+
+       return graph;
+}
+
+function link(from, to) {
+       return function (args) {
+               return to(from(args));
+       };
+}
+
+function wrapConversion(toModel, graph) {
+       var path = [graph[toModel].parent, toModel];
+       var fn = conversions[graph[toModel].parent][toModel];
+
+       var cur = graph[toModel].parent;
+       while (graph[cur].parent) {
+               path.unshift(graph[cur].parent);
+               fn = link(conversions[graph[cur].parent][cur], fn);
+               cur = graph[cur].parent;
+       }
+
+       fn.conversion = path;
+       return fn;
+}
+
+module.exports = function (fromModel) {
+       var graph = deriveBFS(fromModel);
+       var conversion = {};
+
+       var models = Object.keys(graph);
+       for (var len = models.length, i = 0; i < len; i++) {
+               var toModel = models[i];
+               var node = graph[toModel];
+
+               if (node.parent === null) {
+                       // no possible conversion, or this node is the source model.
+                       continue;
+               }
+
+               conversion[toModel] = wrapConversion(toModel, graph);
+       }
+
+       return conversion;
+};
+
diff --git a/d2d_app/node_modules/color-name/.eslintrc.json b/d2d_app/node_modules/color-name/.eslintrc.json
new file mode 100644 (file)
index 0000000..c50c250
--- /dev/null
@@ -0,0 +1,43 @@
+{
+    "env": {
+        "browser": true,
+        "node": true,
+        "commonjs": true,
+        "es6": true
+    },
+    "extends": "eslint:recommended",
+    "rules": {
+        "strict": 2,
+        "indent": 0,
+        "linebreak-style": 0,
+        "quotes": 0,
+        "semi": 0,
+        "no-cond-assign": 1,
+        "no-constant-condition": 1,
+        "no-duplicate-case": 1,
+        "no-empty": 1,
+        "no-ex-assign": 1,
+        "no-extra-boolean-cast": 1,
+        "no-extra-semi": 1,
+        "no-fallthrough": 1,
+        "no-func-assign": 1,
+        "no-global-assign": 1,
+        "no-implicit-globals": 2,
+        "no-inner-declarations": ["error", "functions"],
+        "no-irregular-whitespace": 2,
+        "no-loop-func": 1,
+        "no-multi-str": 1,
+        "no-mixed-spaces-and-tabs": 1,
+        "no-proto": 1,
+        "no-sequences": 1,
+        "no-throw-literal": 1,
+        "no-unmodified-loop-condition": 1,
+        "no-useless-call": 1,
+        "no-void": 1,
+        "no-with": 2,
+        "wrap-iife": 1,
+        "no-redeclare": 1,
+        "no-unused-vars": ["error", { "vars": "all", "args": "none" }],
+        "no-sparse-arrays": 1
+    }
+}
diff --git a/d2d_app/node_modules/color-name/.npmignore b/d2d_app/node_modules/color-name/.npmignore
new file mode 100644 (file)
index 0000000..f9f2816
--- /dev/null
@@ -0,0 +1,107 @@
+//this will affect all the git repos\r
+git config --global core.excludesfile ~/.gitignore\r
+\r
+\r
+//update files since .ignore won't if already tracked\r
+git rm --cached <file>\r
+\r
+# Compiled source #\r
+###################\r
+*.com\r
+*.class\r
+*.dll\r
+*.exe\r
+*.o\r
+*.so\r
+\r
+# Packages #\r
+############\r
+# it's better to unpack these files and commit the raw source\r
+# git has its own built in compression methods\r
+*.7z\r
+*.dmg\r
+*.gz\r
+*.iso\r
+*.jar\r
+*.rar\r
+*.tar\r
+*.zip\r
+\r
+# Logs and databases #\r
+######################\r
+*.log\r
+*.sql\r
+*.sqlite\r
+\r
+# OS generated files #\r
+######################\r
+.DS_Store\r
+.DS_Store?\r
+._*\r
+.Spotlight-V100\r
+.Trashes\r
+# Icon?\r
+ehthumbs.db\r
+Thumbs.db\r
+.cache\r
+.project\r
+.settings\r
+.tmproj\r
+*.esproj\r
+nbproject\r
+\r
+# Numerous always-ignore extensions #\r
+#####################################\r
+*.diff\r
+*.err\r
+*.orig\r
+*.rej\r
+*.swn\r
+*.swo\r
+*.swp\r
+*.vi\r
+*~\r
+*.sass-cache\r
+*.grunt\r
+*.tmp\r
+\r
+# Dreamweaver added files #\r
+###########################\r
+_notes\r
+dwsync.xml\r
+\r
+# Komodo #\r
+###########################\r
+*.komodoproject\r
+.komodotools\r
+\r
+# Node #\r
+#####################\r
+node_modules\r
+\r
+# Bower #\r
+#####################\r
+bower_components\r
+\r
+# Folders to ignore #\r
+#####################\r
+.hg\r
+.svn\r
+.CVS\r
+intermediate\r
+publish\r
+.idea\r
+.graphics\r
+_test\r
+_archive\r
+uploads\r
+tmp\r
+\r
+# Vim files to ignore #\r
+#######################\r
+.VimballRecord\r
+.netrwhist\r
+\r
+bundle.*\r
+\r
+_demo
\ No newline at end of file
diff --git a/d2d_app/node_modules/color-name/LICENSE b/d2d_app/node_modules/color-name/LICENSE
new file mode 100644 (file)
index 0000000..c6b1001
--- /dev/null
@@ -0,0 +1,8 @@
+The MIT License (MIT)\r
+Copyright (c) 2015 Dmitry Ivanov\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/d2d_app/node_modules/color-name/README.md b/d2d_app/node_modules/color-name/README.md
new file mode 100644 (file)
index 0000000..932b979
--- /dev/null
@@ -0,0 +1,11 @@
+A JSON with color names and its values. Based on http://dev.w3.org/csswg/css-color/#named-colors.\r
+\r
+[![NPM](https://nodei.co/npm/color-name.png?mini=true)](https://nodei.co/npm/color-name/)\r
+\r
+\r
+```js\r
+var colors = require('color-name');\r
+colors.red //[255,0,0]\r
+```\r
+\r
+<a href="LICENSE"><img src="https://upload.wikimedia.org/wikipedia/commons/0/0c/MIT_logo.svg" width="120"/></a>\r
diff --git a/d2d_app/node_modules/color-name/index.js b/d2d_app/node_modules/color-name/index.js
new file mode 100644 (file)
index 0000000..b7c198a
--- /dev/null
@@ -0,0 +1,152 @@
+'use strict'\r
+\r
+module.exports = {\r
+       "aliceblue": [240, 248, 255],\r
+       "antiquewhite": [250, 235, 215],\r
+       "aqua": [0, 255, 255],\r
+       "aquamarine": [127, 255, 212],\r
+       "azure": [240, 255, 255],\r
+       "beige": [245, 245, 220],\r
+       "bisque": [255, 228, 196],\r
+       "black": [0, 0, 0],\r
+       "blanchedalmond": [255, 235, 205],\r
+       "blue": [0, 0, 255],\r
+       "blueviolet": [138, 43, 226],\r
+       "brown": [165, 42, 42],\r
+       "burlywood": [222, 184, 135],\r
+       "cadetblue": [95, 158, 160],\r
+       "chartreuse": [127, 255, 0],\r
+       "chocolate": [210, 105, 30],\r
+       "coral": [255, 127, 80],\r
+       "cornflowerblue": [100, 149, 237],\r
+       "cornsilk": [255, 248, 220],\r
+       "crimson": [220, 20, 60],\r
+       "cyan": [0, 255, 255],\r
+       "darkblue": [0, 0, 139],\r
+       "darkcyan": [0, 139, 139],\r
+       "darkgoldenrod": [184, 134, 11],\r
+       "darkgray": [169, 169, 169],\r
+       "darkgreen": [0, 100, 0],\r
+       "darkgrey": [169, 169, 169],\r
+       "darkkhaki": [189, 183, 107],\r
+       "darkmagenta": [139, 0, 139],\r
+       "darkolivegreen": [85, 107, 47],\r
+       "darkorange": [255, 140, 0],\r
+       "darkorchid": [153, 50, 204],\r
+       "darkred": [139, 0, 0],\r
+       "darksalmon": [233, 150, 122],\r
+       "darkseagreen": [143, 188, 143],\r
+       "darkslateblue": [72, 61, 139],\r
+       "darkslategray": [47, 79, 79],\r
+       "darkslategrey": [47, 79, 79],\r
+       "darkturquoise": [0, 206, 209],\r
+       "darkviolet": [148, 0, 211],\r
+       "deeppink": [255, 20, 147],\r
+       "deepskyblue": [0, 191, 255],\r
+       "dimgray": [105, 105, 105],\r
+       "dimgrey": [105, 105, 105],\r
+       "dodgerblue": [30, 144, 255],\r
+       "firebrick": [178, 34, 34],\r
+       "floralwhite": [255, 250, 240],\r
+       "forestgreen": [34, 139, 34],\r
+       "fuchsia": [255, 0, 255],\r
+       "gainsboro": [220, 220, 220],\r
+       "ghostwhite": [248, 248, 255],\r
+       "gold": [255, 215, 0],\r
+       "goldenrod": [218, 165, 32],\r
+       "gray": [128, 128, 128],\r
+       "green": [0, 128, 0],\r
+       "greenyellow": [173, 255, 47],\r
+       "grey": [128, 128, 128],\r
+       "honeydew": [240, 255, 240],\r
+       "hotpink": [255, 105, 180],\r
+       "indianred": [205, 92, 92],\r
+       "indigo": [75, 0, 130],\r
+       "ivory": [255, 255, 240],\r
+       "khaki": [240, 230, 140],\r
+       "lavender": [230, 230, 250],\r
+       "lavenderblush": [255, 240, 245],\r
+       "lawngreen": [124, 252, 0],\r
+       "lemonchiffon": [255, 250, 205],\r
+       "lightblue": [173, 216, 230],\r
+       "lightcoral": [240, 128, 128],\r
+       "lightcyan": [224, 255, 255],\r
+       "lightgoldenrodyellow": [250, 250, 210],\r
+       "lightgray": [211, 211, 211],\r
+       "lightgreen": [144, 238, 144],\r
+       "lightgrey": [211, 211, 211],\r
+       "lightpink": [255, 182, 193],\r
+       "lightsalmon": [255, 160, 122],\r
+       "lightseagreen": [32, 178, 170],\r
+       "lightskyblue": [135, 206, 250],\r
+       "lightslategray": [119, 136, 153],\r
+       "lightslategrey": [119, 136, 153],\r
+       "lightsteelblue": [176, 196, 222],\r
+       "lightyellow": [255, 255, 224],\r
+       "lime": [0, 255, 0],\r
+       "limegreen": [50, 205, 50],\r
+       "linen": [250, 240, 230],\r
+       "magenta": [255, 0, 255],\r
+       "maroon": [128, 0, 0],\r
+       "mediumaquamarine": [102, 205, 170],\r
+       "mediumblue": [0, 0, 205],\r
+       "mediumorchid": [186, 85, 211],\r
+       "mediumpurple": [147, 112, 219],\r
+       "mediumseagreen": [60, 179, 113],\r
+       "mediumslateblue": [123, 104, 238],\r
+       "mediumspringgreen": [0, 250, 154],\r
+       "mediumturquoise": [72, 209, 204],\r
+       "mediumvioletred": [199, 21, 133],\r
+       "midnightblue": [25, 25, 112],\r
+       "mintcream": [245, 255, 250],\r
+       "mistyrose": [255, 228, 225],\r
+       "moccasin": [255, 228, 181],\r
+       "navajowhite": [255, 222, 173],\r
+       "navy": [0, 0, 128],\r
+       "oldlace": [253, 245, 230],\r
+       "olive": [128, 128, 0],\r
+       "olivedrab": [107, 142, 35],\r
+       "orange": [255, 165, 0],\r
+       "orangered": [255, 69, 0],\r
+       "orchid": [218, 112, 214],\r
+       "palegoldenrod": [238, 232, 170],\r
+       "palegreen": [152, 251, 152],\r
+       "paleturquoise": [175, 238, 238],\r
+       "palevioletred": [219, 112, 147],\r
+       "papayawhip": [255, 239, 213],\r
+       "peachpuff": [255, 218, 185],\r
+       "peru": [205, 133, 63],\r
+       "pink": [255, 192, 203],\r
+       "plum": [221, 160, 221],\r
+       "powderblue": [176, 224, 230],\r
+       "purple": [128, 0, 128],\r
+       "rebeccapurple": [102, 51, 153],\r
+       "red": [255, 0, 0],\r
+       "rosybrown": [188, 143, 143],\r
+       "royalblue": [65, 105, 225],\r
+       "saddlebrown": [139, 69, 19],\r
+       "salmon": [250, 128, 114],\r
+       "sandybrown": [244, 164, 96],\r
+       "seagreen": [46, 139, 87],\r
+       "seashell": [255, 245, 238],\r
+       "sienna": [160, 82, 45],\r
+       "silver": [192, 192, 192],\r
+       "skyblue": [135, 206, 235],\r
+       "slateblue": [106, 90, 205],\r
+       "slategray": [112, 128, 144],\r
+       "slategrey": [112, 128, 144],\r
+       "snow": [255, 250, 250],\r
+       "springgreen": [0, 255, 127],\r
+       "steelblue": [70, 130, 180],\r
+       "tan": [210, 180, 140],\r
+       "teal": [0, 128, 128],\r
+       "thistle": [216, 191, 216],\r
+       "tomato": [255, 99, 71],\r
+       "turquoise": [64, 224, 208],\r
+       "violet": [238, 130, 238],\r
+       "wheat": [245, 222, 179],\r
+       "white": [255, 255, 255],\r
+       "whitesmoke": [245, 245, 245],\r
+       "yellow": [255, 255, 0],\r
+       "yellowgreen": [154, 205, 50]\r
+};\r
diff --git a/d2d_app/node_modules/color-name/package.json b/d2d_app/node_modules/color-name/package.json
new file mode 100644 (file)
index 0000000..9cd60a8
--- /dev/null
@@ -0,0 +1,53 @@
+{
+  "_from": "color-name@1.1.3",
+  "_id": "color-name@1.1.3",
+  "_inBundle": false,
+  "_integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+  "_location": "/color-name",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "color-name@1.1.3",
+    "name": "color-name",
+    "escapedName": "color-name",
+    "rawSpec": "1.1.3",
+    "saveSpec": null,
+    "fetchSpec": "1.1.3"
+  },
+  "_requiredBy": [
+    "/color-convert"
+  ],
+  "_resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+  "_shasum": "a7d0558bd89c42f795dd42328f740831ca53bc25",
+  "_spec": "color-name@1.1.3",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/color-convert",
+  "author": {
+    "name": "DY",
+    "email": "dfcreative@gmail.com"
+  },
+  "bugs": {
+    "url": "https://github.com/dfcreative/color-name/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "A list of color names and its values",
+  "homepage": "https://github.com/dfcreative/color-name",
+  "keywords": [
+    "color-name",
+    "color",
+    "color-keyword",
+    "keyword"
+  ],
+  "license": "MIT",
+  "main": "index.js",
+  "name": "color-name",
+  "repository": {
+    "type": "git",
+    "url": "git+ssh://git@github.com/dfcreative/color-name.git"
+  },
+  "scripts": {
+    "test": "node test.js"
+  },
+  "version": "1.1.3"
+}
diff --git a/d2d_app/node_modules/color-name/test.js b/d2d_app/node_modules/color-name/test.js
new file mode 100644 (file)
index 0000000..6e6bf30
--- /dev/null
@@ -0,0 +1,7 @@
+'use strict'\r
+\r
+var names = require('./');\r
+var assert = require('assert');\r
+\r
+assert.deepEqual(names.red, [255,0,0]);\r
+assert.deepEqual(names.aliceblue, [240,248,255]);\r
diff --git a/d2d_app/node_modules/concat-map/.travis.yml b/d2d_app/node_modules/concat-map/.travis.yml
new file mode 100644 (file)
index 0000000..f1d0f13
--- /dev/null
@@ -0,0 +1,4 @@
+language: node_js
+node_js:
+  - 0.4
+  - 0.6
diff --git a/d2d_app/node_modules/concat-map/LICENSE b/d2d_app/node_modules/concat-map/LICENSE
new file mode 100644 (file)
index 0000000..ee27ba4
--- /dev/null
@@ -0,0 +1,18 @@
+This software is released under the MIT license:
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/concat-map/README.markdown b/d2d_app/node_modules/concat-map/README.markdown
new file mode 100644 (file)
index 0000000..408f70a
--- /dev/null
@@ -0,0 +1,62 @@
+concat-map
+==========
+
+Concatenative mapdashery.
+
+[![browser support](http://ci.testling.com/substack/node-concat-map.png)](http://ci.testling.com/substack/node-concat-map)
+
+[![build status](https://secure.travis-ci.org/substack/node-concat-map.png)](http://travis-ci.org/substack/node-concat-map)
+
+example
+=======
+
+``` js
+var concatMap = require('concat-map');
+var xs = [ 1, 2, 3, 4, 5, 6 ];
+var ys = concatMap(xs, function (x) {
+    return x % 2 ? [ x - 0.1, x, x + 0.1 ] : [];
+});
+console.dir(ys);
+```
+
+***
+
+```
+[ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]
+```
+
+methods
+=======
+
+``` js
+var concatMap = require('concat-map')
+```
+
+concatMap(xs, fn)
+-----------------
+
+Return an array of concatenated elements by calling `fn(x, i)` for each element
+`x` and each index `i` in the array `xs`.
+
+When `fn(x, i)` returns an array, its result will be concatenated with the
+result array. If `fn(x, i)` returns anything else, that value will be pushed
+onto the end of the result array.
+
+install
+=======
+
+With [npm](http://npmjs.org) do:
+
+```
+npm install concat-map
+```
+
+license
+=======
+
+MIT
+
+notes
+=====
+
+This module was written while sitting high above the ground in a tree.
diff --git a/d2d_app/node_modules/concat-map/example/map.js b/d2d_app/node_modules/concat-map/example/map.js
new file mode 100644 (file)
index 0000000..3365621
--- /dev/null
@@ -0,0 +1,6 @@
+var concatMap = require('../');
+var xs = [ 1, 2, 3, 4, 5, 6 ];
+var ys = concatMap(xs, function (x) {
+    return x % 2 ? [ x - 0.1, x, x + 0.1 ] : [];
+});
+console.dir(ys);
diff --git a/d2d_app/node_modules/concat-map/index.js b/d2d_app/node_modules/concat-map/index.js
new file mode 100644 (file)
index 0000000..b29a781
--- /dev/null
@@ -0,0 +1,13 @@
+module.exports = function (xs, fn) {
+    var res = [];
+    for (var i = 0; i < xs.length; i++) {
+        var x = fn(xs[i], i);
+        if (isArray(x)) res.push.apply(res, x);
+        else res.push(x);
+    }
+    return res;
+};
+
+var isArray = Array.isArray || function (xs) {
+    return Object.prototype.toString.call(xs) === '[object Array]';
+};
diff --git a/d2d_app/node_modules/concat-map/package.json b/d2d_app/node_modules/concat-map/package.json
new file mode 100644 (file)
index 0000000..cae3b13
--- /dev/null
@@ -0,0 +1,88 @@
+{
+  "_from": "concat-map@0.0.1",
+  "_id": "concat-map@0.0.1",
+  "_inBundle": false,
+  "_integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+  "_location": "/concat-map",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "version",
+    "registry": true,
+    "raw": "concat-map@0.0.1",
+    "name": "concat-map",
+    "escapedName": "concat-map",
+    "rawSpec": "0.0.1",
+    "saveSpec": null,
+    "fetchSpec": "0.0.1"
+  },
+  "_requiredBy": [
+    "/brace-expansion"
+  ],
+  "_resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+  "_shasum": "d8a96bd77fd68df7793a73036a3ba0d5405d477b",
+  "_spec": "concat-map@0.0.1",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/brace-expansion",
+  "author": {
+    "name": "James Halliday",
+    "email": "mail@substack.net",
+    "url": "http://substack.net"
+  },
+  "bugs": {
+    "url": "https://github.com/substack/node-concat-map/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "concatenative mapdashery",
+  "devDependencies": {
+    "tape": "~2.4.0"
+  },
+  "directories": {
+    "example": "example",
+    "test": "test"
+  },
+  "homepage": "https://github.com/substack/node-concat-map#readme",
+  "keywords": [
+    "concat",
+    "concatMap",
+    "map",
+    "functional",
+    "higher-order"
+  ],
+  "license": "MIT",
+  "main": "index.js",
+  "name": "concat-map",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/substack/node-concat-map.git"
+  },
+  "scripts": {
+    "test": "tape test/*.js"
+  },
+  "testling": {
+    "files": "test/*.js",
+    "browsers": {
+      "ie": [
+        6,
+        7,
+        8,
+        9
+      ],
+      "ff": [
+        3.5,
+        10,
+        15
+      ],
+      "chrome": [
+        10,
+        22
+      ],
+      "safari": [
+        5.1
+      ],
+      "opera": [
+        12
+      ]
+    }
+  },
+  "version": "0.0.1"
+}
diff --git a/d2d_app/node_modules/concat-map/test/map.js b/d2d_app/node_modules/concat-map/test/map.js
new file mode 100644 (file)
index 0000000..fdbd702
--- /dev/null
@@ -0,0 +1,39 @@
+var concatMap = require('../');
+var test = require('tape');
+
+test('empty or not', function (t) {
+    var xs = [ 1, 2, 3, 4, 5, 6 ];
+    var ixes = [];
+    var ys = concatMap(xs, function (x, ix) {
+        ixes.push(ix);
+        return x % 2 ? [ x - 0.1, x, x + 0.1 ] : [];
+    });
+    t.same(ys, [ 0.9, 1, 1.1, 2.9, 3, 3.1, 4.9, 5, 5.1 ]);
+    t.same(ixes, [ 0, 1, 2, 3, 4, 5 ]);
+    t.end();
+});
+
+test('always something', function (t) {
+    var xs = [ 'a', 'b', 'c', 'd' ];
+    var ys = concatMap(xs, function (x) {
+        return x === 'b' ? [ 'B', 'B', 'B' ] : [ x ];
+    });
+    t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]);
+    t.end();
+});
+
+test('scalars', function (t) {
+    var xs = [ 'a', 'b', 'c', 'd' ];
+    var ys = concatMap(xs, function (x) {
+        return x === 'b' ? [ 'B', 'B', 'B' ] : x;
+    });
+    t.same(ys, [ 'a', 'B', 'B', 'B', 'c', 'd' ]);
+    t.end();
+});
+
+test('undefs', function (t) {
+    var xs = [ 'a', 'b', 'c', 'd' ];
+    var ys = concatMap(xs, function () {});
+    t.same(ys, [ undefined, undefined, undefined, undefined ]);
+    t.end();
+});
     "fetchSpec": "1.0.6"
   },
   "_requiredBy": [
-    "/express"
+    "/express-session"
   ],
   "_resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
   "_shasum": "e303a882b342cc3ee8ca513a79999734dab3ae2c",
   "_spec": "cookie-signature@1.0.6",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/express",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/express-session",
   "author": {
     "name": "TJ Holowaychuk",
     "email": "tj@learnboost.com"
     "fetchSpec": "0.4.0"
   },
   "_requiredBy": [
-    "/express"
+    "/express-session"
   ],
   "_resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
   "_shasum": "beb437e7022b3b6d49019d088665303ebe9c14ba",
   "_spec": "cookie@0.4.0",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/express",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/express-session",
   "author": {
     "name": "Roman Shtylman",
     "email": "shtylman@gmail.com"
@@ -3,7 +3,7 @@
   "_id": "debug@2.6.9",
   "_inBundle": false,
   "_integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-  "_location": "/express/debug",
+  "_location": "/debug",
   "_phantomChildren": {},
   "_requested": {
     "type": "version",
     "fetchSpec": "2.6.9"
   },
   "_requiredBy": [
-    "/express"
+    "/express-session"
   ],
   "_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
   "_shasum": "5d128515df134ff327e90a4c93f4e077a536341f",
   "_spec": "debug@2.6.9",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/express",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/express-session",
   "author": {
     "name": "TJ Holowaychuk",
     "email": "tj@vision-media.ca"
@@ -1,3 +1,10 @@
+2.0.0 / 2018-10-26
+==================
+
+  * Drop support for Node.js 0.6
+  * Replace internal `eval` usage with `Function` constructor
+  * Use instance methods on `process` to check for listeners
+
 1.1.2 / 2018-01-11
 ==================
 
similarity index 95%
rename from d2d_app/node_modules/express/node_modules/depd/LICENSE
rename to d2d_app/node_modules/depd/LICENSE
index 84441fb..248de7a 100644 (file)
@@ -1,6 +1,6 @@
 (The MIT License)
 
-Copyright (c) 2014-2017 Douglas Christopher Wilson
+Copyright (c) 2014-2018 Douglas Christopher Wilson
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
@@ -267,14 +267,14 @@ deprecate.property(exports, 'oldprop', 'oldprop >= 0.10')
 
 [MIT](LICENSE)
 
-[npm-version-image]: https://img.shields.io/npm/v/depd.svg
-[npm-downloads-image]: https://img.shields.io/npm/dm/depd.svg
-[npm-url]: https://npmjs.org/package/depd
-[travis-image]: https://img.shields.io/travis/dougwilson/nodejs-depd/master.svg?label=linux
-[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd
-[appveyor-image]: https://img.shields.io/appveyor/ci/dougwilson/nodejs-depd/master.svg?label=windows
+[appveyor-image]: https://badgen.net/appveyor/ci/dougwilson/nodejs-depd/master?label=windows
 [appveyor-url]: https://ci.appveyor.com/project/dougwilson/nodejs-depd
-[coveralls-image]: https://img.shields.io/coveralls/dougwilson/nodejs-depd/master.svg
+[coveralls-image]: https://badgen.net/coveralls/c/github/dougwilson/nodejs-depd/master
 [coveralls-url]: https://coveralls.io/r/dougwilson/nodejs-depd?branch=master
-[node-image]: https://img.shields.io/node/v/depd.svg
+[node-image]: https://badgen.net/npm/node/depd
 [node-url]: https://nodejs.org/en/download/
+[npm-downloads-image]: https://badgen.net/npm/dm/depd
+[npm-url]: https://npmjs.org/package/depd
+[npm-version-image]: https://badgen.net/npm/v/depd
+[travis-image]: https://badgen.net/travis/dougwilson/nodejs-depd/master?label=linux
+[travis-url]: https://travis-ci.org/dougwilson/nodejs-depd
similarity index 90%
rename from d2d_app/node_modules/express/node_modules/depd/index.js
rename to d2d_app/node_modules/depd/index.js
index d758d3c..1bf2fcf 100644 (file)
@@ -1,6 +1,6 @@
 /*!
  * depd
- * Copyright(c) 2014-2017 Douglas Christopher Wilson
+ * Copyright(c) 2014-2018 Douglas Christopher Wilson
  * MIT Licensed
  */
 
@@ -8,8 +8,6 @@
  * Module dependencies.
  */
 
-var callSiteToString = require('./lib/compat').callSiteToString
-var eventListenerCount = require('./lib/compat').eventListenerCount
 var relative = require('path').relative
 
 /**
@@ -92,7 +90,7 @@ function createStackString (stack) {
   }
 
   for (var i = 0; i < stack.length; i++) {
-    str += '\n    at ' + callSiteToString(stack[i])
+    str += '\n    at ' + stack[i].toString()
   }
 
   return str
@@ -129,11 +127,30 @@ function depd (namespace) {
 }
 
 /**
+ * Determine if event emitter has listeners of a given type.
+ *
+ * The way to do this check is done three different ways in Node.js >= 0.8
+ * so this consolidates them into a minimal set using instance methods.
+ *
+ * @param {EventEmitter} emitter
+ * @param {string} type
+ * @returns {boolean}
+ * @private
+ */
+
+function eehaslisteners (emitter, type) {
+  var count = typeof emitter.listenerCount !== 'function'
+    ? emitter.listeners(type).length
+    : emitter.listenerCount(type)
+
+  return count > 0
+}
+
+/**
  * Determine if namespace is ignored.
  */
 
 function isignored (namespace) {
-  /* istanbul ignore next: tested in a child processs */
   if (process.noDeprecation) {
     // --no-deprecation support
     return true
@@ -150,7 +167,6 @@ function isignored (namespace) {
  */
 
 function istraced (namespace) {
-  /* istanbul ignore next: tested in a child processs */
   if (process.traceDeprecation) {
     // --trace-deprecation support
     return true
@@ -167,7 +183,7 @@ function istraced (namespace) {
  */
 
 function log (message, site) {
-  var haslisteners = eventListenerCount(process, 'deprecation') !== 0
+  var haslisteners = eehaslisteners(process, 'deprecation')
 
   // abort early if no destination
   if (!haslisteners && this._ignored) {
@@ -310,7 +326,7 @@ function formatPlain (msg, caller, stack) {
   // add stack trace
   if (this._traced) {
     for (var i = 0; i < stack.length; i++) {
-      formatted += '\n    at ' + callSiteToString(stack[i])
+      formatted += '\n    at ' + stack[i].toString()
     }
 
     return formatted
@@ -335,7 +351,7 @@ function formatColor (msg, caller, stack) {
   // add stack trace
   if (this._traced) {
     for (var i = 0; i < stack.length; i++) {
-      formatted += '\n    \x1b[36mat ' + callSiteToString(stack[i]) + '\x1b[39m' // cyan
+      formatted += '\n    \x1b[36mat ' + stack[i].toString() + '\x1b[39m' // cyan
     }
 
     return formatted
@@ -400,18 +416,18 @@ function wrapfunction (fn, message) {
   }
 
   var args = createArgumentsString(fn.length)
-  var deprecate = this // eslint-disable-line no-unused-vars
   var stack = getStack()
   var site = callSiteLocation(stack[1])
 
   site.name = fn.name
 
-   // eslint-disable-next-line no-eval
-  var deprecatedfn = eval('(function (' + args + ') {\n' +
+  // eslint-disable-next-line no-new-func
+  var deprecatedfn = new Function('fn', 'log', 'deprecate', 'message', 'site',
     '"use strict"\n' +
+    'return function (' + args + ') {' +
     'log.call(deprecate, message, site)\n' +
     'return fn.apply(this, arguments)\n' +
-    '})')
+    '}')(fn, log, this, message, site)
 
   return deprecatedfn
 }
@@ -1,30 +1,27 @@
 {
-  "_from": "depd@~1.1.2",
-  "_id": "depd@1.1.2",
+  "_from": "depd@~2.0.0",
+  "_id": "depd@2.0.0",
   "_inBundle": false,
-  "_integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+  "_integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
   "_location": "/depd",
   "_phantomChildren": {},
   "_requested": {
     "type": "range",
     "registry": true,
-    "raw": "depd@~1.1.2",
+    "raw": "depd@~2.0.0",
     "name": "depd",
     "escapedName": "depd",
-    "rawSpec": "~1.1.2",
+    "rawSpec": "~2.0.0",
     "saveSpec": null,
-    "fetchSpec": "~1.1.2"
+    "fetchSpec": "~2.0.0"
   },
   "_requiredBy": [
-    "/body-parser",
-    "/express",
-    "/http-errors",
-    "/send"
+    "/express-session"
   ],
-  "_resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
-  "_shasum": "9bcd52e14c097763e749b274c4346ed2e560b5a9",
-  "_spec": "depd@~1.1.2",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/express",
+  "_resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+  "_shasum": "b696163cc757560d09cf22cc8fad1571b79e76df",
+  "_spec": "depd@~2.0.0",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/express-session",
   "author": {
     "name": "Douglas Christopher Wilson",
     "email": "doug@somethingdoug.com"
   "devDependencies": {
     "beautify-benchmark": "0.2.4",
     "benchmark": "2.1.4",
-    "eslint": "3.19.0",
-    "eslint-config-standard": "7.1.0",
+    "eslint": "5.7.0",
+    "eslint-config-standard": "12.0.0",
+    "eslint-plugin-import": "2.14.0",
     "eslint-plugin-markdown": "1.0.0-beta.7",
-    "eslint-plugin-promise": "3.6.0",
-    "eslint-plugin-standard": "3.0.1",
+    "eslint-plugin-node": "7.0.1",
+    "eslint-plugin-promise": "4.0.1",
+    "eslint-plugin-standard": "4.0.0",
     "istanbul": "0.4.5",
-    "mocha": "~1.21.5"
+    "mocha": "5.2.0",
+    "safe-buffer": "5.1.2",
+    "uid-safe": "2.1.5"
   },
   "engines": {
-    "node": ">= 0.6"
+    "node": ">= 0.8"
   },
   "files": [
     "lib/",
@@ -72,8 +73,8 @@
     "bench": "node benchmark/index.js",
     "lint": "eslint --plugin markdown --ext js,md .",
     "test": "mocha --reporter spec --bail test/",
-    "test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --no-exit test/",
-    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot test/"
+    "test-ci": "istanbul cover --print=none node_modules/mocha/bin/_mocha -- --reporter spec test/ && istanbul report lcovonly text-summary",
+    "test-cov": "istanbul cover --print=none node_modules/mocha/bin/_mocha -- --reporter dot test/ && istanbul report lcov text-summary"
   },
-  "version": "1.1.2"
+  "version": "2.0.0"
 }
diff --git a/d2d_app/node_modules/ejs/LICENSE b/d2d_app/node_modules/ejs/LICENSE
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/d2d_app/node_modules/ejs/README.md b/d2d_app/node_modules/ejs/README.md
new file mode 100644 (file)
index 0000000..009809c
--- /dev/null
@@ -0,0 +1,341 @@
+Embedded JavaScript templates<br/>
+[![Build Status](https://img.shields.io/travis/mde/ejs/master.svg?style=flat)](https://travis-ci.org/mde/ejs)
+[![Developing Dependencies](https://img.shields.io/david/dev/mde/ejs.svg?style=flat)](https://david-dm.org/mde/ejs?type=dev)
+[![Known Vulnerabilities](https://snyk.io/test/npm/ejs/badge.svg?style=flat)](https://snyk.io/test/npm/ejs)
+=============================
+
+## Installation
+
+```bash
+$ npm install ejs
+```
+
+## Features
+
+  * Control flow with `<% %>`
+  * Escaped output with `<%= %>` (escape function configurable)
+  * Unescaped raw output with `<%- %>`
+  * Newline-trim mode ('newline slurping') with `-%>` ending tag
+  * Whitespace-trim mode (slurp all whitespace) for control flow with `<%_ _%>`
+  * Custom delimiters (e.g. `[? ?]` instead of `<% %>`)
+  * Includes
+  * Client-side support
+  * Static caching of intermediate JavaScript
+  * Static caching of templates
+  * Complies with the [Express](http://expressjs.com) view system
+
+## Example
+
+```ejs
+<% if (user) { %>
+  <h2><%= user.name %></h2>
+<% } %>
+```
+
+Try EJS online at: https://ionicabizau.github.io/ejs-playground/.
+
+## Basic usage
+
+```javascript
+let template = ejs.compile(str, options);
+template(data);
+// => Rendered HTML string
+
+ejs.render(str, data, options);
+// => Rendered HTML string
+
+ejs.renderFile(filename, data, options, function(err, str){
+    // str => Rendered HTML string
+});
+```
+
+It is also possible to use `ejs.render(dataAndOptions);` where you pass
+everything in a single object. In that case, you'll end up with local variables
+for all the passed options. However, be aware that your code could break if we
+add an option with the same name as one of your data object's properties.
+Therefore, we do not recommend using this shortcut.
+
+### Options
+
+  - `cache`                 Compiled functions are cached, requires `filename`
+  - `filename`              The name of the file being rendered. Not required if you
+    are using `renderFile()`. Used by `cache` to key caches, and for includes.
+  - `root`                  Set project root for includes with an absolute path (e.g, /file.ejs).
+    Can be array to try to resolve include from multiple directories.
+  - `views`                 An array of paths to use when resolving includes with relative paths.
+  - `context`               Function execution context
+  - `compileDebug`          When `false` no debug instrumentation is compiled
+  - `client`                When `true`, compiles a function that can be rendered
+    in the browser without needing to load the EJS Runtime
+    ([ejs.min.js](https://github.com/mde/ejs/releases/latest)).
+  - `delimiter`             Character to use for inner delimiter, by default '%'
+  - `openDelimiter`         Character to use for opening delimiter, by default '<'
+  - `closeDelimiter`        Character to use for closing delimiter, by default '>'
+  - `debug`                 Outputs generated function body
+  - `strict`                When set to `true`, generated function is in strict mode
+  - `_with`                 Whether or not to use `with() {}` constructs. If `false`
+    then the locals will be stored in the `locals` object. Set to `false` in strict mode.
+  - `destructuredLocals`    An array of local variables that are always destructured from
+    the locals object, available even in strict mode.
+  - `localsName`            Name to use for the object storing local variables when not using
+    `with` Defaults to `locals`
+  - `rmWhitespace`          Remove all safe-to-remove whitespace, including leading
+    and trailing whitespace. It also enables a safer version of `-%>` line
+    slurping for all scriptlet tags (it does not strip new lines of tags in
+    the middle of a line).
+  - `escape`                The escaping function used with `<%=` construct. It is
+    used in rendering and is `.toString()`ed in the generation of client functions.
+    (By default escapes XML).
+  - `outputFunctionName`    Set to a string (e.g., 'echo' or 'print') for a function to print
+    output inside scriptlet tags.
+  - `async`                 When `true`, EJS will use an async function for rendering. (Depends
+    on async/await support in the JS runtime.
+  - `includer`              Custom function to handle EJS includes, receives `(originalPath, parsedPath)`
+    parameters, where `originalPath` is the path in include as-is and `parsedPath` is the
+    previously resolved path. Should return an object `{ filename, template }`,
+    you may return only one of the properties, where `filename` is the final parsed path and `template`
+    is the included content.
+
+This project uses [JSDoc](http://usejsdoc.org/). For the full public API
+documentation, clone the repository and run `jake doc`. This will run JSDoc
+with the proper options and output the documentation to `out/`. If you want
+the both the public & private API docs, run `jake devdoc` instead.
+
+### Tags
+
+  - `<%`              'Scriptlet' tag, for control-flow, no output
+  - `<%_`             'Whitespace Slurping' Scriptlet tag, strips all whitespace before it
+  - `<%=`             Outputs the value into the template (escaped)
+  - `<%-`             Outputs the unescaped value into the template
+  - `<%#`             Comment tag, no execution, no output
+  - `<%%`             Outputs a literal '<%'
+  - `%%>`             Outputs a literal '%>'
+  - `%>`              Plain ending tag
+  - `-%>`             Trim-mode ('newline slurp') tag, trims following newline
+  - `_%>`             'Whitespace Slurping' ending tag, removes all whitespace after it
+
+For the full syntax documentation, please see [docs/syntax.md](https://github.com/mde/ejs/blob/master/docs/syntax.md).
+
+### Includes
+
+Includes either have to be an absolute path, or, if not, are assumed as
+relative to the template with the `include` call. For example if you are
+including `./views/user/show.ejs` from `./views/users.ejs` you would
+use `<%- include('user/show') %>`.
+
+You must specify the `filename` option for the template with the `include`
+call unless you are using `renderFile()`.
+
+You'll likely want to use the raw output tag (`<%-`) with your include to avoid
+double-escaping the HTML output.
+
+```ejs
+<ul>
+  <% users.forEach(function(user){ %>
+    <%- include('user/show', {user: user}) %>
+  <% }); %>
+</ul>
+```
+
+Includes are inserted at runtime, so you can use variables for the path in the
+`include` call (for example `<%- include(somePath) %>`). Variables in your
+top-level data object are available to all your includes, but local variables
+need to be passed down.
+
+NOTE: Include preprocessor directives (`<% include user/show %>`) are
+not supported in v3.0+.
+
+## Custom delimiters
+
+Custom delimiters can be applied on a per-template basis, or globally:
+
+```javascript
+let ejs = require('ejs'),
+    users = ['geddy', 'neil', 'alex'];
+
+// Just one template
+ejs.render('<p>[?= users.join(" | "); ?]</p>', {users: users}, {delimiter: '?', openDelimiter: '[', closeDelimiter: ']'});
+// => '<p>geddy | neil | alex</p>'
+
+// Or globally
+ejs.delimiter = '?';
+ejs.openDelimiter = '[';
+ejs.closeDelimiter = ']';
+ejs.render('<p>[?= users.join(" | "); ?]</p>', {users: users});
+// => '<p>geddy | neil | alex</p>'
+```
+
+### Caching
+
+EJS ships with a basic in-process cache for caching the intermediate JavaScript
+functions used to render templates. It's easy to plug in LRU caching using
+Node's `lru-cache` library:
+
+```javascript
+let ejs = require('ejs'),
+    LRU = require('lru-cache');
+ejs.cache = LRU(100); // LRU cache with 100-item limit
+```
+
+If you want to clear the EJS cache, call `ejs.clearCache`. If you're using the
+LRU cache and need a different limit, simple reset `ejs.cache` to a new instance
+of the LRU.
+
+### Custom file loader
+
+The default file loader is `fs.readFileSync`, if you want to customize it, you can set ejs.fileLoader.
+
+```javascript
+let ejs = require('ejs');
+let myFileLoad = function (filePath) {
+  return 'myFileLoad: ' + fs.readFileSync(filePath);
+};
+
+ejs.fileLoader = myFileLoad;
+```
+
+With this feature, you can preprocess the template before reading it.
+
+### Layouts
+
+EJS does not specifically support blocks, but layouts can be implemented by
+including headers and footers, like so:
+
+
+```ejs
+<%- include('header') -%>
+<h1>
+  Title
+</h1>
+<p>
+  My page
+</p>
+<%- include('footer') -%>
+```
+
+## Client-side support
+
+Go to the [Latest Release](https://github.com/mde/ejs/releases/latest), download
+`./ejs.js` or `./ejs.min.js`. Alternately, you can compile it yourself by cloning
+the repository and running `jake build` (or `$(npm bin)/jake build` if jake is
+not installed globally).
+
+Include one of these files on your page, and `ejs` should be available globally.
+
+### Example
+
+```html
+<div id="output"></div>
+<script src="ejs.min.js"></script>
+<script>
+  let people = ['geddy', 'neil', 'alex'],
+      html = ejs.render('<%= people.join(", "); %>', {people: people});
+  // With jQuery:
+  $('#output').html(html);
+  // Vanilla JS:
+  document.getElementById('output').innerHTML = html;
+</script>
+```
+
+### Caveats
+
+Most of EJS will work as expected; however, there are a few things to note:
+
+1. Obviously, since you do not have access to the filesystem, `ejs.renderFile()` won't work.
+2. For the same reason, `include`s do not work unless you use an `include callback`. Here is an example:
+  ```javascript
+  let str = "Hello <%= include('file', {person: 'John'}); %>",
+      fn = ejs.compile(str, {client: true});
+
+  fn(data, null, function(path, d){ // include callback
+    // path -> 'file'
+    // d -> {person: 'John'}
+    // Put your code here
+    // Return the contents of file as a string
+  }); // returns rendered string
+  ```
+
+See the [examples folder](https://github.com/mde/ejs/tree/master/examples) for more details.
+
+## CLI
+
+EJS ships with a full-featured CLI. Options are similar to those used in JavaScript code:
+
+  - `-o / --output-file FILE`            Write the rendered output to FILE rather than stdout.
+  - `-f / --data-file FILE`              Must be JSON-formatted. Use parsed input from FILE as data for rendering.
+  - `-i / --data-input STRING`           Must be JSON-formatted and URI-encoded. Use parsed input from STRING as data for rendering.
+  - `-m / --delimiter CHARACTER`         Use CHARACTER with angle brackets for open/close (defaults to %).
+  - `-p / --open-delimiter CHARACTER`    Use CHARACTER instead of left angle bracket to open.
+  - `-c / --close-delimiter CHARACTER`   Use CHARACTER instead of right angle bracket to close.
+  - `-s / --strict`                      When set to `true`, generated function is in strict mode
+  - `-n / --no-with`                     Use 'locals' object for vars rather than using `with` (implies --strict).
+  - `-l / --locals-name`                 Name to use for the object storing local variables when not using `with`.
+  - `-w / --rm-whitespace`               Remove all safe-to-remove whitespace, including leading and trailing whitespace.
+  - `-d / --debug`                       Outputs generated function body
+  - `-h / --help`                        Display this help message.
+  - `-V/v / --version`                   Display the EJS version.
+
+Here are some examples of usage:
+
+```shell
+$ ejs -p [ -c ] ./template_file.ejs -o ./output.html
+$ ejs ./test/fixtures/user.ejs name=Lerxst
+$ ejs -n -l _ ./some_template.ejs -f ./data_file.json
+```
+
+### Data input
+
+There is a variety of ways to pass the CLI data for rendering.
+
+Stdin:
+
+```shell
+$ ./test/fixtures/user_data.json | ejs ./test/fixtures/user.ejs
+$ ejs ./test/fixtures/user.ejs < test/fixtures/user_data.json
+```
+
+A data file:
+
+```shell
+$ ejs ./test/fixtures/user.ejs -f ./user_data.json
+```
+
+A command-line option (must be URI-encoded):
+
+```shell
+./bin/cli.js -i %7B%22name%22%3A%20%22foo%22%7D ./test/fixtures/user.ejs
+```
+
+Or, passing values directly at the end of the invocation:
+
+```shell
+./bin/cli.js -m $ ./test/fixtures/user.ejs name=foo
+```
+
+### Output
+
+The CLI by default send output to stdout, but you can use the `-o` or `--output-file`
+flag to specify a target file to send the output to.
+
+## IDE Integration with Syntax Highlighting
+
+VSCode:Javascript EJS by *DigitalBrainstem*
+
+## Related projects
+
+There are a number of implementations of EJS:
+
+ * TJ's implementation, the v1 of this library: https://github.com/tj/ejs
+ * EJS Embedded JavaScript Framework on Google Code: https://code.google.com/p/embeddedjavascript/
+ * Sam Stephenson's Ruby implementation: https://rubygems.org/gems/ejs
+ * Erubis, an ERB implementation which also runs JavaScript: http://www.kuwata-lab.com/erubis/users-guide.04.html#lang-javascript
+ * DigitalBrainstem EJS Language support: https://github.com/Digitalbrainstem/ejs-grammar
+
+## License
+
+Licensed under the Apache License, Version 2.0
+(<http://www.apache.org/licenses/LICENSE-2.0>)
+
+- - -
+EJS Embedded JavaScript templates copyright 2112
+mde@fleegix.org.
diff --git a/d2d_app/node_modules/ejs/bin/cli.js b/d2d_app/node_modules/ejs/bin/cli.js
new file mode 100755 (executable)
index 0000000..0feab0b
--- /dev/null
@@ -0,0 +1,212 @@
+#!/usr/bin/env node
+/*
+ * EJS Embedded JavaScript templates
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+
+let program = require('jake').program;
+delete global.jake; // NO NOT WANT
+program.setTaskNames = function (n) { this.taskNames = n; };
+
+let ejs = require('../lib/ejs');
+let { hyphenToCamel } = require('../lib/utils');
+let fs = require('fs');
+let args = process.argv.slice(2);
+let usage = fs.readFileSync(`${__dirname}/../usage.txt`).toString();
+
+const CLI_OPTS = [
+  { full: 'output-file',
+    abbr: 'o',
+    expectValue: true,
+  },
+  { full: 'data-file',
+    abbr: 'f',
+    expectValue: true,
+  },
+  { full: 'data-input',
+    abbr: 'i',
+    expectValue: true,
+  },
+  { full: 'delimiter',
+    abbr: 'm',
+    expectValue: true,
+    passThrough: true,
+  },
+  { full: 'open-delimiter',
+    abbr: 'p',
+    expectValue: true,
+    passThrough: true,
+  },
+  { full: 'close-delimiter',
+    abbr: 'c',
+    expectValue: true,
+    passThrough: true,
+  },
+  { full: 'strict',
+    abbr: 's',
+    expectValue: false,
+    allowValue: false,
+    passThrough: true,
+  },
+  { full: 'no-with',
+    abbr: 'n',
+    expectValue: false,
+    allowValue: false,
+  },
+  { full: 'locals-name',
+    abbr: 'l',
+    expectValue: true,
+    passThrough: true,
+  },
+  { full: 'rm-whitespace',
+    abbr: 'w',
+    expectValue: false,
+    allowValue: false,
+    passThrough: true,
+  },
+  { full: 'debug',
+    abbr: 'd',
+    expectValue: false,
+    allowValue: false,
+    passThrough: true,
+  },
+  { full: 'help',
+    abbr: 'h',
+    passThrough: true,
+  },
+  { full: 'version',
+    abbr: 'V',
+    passThrough: true,
+  },
+  // Alias lowercase v
+  { full: 'version',
+    abbr: 'v',
+    passThrough: true,
+  },
+];
+
+let preempts = {
+  version: function () {
+    program.die(ejs.VERSION);
+  },
+  help: function () {
+    program.die(usage);
+  }
+};
+
+let stdin = '';
+process.stdin.setEncoding('utf8');
+process.stdin.on('readable', () => {
+  let chunk;
+  while ((chunk = process.stdin.read()) !== null) {
+    stdin += chunk;
+  }
+});
+
+function run() {
+
+  program.availableOpts = CLI_OPTS;
+  program.parseArgs(args);
+
+  let templatePath = program.taskNames[0];
+  let pVals = program.envVars;
+  let pOpts = {};
+
+  for (let p in program.opts) {
+    let name = hyphenToCamel(p);
+    pOpts[name] = program.opts[p];
+  }
+
+  let opts = {};
+  let vals = {};
+
+  // Same-named 'passthrough' opts
+  CLI_OPTS.forEach((opt) => {
+    let optName = hyphenToCamel(opt.full);
+    if (opt.passThrough && typeof pOpts[optName] != 'undefined') {
+      opts[optName] = pOpts[optName];
+    }
+  });
+
+  // Bail out for help/version
+  for (let p in opts) {
+    if (preempts[p]) {
+      return preempts[p]();
+    }
+  }
+
+  // Default to having views relative from the current working directory
+  opts.views = ['.'];
+
+  // Ensure there's a template to render
+  if (!templatePath) {
+    throw new Error('Please provide a template path. (Run ejs -h for help)');
+  }
+
+  if (opts.strict) {
+    pOpts.noWith = true;
+  }
+  if (pOpts.noWith) {
+    opts._with = false;
+  }
+
+  // Grab and parse any input data, in order of precedence:
+  // 1. Stdin
+  // 2. CLI arg via -i
+  // 3. Data file via -f
+  // Any individual vals passed at the end (e.g., foo=bar) will override
+  // any vals previously set
+  let input;
+  let err = new Error('Please do not pass data multiple ways. Pick one of stdin, -f, or -i.');
+  if (stdin) {
+    input = stdin;
+  }
+  else if (pOpts.dataInput) {
+    if (input) {
+      throw err;
+    }
+    input = decodeURIComponent(pOpts.dataInput);
+  }
+  else if (pOpts.dataFile) {
+    if (input) {
+      throw err;
+    }
+    input = fs.readFileSync(pOpts.dataFile).toString();
+  }
+
+  if (input) {
+    vals = JSON.parse(input);
+  }
+
+  // Override / set any individual values passed from the command line
+  for (let p in pVals) {
+    vals[p] = pVals[p];
+  }
+
+  let template = fs.readFileSync(templatePath).toString();
+  let output = ejs.render(template, vals, opts);
+  if (pOpts.outputFile) {
+    fs.writeFileSync(pOpts.outputFile, output);
+  }
+  else {
+    process.stdout.write(output);
+  }
+  process.exit();
+}
+
+// Defer execution so that stdin can be read if necessary
+setImmediate(run);
diff --git a/d2d_app/node_modules/ejs/ejs.js b/d2d_app/node_modules/ejs/ejs.js
new file mode 100644 (file)
index 0000000..5310e76
--- /dev/null
@@ -0,0 +1,1662 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ejs = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
+/*
+ * EJS Embedded JavaScript templates
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+'use strict';
+
+/**
+ * @file Embedded JavaScript templating engine. {@link http://ejs.co}
+ * @author Matthew Eernisse <mde@fleegix.org>
+ * @author Tiancheng "Timothy" Gu <timothygu99@gmail.com>
+ * @project EJS
+ * @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0}
+ */
+
+/**
+ * EJS internal functions.
+ *
+ * Technically this "module" lies in the same file as {@link module:ejs}, for
+ * the sake of organization all the private functions re grouped into this
+ * module.
+ *
+ * @module ejs-internal
+ * @private
+ */
+
+/**
+ * Embedded JavaScript templating engine.
+ *
+ * @module ejs
+ * @public
+ */
+
+var fs = require('fs');
+var path = require('path');
+var utils = require('./utils');
+
+var scopeOptionWarned = false;
+/** @type {string} */
+var _VERSION_STRING = require('../package.json').version;
+var _DEFAULT_OPEN_DELIMITER = '<';
+var _DEFAULT_CLOSE_DELIMITER = '>';
+var _DEFAULT_DELIMITER = '%';
+var _DEFAULT_LOCALS_NAME = 'locals';
+var _NAME = 'ejs';
+var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)';
+var _OPTS_PASSABLE_WITH_DATA = ['delimiter', 'scope', 'context', 'debug', 'compileDebug',
+  'client', '_with', 'rmWhitespace', 'strict', 'filename', 'async'];
+// We don't allow 'cache' option to be passed in the data obj for
+// the normal `render` call, but this is where Express 2 & 3 put it
+// so we make an exception for `renderFile`
+var _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat('cache');
+var _BOM = /^\uFEFF/;
+
+/**
+ * EJS template function cache. This can be a LRU object from lru-cache NPM
+ * module. By default, it is {@link module:utils.cache}, a simple in-process
+ * cache that grows continuously.
+ *
+ * @type {Cache}
+ */
+
+exports.cache = utils.cache;
+
+/**
+ * Custom file loader. Useful for template preprocessing or restricting access
+ * to a certain part of the filesystem.
+ *
+ * @type {fileLoader}
+ */
+
+exports.fileLoader = fs.readFileSync;
+
+/**
+ * Name of the object containing the locals.
+ *
+ * This variable is overridden by {@link Options}`.localsName` if it is not
+ * `undefined`.
+ *
+ * @type {String}
+ * @public
+ */
+
+exports.localsName = _DEFAULT_LOCALS_NAME;
+
+/**
+ * Promise implementation -- defaults to the native implementation if available
+ * This is mostly just for testability
+ *
+ * @type {PromiseConstructorLike}
+ * @public
+ */
+
+exports.promiseImpl = (new Function('return this;'))().Promise;
+
+/**
+ * Get the path to the included file from the parent file path and the
+ * specified path.
+ *
+ * @param {String}  name     specified path
+ * @param {String}  filename parent file path
+ * @param {Boolean} [isDir=false] whether the parent file path is a directory
+ * @return {String}
+ */
+exports.resolveInclude = function(name, filename, isDir) {
+  var dirname = path.dirname;
+  var extname = path.extname;
+  var resolve = path.resolve;
+  var includePath = resolve(isDir ? filename : dirname(filename), name);
+  var ext = extname(name);
+  if (!ext) {
+    includePath += '.ejs';
+  }
+  return includePath;
+};
+
+/**
+ * Try to resolve file path on multiple directories
+ *
+ * @param  {String}        name  specified path
+ * @param  {Array<String>} paths list of possible parent directory paths
+ * @return {String}
+ */
+function resolvePaths(name, paths) {
+  var filePath;
+  if (paths.some(function (v) {
+    filePath = exports.resolveInclude(name, v, true);
+    return fs.existsSync(filePath);
+  })) {
+    return filePath;
+  }
+}
+
+/**
+ * Get the path to the included file by Options
+ *
+ * @param  {String}  path    specified path
+ * @param  {Options} options compilation options
+ * @return {String}
+ */
+function getIncludePath(path, options) {
+  var includePath;
+  var filePath;
+  var views = options.views;
+  var match = /^[A-Za-z]+:\\|^\//.exec(path);
+
+  // Abs path
+  if (match && match.length) {
+    path = path.replace(/^\/*/, '');
+    if (Array.isArray(options.root)) {
+      includePath = resolvePaths(path, options.root);
+    } else {
+      includePath = exports.resolveInclude(path, options.root || '/', true);
+    }
+  }
+  // Relative paths
+  else {
+    // Look relative to a passed filename first
+    if (options.filename) {
+      filePath = exports.resolveInclude(path, options.filename);
+      if (fs.existsSync(filePath)) {
+        includePath = filePath;
+      }
+    }
+    // Then look in any views directories
+    if (!includePath && Array.isArray(views)) {
+      includePath = resolvePaths(path, views);
+    }
+    if (!includePath && typeof options.includer !== 'function') {
+      throw new Error('Could not find the include file "' +
+          options.escapeFunction(path) + '"');
+    }
+  }
+  return includePath;
+}
+
+/**
+ * Get the template from a string or a file, either compiled on-the-fly or
+ * read from cache (if enabled), and cache the template if needed.
+ *
+ * If `template` is not set, the file specified in `options.filename` will be
+ * read.
+ *
+ * If `options.cache` is true, this function reads the file from
+ * `options.filename` so it must be set prior to calling this function.
+ *
+ * @memberof module:ejs-internal
+ * @param {Options} options   compilation options
+ * @param {String} [template] template source
+ * @return {(TemplateFunction|ClientFunction)}
+ * Depending on the value of `options.client`, either type might be returned.
+ * @static
+ */
+
+function handleCache(options, template) {
+  var func;
+  var filename = options.filename;
+  var hasTemplate = arguments.length > 1;
+
+  if (options.cache) {
+    if (!filename) {
+      throw new Error('cache option requires a filename');
+    }
+    func = exports.cache.get(filename);
+    if (func) {
+      return func;
+    }
+    if (!hasTemplate) {
+      template = fileLoader(filename).toString().replace(_BOM, '');
+    }
+  }
+  else if (!hasTemplate) {
+    // istanbul ignore if: should not happen at all
+    if (!filename) {
+      throw new Error('Internal EJS error: no file name or template '
+                    + 'provided');
+    }
+    template = fileLoader(filename).toString().replace(_BOM, '');
+  }
+  func = exports.compile(template, options);
+  if (options.cache) {
+    exports.cache.set(filename, func);
+  }
+  return func;
+}
+
+/**
+ * Try calling handleCache with the given options and data and call the
+ * callback with the result. If an error occurs, call the callback with
+ * the error. Used by renderFile().
+ *
+ * @memberof module:ejs-internal
+ * @param {Options} options    compilation options
+ * @param {Object} data        template data
+ * @param {RenderFileCallback} cb callback
+ * @static
+ */
+
+function tryHandleCache(options, data, cb) {
+  var result;
+  if (!cb) {
+    if (typeof exports.promiseImpl == 'function') {
+      return new exports.promiseImpl(function (resolve, reject) {
+        try {
+          result = handleCache(options)(data);
+          resolve(result);
+        }
+        catch (err) {
+          reject(err);
+        }
+      });
+    }
+    else {
+      throw new Error('Please provide a callback function');
+    }
+  }
+  else {
+    try {
+      result = handleCache(options)(data);
+    }
+    catch (err) {
+      return cb(err);
+    }
+
+    cb(null, result);
+  }
+}
+
+/**
+ * fileLoader is independent
+ *
+ * @param {String} filePath ejs file path.
+ * @return {String} The contents of the specified file.
+ * @static
+ */
+
+function fileLoader(filePath){
+  return exports.fileLoader(filePath);
+}
+
+/**
+ * Get the template function.
+ *
+ * If `options.cache` is `true`, then the template is cached.
+ *
+ * @memberof module:ejs-internal
+ * @param {String}  path    path for the specified file
+ * @param {Options} options compilation options
+ * @return {(TemplateFunction|ClientFunction)}
+ * Depending on the value of `options.client`, either type might be returned
+ * @static
+ */
+
+function includeFile(path, options) {
+  var opts = utils.shallowCopy({}, options);
+  opts.filename = getIncludePath(path, opts);
+  if (typeof options.includer === 'function') {
+    var includerResult = options.includer(path, opts.filename);
+    if (includerResult) {
+      if (includerResult.filename) {
+        opts.filename = includerResult.filename;
+      }
+      if (includerResult.template) {
+        return handleCache(opts, includerResult.template);
+      }
+    }
+  }
+  return handleCache(opts);
+}
+
+/**
+ * Re-throw the given `err` in context to the `str` of ejs, `filename`, and
+ * `lineno`.
+ *
+ * @implements {RethrowCallback}
+ * @memberof module:ejs-internal
+ * @param {Error}  err      Error object
+ * @param {String} str      EJS source
+ * @param {String} flnm     file name of the EJS file
+ * @param {Number} lineno   line number of the error
+ * @param {EscapeCallback} esc
+ * @static
+ */
+
+function rethrow(err, str, flnm, lineno, esc) {
+  var lines = str.split('\n');
+  var start = Math.max(lineno - 3, 0);
+  var end = Math.min(lines.length, lineno + 3);
+  var filename = esc(flnm);
+  // Error context
+  var context = lines.slice(start, end).map(function (line, i){
+    var curr = i + start + 1;
+    return (curr == lineno ? ' >> ' : '    ')
+      + curr
+      + '| '
+      + line;
+  }).join('\n');
+
+  // Alter exception message
+  err.path = filename;
+  err.message = (filename || 'ejs') + ':'
+    + lineno + '\n'
+    + context + '\n\n'
+    + err.message;
+
+  throw err;
+}
+
+function stripSemi(str){
+  return str.replace(/;(\s*$)/, '$1');
+}
+
+/**
+ * Compile the given `str` of ejs into a template function.
+ *
+ * @param {String}  template EJS template
+ *
+ * @param {Options} [opts] compilation options
+ *
+ * @return {(TemplateFunction|ClientFunction)}
+ * Depending on the value of `opts.client`, either type might be returned.
+ * Note that the return type of the function also depends on the value of `opts.async`.
+ * @public
+ */
+
+exports.compile = function compile(template, opts) {
+  var templ;
+
+  // v1 compat
+  // 'scope' is 'context'
+  // FIXME: Remove this in a future version
+  if (opts && opts.scope) {
+    if (!scopeOptionWarned){
+      console.warn('`scope` option is deprecated and will be removed in EJS 3');
+      scopeOptionWarned = true;
+    }
+    if (!opts.context) {
+      opts.context = opts.scope;
+    }
+    delete opts.scope;
+  }
+  templ = new Template(template, opts);
+  return templ.compile();
+};
+
+/**
+ * Render the given `template` of ejs.
+ *
+ * If you would like to include options but not data, you need to explicitly
+ * call this function with `data` being an empty object or `null`.
+ *
+ * @param {String}   template EJS template
+ * @param {Object}  [data={}] template data
+ * @param {Options} [opts={}] compilation and rendering options
+ * @return {(String|Promise<String>)}
+ * Return value type depends on `opts.async`.
+ * @public
+ */
+
+exports.render = function (template, d, o) {
+  var data = d || {};
+  var opts = o || {};
+
+  // No options object -- if there are optiony names
+  // in the data, copy them to options
+  if (arguments.length == 2) {
+    utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA);
+  }
+
+  return handleCache(opts, template)(data);
+};
+
+/**
+ * Render an EJS file at the given `path` and callback `cb(err, str)`.
+ *
+ * If you would like to include options but not data, you need to explicitly
+ * call this function with `data` being an empty object or `null`.
+ *
+ * @param {String}             path     path to the EJS file
+ * @param {Object}            [data={}] template data
+ * @param {Options}           [opts={}] compilation and rendering options
+ * @param {RenderFileCallback} cb callback
+ * @public
+ */
+
+exports.renderFile = function () {
+  var args = Array.prototype.slice.call(arguments);
+  var filename = args.shift();
+  var cb;
+  var opts = {filename: filename};
+  var data;
+  var viewOpts;
+
+  // Do we have a callback?
+  if (typeof arguments[arguments.length - 1] == 'function') {
+    cb = args.pop();
+  }
+  // Do we have data/opts?
+  if (args.length) {
+    // Should always have data obj
+    data = args.shift();
+    // Normal passed opts (data obj + opts obj)
+    if (args.length) {
+      // Use shallowCopy so we don't pollute passed in opts obj with new vals
+      utils.shallowCopy(opts, args.pop());
+    }
+    // Special casing for Express (settings + opts-in-data)
+    else {
+      // Express 3 and 4
+      if (data.settings) {
+        // Pull a few things from known locations
+        if (data.settings.views) {
+          opts.views = data.settings.views;
+        }
+        if (data.settings['view cache']) {
+          opts.cache = true;
+        }
+        // Undocumented after Express 2, but still usable, esp. for
+        // items that are unsafe to be passed along with data, like `root`
+        viewOpts = data.settings['view options'];
+        if (viewOpts) {
+          utils.shallowCopy(opts, viewOpts);
+        }
+      }
+      // Express 2 and lower, values set in app.locals, or people who just
+      // want to pass options in their data. NOTE: These values will override
+      // anything previously set in settings  or settings['view options']
+      utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA_EXPRESS);
+    }
+    opts.filename = filename;
+  }
+  else {
+    data = {};
+  }
+
+  return tryHandleCache(opts, data, cb);
+};
+
+/**
+ * Clear intermediate JavaScript cache. Calls {@link Cache#reset}.
+ * @public
+ */
+
+/**
+ * EJS template class
+ * @public
+ */
+exports.Template = Template;
+
+exports.clearCache = function () {
+  exports.cache.reset();
+};
+
+function Template(text, opts) {
+  opts = opts || {};
+  var options = {};
+  this.templateText = text;
+  /** @type {string | null} */
+  this.mode = null;
+  this.truncate = false;
+  this.currentLine = 1;
+  this.source = '';
+  options.client = opts.client || false;
+  options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML;
+  options.compileDebug = opts.compileDebug !== false;
+  options.debug = !!opts.debug;
+  options.filename = opts.filename;
+  options.openDelimiter = opts.openDelimiter || exports.openDelimiter || _DEFAULT_OPEN_DELIMITER;
+  options.closeDelimiter = opts.closeDelimiter || exports.closeDelimiter || _DEFAULT_CLOSE_DELIMITER;
+  options.delimiter = opts.delimiter || exports.delimiter || _DEFAULT_DELIMITER;
+  options.strict = opts.strict || false;
+  options.context = opts.context;
+  options.cache = opts.cache || false;
+  options.rmWhitespace = opts.rmWhitespace;
+  options.root = opts.root;
+  options.includer = opts.includer;
+  options.outputFunctionName = opts.outputFunctionName;
+  options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME;
+  options.views = opts.views;
+  options.async = opts.async;
+  options.destructuredLocals = opts.destructuredLocals;
+  options.legacyInclude = typeof opts.legacyInclude != 'undefined' ? !!opts.legacyInclude : true;
+
+  if (options.strict) {
+    options._with = false;
+  }
+  else {
+    options._with = typeof opts._with != 'undefined' ? opts._with : true;
+  }
+
+  this.opts = options;
+
+  this.regex = this.createRegex();
+}
+
+Template.modes = {
+  EVAL: 'eval',
+  ESCAPED: 'escaped',
+  RAW: 'raw',
+  COMMENT: 'comment',
+  LITERAL: 'literal'
+};
+
+Template.prototype = {
+  createRegex: function () {
+    var str = _REGEX_STRING;
+    var delim = utils.escapeRegExpChars(this.opts.delimiter);
+    var open = utils.escapeRegExpChars(this.opts.openDelimiter);
+    var close = utils.escapeRegExpChars(this.opts.closeDelimiter);
+    str = str.replace(/%/g, delim)
+      .replace(/</g, open)
+      .replace(/>/g, close);
+    return new RegExp(str);
+  },
+
+  compile: function () {
+    /** @type {string} */
+    var src;
+    /** @type {ClientFunction} */
+    var fn;
+    var opts = this.opts;
+    var prepended = '';
+    var appended = '';
+    /** @type {EscapeCallback} */
+    var escapeFn = opts.escapeFunction;
+    /** @type {FunctionConstructor} */
+    var ctor;
+    /** @type {string} */
+    var sanitizedFilename = opts.filename ? JSON.stringify(opts.filename) : 'undefined';
+
+    if (!this.source) {
+      this.generateSource();
+      prepended +=
+        '  var __output = "";\n' +
+        '  function __append(s) { if (s !== undefined && s !== null) __output += s }\n';
+      if (opts.outputFunctionName) {
+        prepended += '  var ' + opts.outputFunctionName + ' = __append;' + '\n';
+      }
+      if (opts.destructuredLocals && opts.destructuredLocals.length) {
+        var destructuring = '  var __locals = (' + opts.localsName + ' || {}),\n';
+        for (var i = 0; i < opts.destructuredLocals.length; i++) {
+          var name = opts.destructuredLocals[i];
+          if (i > 0) {
+            destructuring += ',\n  ';
+          }
+          destructuring += name + ' = __locals.' + name;
+        }
+        prepended += destructuring + ';\n';
+      }
+      if (opts._with !== false) {
+        prepended +=  '  with (' + opts.localsName + ' || {}) {' + '\n';
+        appended += '  }' + '\n';
+      }
+      appended += '  return __output;' + '\n';
+      this.source = prepended + this.source + appended;
+    }
+
+    if (opts.compileDebug) {
+      src = 'var __line = 1' + '\n'
+        + '  , __lines = ' + JSON.stringify(this.templateText) + '\n'
+        + '  , __filename = ' + sanitizedFilename + ';' + '\n'
+        + 'try {' + '\n'
+        + this.source
+        + '} catch (e) {' + '\n'
+        + '  rethrow(e, __lines, __filename, __line, escapeFn);' + '\n'
+        + '}' + '\n';
+    }
+    else {
+      src = this.source;
+    }
+
+    if (opts.client) {
+      src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src;
+      if (opts.compileDebug) {
+        src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src;
+      }
+    }
+
+    if (opts.strict) {
+      src = '"use strict";\n' + src;
+    }
+    if (opts.debug) {
+      console.log(src);
+    }
+    if (opts.compileDebug && opts.filename) {
+      src = src + '\n'
+        + '//# sourceURL=' + sanitizedFilename + '\n';
+    }
+
+    try {
+      if (opts.async) {
+        // Have to use generated function for this, since in envs without support,
+        // it breaks in parsing
+        try {
+          ctor = (new Function('return (async function(){}).constructor;'))();
+        }
+        catch(e) {
+          if (e instanceof SyntaxError) {
+            throw new Error('This environment does not support async/await');
+          }
+          else {
+            throw e;
+          }
+        }
+      }
+      else {
+        ctor = Function;
+      }
+      fn = new ctor(opts.localsName + ', escapeFn, include, rethrow', src);
+    }
+    catch(e) {
+      // istanbul ignore else
+      if (e instanceof SyntaxError) {
+        if (opts.filename) {
+          e.message += ' in ' + opts.filename;
+        }
+        e.message += ' while compiling ejs\n\n';
+        e.message += 'If the above error is not helpful, you may want to try EJS-Lint:\n';
+        e.message += 'https://github.com/RyanZim/EJS-Lint';
+        if (!opts.async) {
+          e.message += '\n';
+          e.message += 'Or, if you meant to create an async function, pass `async: true` as an option.';
+        }
+      }
+      throw e;
+    }
+
+    // Return a callable function which will execute the function
+    // created by the source-code, with the passed data as locals
+    // Adds a local `include` function which allows full recursive include
+    var returnedFn = opts.client ? fn : function anonymous(data) {
+      var include = function (path, includeData) {
+        var d = utils.shallowCopy({}, data);
+        if (includeData) {
+          d = utils.shallowCopy(d, includeData);
+        }
+        return includeFile(path, opts)(d);
+      };
+      return fn.apply(opts.context, [data || {}, escapeFn, include, rethrow]);
+    };
+    if (opts.filename && typeof Object.defineProperty === 'function') {
+      var filename = opts.filename;
+      var basename = path.basename(filename, path.extname(filename));
+      try {
+        Object.defineProperty(returnedFn, 'name', {
+          value: basename,
+          writable: false,
+          enumerable: false,
+          configurable: true
+        });
+      } catch (e) {/* ignore */}
+    }
+    return returnedFn;
+  },
+
+  generateSource: function () {
+    var opts = this.opts;
+
+    if (opts.rmWhitespace) {
+      // Have to use two separate replace here as `^` and `$` operators don't
+      // work well with `\r` and empty lines don't work well with the `m` flag.
+      this.templateText =
+        this.templateText.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, '');
+    }
+
+    // Slurp spaces and tabs before <%_ and after _%>
+    this.templateText =
+      this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>');
+
+    var self = this;
+    var matches = this.parseTemplateText();
+    var d = this.opts.delimiter;
+    var o = this.opts.openDelimiter;
+    var c = this.opts.closeDelimiter;
+
+    if (matches && matches.length) {
+      matches.forEach(function (line, index) {
+        var closing;
+        // If this is an opening tag, check for closing tags
+        // FIXME: May end up with some false positives here
+        // Better to store modes as k/v with openDelimiter + delimiter as key
+        // Then this can simply check against the map
+        if ( line.indexOf(o + d) === 0        // If it is a tag
+          && line.indexOf(o + d + d) !== 0) { // and is not escaped
+          closing = matches[index + 2];
+          if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) {
+            throw new Error('Could not find matching close tag for "' + line + '".');
+          }
+        }
+        self.scanLine(line);
+      });
+    }
+
+  },
+
+  parseTemplateText: function () {
+    var str = this.templateText;
+    var pat = this.regex;
+    var result = pat.exec(str);
+    var arr = [];
+    var firstPos;
+
+    while (result) {
+      firstPos = result.index;
+
+      if (firstPos !== 0) {
+        arr.push(str.substring(0, firstPos));
+        str = str.slice(firstPos);
+      }
+
+      arr.push(result[0]);
+      str = str.slice(result[0].length);
+      result = pat.exec(str);
+    }
+
+    if (str) {
+      arr.push(str);
+    }
+
+    return arr;
+  },
+
+  _addOutput: function (line) {
+    if (this.truncate) {
+      // Only replace single leading linebreak in the line after
+      // -%> tag -- this is the single, trailing linebreak
+      // after the tag that the truncation mode replaces
+      // Handle Win / Unix / old Mac linebreaks -- do the \r\n
+      // combo first in the regex-or
+      line = line.replace(/^(?:\r\n|\r|\n)/, '');
+      this.truncate = false;
+    }
+    if (!line) {
+      return line;
+    }
+
+    // Preserve literal slashes
+    line = line.replace(/\\/g, '\\\\');
+
+    // Convert linebreaks
+    line = line.replace(/\n/g, '\\n');
+    line = line.replace(/\r/g, '\\r');
+
+    // Escape double-quotes
+    // - this will be the delimiter during execution
+    line = line.replace(/"/g, '\\"');
+    this.source += '    ; __append("' + line + '")' + '\n';
+  },
+
+  scanLine: function (line) {
+    var self = this;
+    var d = this.opts.delimiter;
+    var o = this.opts.openDelimiter;
+    var c = this.opts.closeDelimiter;
+    var newLineCount = 0;
+
+    newLineCount = (line.split('\n').length - 1);
+
+    switch (line) {
+    case o + d:
+    case o + d + '_':
+      this.mode = Template.modes.EVAL;
+      break;
+    case o + d + '=':
+      this.mode = Template.modes.ESCAPED;
+      break;
+    case o + d + '-':
+      this.mode = Template.modes.RAW;
+      break;
+    case o + d + '#':
+      this.mode = Template.modes.COMMENT;
+      break;
+    case o + d + d:
+      this.mode = Template.modes.LITERAL;
+      this.source += '    ; __append("' + line.replace(o + d + d, o + d) + '")' + '\n';
+      break;
+    case d + d + c:
+      this.mode = Template.modes.LITERAL;
+      this.source += '    ; __append("' + line.replace(d + d + c, d + c) + '")' + '\n';
+      break;
+    case d + c:
+    case '-' + d + c:
+    case '_' + d + c:
+      if (this.mode == Template.modes.LITERAL) {
+        this._addOutput(line);
+      }
+
+      this.mode = null;
+      this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0;
+      break;
+    default:
+      // In script mode, depends on type of tag
+      if (this.mode) {
+        // If '//' is found without a line break, add a line break.
+        switch (this.mode) {
+        case Template.modes.EVAL:
+        case Template.modes.ESCAPED:
+        case Template.modes.RAW:
+          if (line.lastIndexOf('//') > line.lastIndexOf('\n')) {
+            line += '\n';
+          }
+        }
+        switch (this.mode) {
+        // Just executing code
+        case Template.modes.EVAL:
+          this.source += '    ; ' + line + '\n';
+          break;
+          // Exec, esc, and output
+        case Template.modes.ESCAPED:
+          this.source += '    ; __append(escapeFn(' + stripSemi(line) + '))' + '\n';
+          break;
+          // Exec and output
+        case Template.modes.RAW:
+          this.source += '    ; __append(' + stripSemi(line) + ')' + '\n';
+          break;
+        case Template.modes.COMMENT:
+          // Do nothing
+          break;
+          // Literal <%% mode, append as raw output
+        case Template.modes.LITERAL:
+          this._addOutput(line);
+          break;
+        }
+      }
+      // In string mode, just add the output
+      else {
+        this._addOutput(line);
+      }
+    }
+
+    if (self.opts.compileDebug && newLineCount) {
+      this.currentLine += newLineCount;
+      this.source += '    ; __line = ' + this.currentLine + '\n';
+    }
+  }
+};
+
+/**
+ * Escape characters reserved in XML.
+ *
+ * This is simply an export of {@link module:utils.escapeXML}.
+ *
+ * If `markup` is `undefined` or `null`, the empty string is returned.
+ *
+ * @param {String} markup Input string
+ * @return {String} Escaped string
+ * @public
+ * @func
+ * */
+exports.escapeXML = utils.escapeXML;
+
+/**
+ * Express.js support.
+ *
+ * This is an alias for {@link module:ejs.renderFile}, in order to support
+ * Express.js out-of-the-box.
+ *
+ * @func
+ */
+
+exports.__express = exports.renderFile;
+
+/**
+ * Version of EJS.
+ *
+ * @readonly
+ * @type {String}
+ * @public
+ */
+
+exports.VERSION = _VERSION_STRING;
+
+/**
+ * Name for detection of EJS.
+ *
+ * @readonly
+ * @type {String}
+ * @public
+ */
+
+exports.name = _NAME;
+
+/* istanbul ignore if */
+if (typeof window != 'undefined') {
+  window.ejs = exports;
+}
+
+},{"../package.json":6,"./utils":2,"fs":3,"path":4}],2:[function(require,module,exports){
+/*
+ * EJS Embedded JavaScript templates
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/**
+ * Private utility functions
+ * @module utils
+ * @private
+ */
+
+'use strict';
+
+var regExpChars = /[|\\{}()[\]^$+*?.]/g;
+
+/**
+ * Escape characters reserved in regular expressions.
+ *
+ * If `string` is `undefined` or `null`, the empty string is returned.
+ *
+ * @param {String} string Input string
+ * @return {String} Escaped string
+ * @static
+ * @private
+ */
+exports.escapeRegExpChars = function (string) {
+  // istanbul ignore if
+  if (!string) {
+    return '';
+  }
+  return String(string).replace(regExpChars, '\\$&');
+};
+
+var _ENCODE_HTML_RULES = {
+  '&': '&amp;',
+  '<': '&lt;',
+  '>': '&gt;',
+  '"': '&#34;',
+  "'": '&#39;'
+};
+var _MATCH_HTML = /[&<>'"]/g;
+
+function encode_char(c) {
+  return _ENCODE_HTML_RULES[c] || c;
+}
+
+/**
+ * Stringified version of constants used by {@link module:utils.escapeXML}.
+ *
+ * It is used in the process of generating {@link ClientFunction}s.
+ *
+ * @readonly
+ * @type {String}
+ */
+
+var escapeFuncStr =
+  'var _ENCODE_HTML_RULES = {\n'
++ '      "&": "&amp;"\n'
++ '    , "<": "&lt;"\n'
++ '    , ">": "&gt;"\n'
++ '    , \'"\': "&#34;"\n'
++ '    , "\'": "&#39;"\n'
++ '    }\n'
++ '  , _MATCH_HTML = /[&<>\'"]/g;\n'
++ 'function encode_char(c) {\n'
++ '  return _ENCODE_HTML_RULES[c] || c;\n'
++ '};\n';
+
+/**
+ * Escape characters reserved in XML.
+ *
+ * If `markup` is `undefined` or `null`, the empty string is returned.
+ *
+ * @implements {EscapeCallback}
+ * @param {String} markup Input string
+ * @return {String} Escaped string
+ * @static
+ * @private
+ */
+
+exports.escapeXML = function (markup) {
+  return markup == undefined
+    ? ''
+    : String(markup)
+      .replace(_MATCH_HTML, encode_char);
+};
+exports.escapeXML.toString = function () {
+  return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr;
+};
+
+/**
+ * Naive copy of properties from one object to another.
+ * Does not recurse into non-scalar properties
+ * Does not check to see if the property has a value before copying
+ *
+ * @param  {Object} to   Destination object
+ * @param  {Object} from Source object
+ * @return {Object}      Destination object
+ * @static
+ * @private
+ */
+exports.shallowCopy = function (to, from) {
+  from = from || {};
+  for (var p in from) {
+    to[p] = from[p];
+  }
+  return to;
+};
+
+/**
+ * Naive copy of a list of key names, from one object to another.
+ * Only copies property if it is actually defined
+ * Does not recurse into non-scalar properties
+ *
+ * @param  {Object} to   Destination object
+ * @param  {Object} from Source object
+ * @param  {Array} list List of properties to copy
+ * @return {Object}      Destination object
+ * @static
+ * @private
+ */
+exports.shallowCopyFromList = function (to, from, list) {
+  for (var i = 0; i < list.length; i++) {
+    var p = list[i];
+    if (typeof from[p] != 'undefined') {
+      to[p] = from[p];
+    }
+  }
+  return to;
+};
+
+/**
+ * Simple in-process cache implementation. Does not implement limits of any
+ * sort.
+ *
+ * @implements {Cache}
+ * @static
+ * @private
+ */
+exports.cache = {
+  _data: {},
+  set: function (key, val) {
+    this._data[key] = val;
+  },
+  get: function (key) {
+    return this._data[key];
+  },
+  remove: function (key) {
+    delete this._data[key];
+  },
+  reset: function () {
+    this._data = {};
+  }
+};
+
+/**
+ * Transforms hyphen case variable into camel case.
+ *
+ * @param {String} string Hyphen case string
+ * @return {String} Camel case string
+ * @static
+ * @private
+ */
+exports.hyphenToCamel = function (str) {
+  return str.replace(/-[a-z]/g, function (match) { return match[1].toUpperCase(); });
+};
+
+},{}],3:[function(require,module,exports){
+
+},{}],4:[function(require,module,exports){
+(function (process){
+// .dirname, .basename, and .extname methods are extracted from Node.js v8.11.1,
+// backported and transplited with Babel, with backwards-compat fixes
+
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// resolves . and .. elements in a path array with directory names there
+// must be no slashes, empty elements, or device names (c:\) in the array
+// (so also no leading and trailing slashes - it does not distinguish
+// relative and absolute paths)
+function normalizeArray(parts, allowAboveRoot) {
+  // if the path tries to go above the root, `up` ends up > 0
+  var up = 0;
+  for (var i = parts.length - 1; i >= 0; i--) {
+    var last = parts[i];
+    if (last === '.') {
+      parts.splice(i, 1);
+    } else if (last === '..') {
+      parts.splice(i, 1);
+      up++;
+    } else if (up) {
+      parts.splice(i, 1);
+      up--;
+    }
+  }
+
+  // if the path is allowed to go above the root, restore leading ..s
+  if (allowAboveRoot) {
+    for (; up--; up) {
+      parts.unshift('..');
+    }
+  }
+
+  return parts;
+}
+
+// path.resolve([from ...], to)
+// posix version
+exports.resolve = function() {
+  var resolvedPath = '',
+      resolvedAbsolute = false;
+
+  for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
+    var path = (i >= 0) ? arguments[i] : process.cwd();
+
+    // Skip empty and invalid entries
+    if (typeof path !== 'string') {
+      throw new TypeError('Arguments to path.resolve must be strings');
+    } else if (!path) {
+      continue;
+    }
+
+    resolvedPath = path + '/' + resolvedPath;
+    resolvedAbsolute = path.charAt(0) === '/';
+  }
+
+  // At this point the path should be resolved to a full absolute path, but
+  // handle relative paths to be safe (might happen when process.cwd() fails)
+
+  // Normalize the path
+  resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
+    return !!p;
+  }), !resolvedAbsolute).join('/');
+
+  return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
+};
+
+// path.normalize(path)
+// posix version
+exports.normalize = function(path) {
+  var isAbsolute = exports.isAbsolute(path),
+      trailingSlash = substr(path, -1) === '/';
+
+  // Normalize the path
+  path = normalizeArray(filter(path.split('/'), function(p) {
+    return !!p;
+  }), !isAbsolute).join('/');
+
+  if (!path && !isAbsolute) {
+    path = '.';
+  }
+  if (path && trailingSlash) {
+    path += '/';
+  }
+
+  return (isAbsolute ? '/' : '') + path;
+};
+
+// posix version
+exports.isAbsolute = function(path) {
+  return path.charAt(0) === '/';
+};
+
+// posix version
+exports.join = function() {
+  var paths = Array.prototype.slice.call(arguments, 0);
+  return exports.normalize(filter(paths, function(p, index) {
+    if (typeof p !== 'string') {
+      throw new TypeError('Arguments to path.join must be strings');
+    }
+    return p;
+  }).join('/'));
+};
+
+
+// path.relative(from, to)
+// posix version
+exports.relative = function(from, to) {
+  from = exports.resolve(from).substr(1);
+  to = exports.resolve(to).substr(1);
+
+  function trim(arr) {
+    var start = 0;
+    for (; start < arr.length; start++) {
+      if (arr[start] !== '') break;
+    }
+
+    var end = arr.length - 1;
+    for (; end >= 0; end--) {
+      if (arr[end] !== '') break;
+    }
+
+    if (start > end) return [];
+    return arr.slice(start, end - start + 1);
+  }
+
+  var fromParts = trim(from.split('/'));
+  var toParts = trim(to.split('/'));
+
+  var length = Math.min(fromParts.length, toParts.length);
+  var samePartsLength = length;
+  for (var i = 0; i < length; i++) {
+    if (fromParts[i] !== toParts[i]) {
+      samePartsLength = i;
+      break;
+    }
+  }
+
+  var outputParts = [];
+  for (var i = samePartsLength; i < fromParts.length; i++) {
+    outputParts.push('..');
+  }
+
+  outputParts = outputParts.concat(toParts.slice(samePartsLength));
+
+  return outputParts.join('/');
+};
+
+exports.sep = '/';
+exports.delimiter = ':';
+
+exports.dirname = function (path) {
+  if (typeof path !== 'string') path = path + '';
+  if (path.length === 0) return '.';
+  var code = path.charCodeAt(0);
+  var hasRoot = code === 47 /*/*/;
+  var end = -1;
+  var matchedSlash = true;
+  for (var i = path.length - 1; i >= 1; --i) {
+    code = path.charCodeAt(i);
+    if (code === 47 /*/*/) {
+        if (!matchedSlash) {
+          end = i;
+          break;
+        }
+      } else {
+      // We saw the first non-path separator
+      matchedSlash = false;
+    }
+  }
+
+  if (end === -1) return hasRoot ? '/' : '.';
+  if (hasRoot && end === 1) {
+    // return '//';
+    // Backwards-compat fix:
+    return '/';
+  }
+  return path.slice(0, end);
+};
+
+function basename(path) {
+  if (typeof path !== 'string') path = path + '';
+
+  var start = 0;
+  var end = -1;
+  var matchedSlash = true;
+  var i;
+
+  for (i = path.length - 1; i >= 0; --i) {
+    if (path.charCodeAt(i) === 47 /*/*/) {
+        // If we reached a path separator that was not part of a set of path
+        // separators at the end of the string, stop now
+        if (!matchedSlash) {
+          start = i + 1;
+          break;
+        }
+      } else if (end === -1) {
+      // We saw the first non-path separator, mark this as the end of our
+      // path component
+      matchedSlash = false;
+      end = i + 1;
+    }
+  }
+
+  if (end === -1) return '';
+  return path.slice(start, end);
+}
+
+// Uses a mixed approach for backwards-compatibility, as ext behavior changed
+// in new Node.js versions, so only basename() above is backported here
+exports.basename = function (path, ext) {
+  var f = basename(path);
+  if (ext && f.substr(-1 * ext.length) === ext) {
+    f = f.substr(0, f.length - ext.length);
+  }
+  return f;
+};
+
+exports.extname = function (path) {
+  if (typeof path !== 'string') path = path + '';
+  var startDot = -1;
+  var startPart = 0;
+  var end = -1;
+  var matchedSlash = true;
+  // Track the state of characters (if any) we see before our first dot and
+  // after any path separator we find
+  var preDotState = 0;
+  for (var i = path.length - 1; i >= 0; --i) {
+    var code = path.charCodeAt(i);
+    if (code === 47 /*/*/) {
+        // If we reached a path separator that was not part of a set of path
+        // separators at the end of the string, stop now
+        if (!matchedSlash) {
+          startPart = i + 1;
+          break;
+        }
+        continue;
+      }
+    if (end === -1) {
+      // We saw the first non-path separator, mark this as the end of our
+      // extension
+      matchedSlash = false;
+      end = i + 1;
+    }
+    if (code === 46 /*.*/) {
+        // If this is our first dot, mark it as the start of our extension
+        if (startDot === -1)
+          startDot = i;
+        else if (preDotState !== 1)
+          preDotState = 1;
+    } else if (startDot !== -1) {
+      // We saw a non-dot and non-path separator before our dot, so we should
+      // have a good chance at having a non-empty extension
+      preDotState = -1;
+    }
+  }
+
+  if (startDot === -1 || end === -1 ||
+      // We saw a non-dot character immediately before the dot
+      preDotState === 0 ||
+      // The (right-most) trimmed path component is exactly '..'
+      preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
+    return '';
+  }
+  return path.slice(startDot, end);
+};
+
+function filter (xs, f) {
+    if (xs.filter) return xs.filter(f);
+    var res = [];
+    for (var i = 0; i < xs.length; i++) {
+        if (f(xs[i], i, xs)) res.push(xs[i]);
+    }
+    return res;
+}
+
+// String.prototype.substr - negative index don't work in IE8
+var substr = 'ab'.substr(-1) === 'b'
+    ? function (str, start, len) { return str.substr(start, len) }
+    : function (str, start, len) {
+        if (start < 0) start = str.length + start;
+        return str.substr(start, len);
+    }
+;
+
+}).call(this,require('_process'))
+},{"_process":5}],5:[function(require,module,exports){
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things.  But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals.  It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+function defaultSetTimout() {
+    throw new Error('setTimeout has not been defined');
+}
+function defaultClearTimeout () {
+    throw new Error('clearTimeout has not been defined');
+}
+(function () {
+    try {
+        if (typeof setTimeout === 'function') {
+            cachedSetTimeout = setTimeout;
+        } else {
+            cachedSetTimeout = defaultSetTimout;
+        }
+    } catch (e) {
+        cachedSetTimeout = defaultSetTimout;
+    }
+    try {
+        if (typeof clearTimeout === 'function') {
+            cachedClearTimeout = clearTimeout;
+        } else {
+            cachedClearTimeout = defaultClearTimeout;
+        }
+    } catch (e) {
+        cachedClearTimeout = defaultClearTimeout;
+    }
+} ())
+function runTimeout(fun) {
+    if (cachedSetTimeout === setTimeout) {
+        //normal enviroments in sane situations
+        return setTimeout(fun, 0);
+    }
+    // if setTimeout wasn't available but was latter defined
+    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
+        cachedSetTimeout = setTimeout;
+        return setTimeout(fun, 0);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedSetTimeout(fun, 0);
+    } catch(e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
+            return cachedSetTimeout.call(null, fun, 0);
+        } catch(e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
+            return cachedSetTimeout.call(this, fun, 0);
+        }
+    }
+
+
+}
+function runClearTimeout(marker) {
+    if (cachedClearTimeout === clearTimeout) {
+        //normal enviroments in sane situations
+        return clearTimeout(marker);
+    }
+    // if clearTimeout wasn't available but was latter defined
+    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
+        cachedClearTimeout = clearTimeout;
+        return clearTimeout(marker);
+    }
+    try {
+        // when when somebody has screwed with setTimeout but no I.E. maddness
+        return cachedClearTimeout(marker);
+    } catch (e){
+        try {
+            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
+            return cachedClearTimeout.call(null, marker);
+        } catch (e){
+            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
+            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
+            return cachedClearTimeout.call(this, marker);
+        }
+    }
+
+
+
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+    if (!draining || !currentQueue) {
+        return;
+    }
+    draining = false;
+    if (currentQueue.length) {
+        queue = currentQueue.concat(queue);
+    } else {
+        queueIndex = -1;
+    }
+    if (queue.length) {
+        drainQueue();
+    }
+}
+
+function drainQueue() {
+    if (draining) {
+        return;
+    }
+    var timeout = runTimeout(cleanUpNextTick);
+    draining = true;
+
+    var len = queue.length;
+    while(len) {
+        currentQueue = queue;
+        queue = [];
+        while (++queueIndex < len) {
+            if (currentQueue) {
+                currentQueue[queueIndex].run();
+            }
+        }
+        queueIndex = -1;
+        len = queue.length;
+    }
+    currentQueue = null;
+    draining = false;
+    runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+    var args = new Array(arguments.length - 1);
+    if (arguments.length > 1) {
+        for (var i = 1; i < arguments.length; i++) {
+            args[i - 1] = arguments[i];
+        }
+    }
+    queue.push(new Item(fun, args));
+    if (queue.length === 1 && !draining) {
+        runTimeout(drainQueue);
+    }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+    this.fun = fun;
+    this.array = array;
+}
+Item.prototype.run = function () {
+    this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+process.prependListener = noop;
+process.prependOnceListener = noop;
+
+process.listeners = function (name) { return [] }
+
+process.binding = function (name) {
+    throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+    throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],6:[function(require,module,exports){
+module.exports={
+  "name": "ejs",
+  "description": "Embedded JavaScript templates",
+  "keywords": [
+    "template",
+    "engine",
+    "ejs"
+  ],
+  "version": "3.1.6",
+  "author": "Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)",
+  "license": "Apache-2.0",
+  "bin": {
+    "ejs": "./bin/cli.js"
+  },
+  "main": "./lib/ejs.js",
+  "jsdelivr": "ejs.min.js",
+  "unpkg": "ejs.min.js",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/mde/ejs.git"
+  },
+  "bugs": "https://github.com/mde/ejs/issues",
+  "homepage": "https://github.com/mde/ejs",
+  "dependencies": {
+    "jake": "^10.6.1"
+  },
+  "devDependencies": {
+    "browserify": "^16.5.1",
+    "eslint": "^6.8.0",
+    "git-directory-deploy": "^1.5.1",
+    "jsdoc": "^3.6.4",
+    "lru-cache": "^4.0.1",
+    "mocha": "^7.1.1",
+    "uglify-js": "^3.3.16"
+  },
+  "engines": {
+    "node": ">=0.10.0"
+  },
+  "scripts": {
+    "test": "mocha"
+  }
+}
+
+},{}]},{},[1])(1)
+});
diff --git a/d2d_app/node_modules/ejs/ejs.min.js b/d2d_app/node_modules/ejs/ejs.min.js
new file mode 100644 (file)
index 0000000..e40628c
--- /dev/null
@@ -0,0 +1 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ejs=f()}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r}()({1:[function(require,module,exports){"use strict";var fs=require("fs");var path=require("path");var utils=require("./utils");var scopeOptionWarned=false;var _VERSION_STRING=require("../package.json").version;var _DEFAULT_OPEN_DELIMITER="<";var _DEFAULT_CLOSE_DELIMITER=">";var _DEFAULT_DELIMITER="%";var _DEFAULT_LOCALS_NAME="locals";var _NAME="ejs";var _REGEX_STRING="(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)";var _OPTS_PASSABLE_WITH_DATA=["delimiter","scope","context","debug","compileDebug","client","_with","rmWhitespace","strict","filename","async"];var _OPTS_PASSABLE_WITH_DATA_EXPRESS=_OPTS_PASSABLE_WITH_DATA.concat("cache");var _BOM=/^\uFEFF/;exports.cache=utils.cache;exports.fileLoader=fs.readFileSync;exports.localsName=_DEFAULT_LOCALS_NAME;exports.promiseImpl=new Function("return this;")().Promise;exports.resolveInclude=function(name,filename,isDir){var dirname=path.dirname;var extname=path.extname;var resolve=path.resolve;var includePath=resolve(isDir?filename:dirname(filename),name);var ext=extname(name);if(!ext){includePath+=".ejs"}return includePath};function resolvePaths(name,paths){var filePath;if(paths.some(function(v){filePath=exports.resolveInclude(name,v,true);return fs.existsSync(filePath)})){return filePath}}function getIncludePath(path,options){var includePath;var filePath;var views=options.views;var match=/^[A-Za-z]+:\\|^\//.exec(path);if(match&&match.length){path=path.replace(/^\/*/,"");if(Array.isArray(options.root)){includePath=resolvePaths(path,options.root)}else{includePath=exports.resolveInclude(path,options.root||"/",true)}}else{if(options.filename){filePath=exports.resolveInclude(path,options.filename);if(fs.existsSync(filePath)){includePath=filePath}}if(!includePath&&Array.isArray(views)){includePath=resolvePaths(path,views)}if(!includePath&&typeof options.includer!=="function"){throw new Error('Could not find the include file "'+options.escapeFunction(path)+'"')}}return includePath}function handleCache(options,template){var func;var filename=options.filename;var hasTemplate=arguments.length>1;if(options.cache){if(!filename){throw new Error("cache option requires a filename")}func=exports.cache.get(filename);if(func){return func}if(!hasTemplate){template=fileLoader(filename).toString().replace(_BOM,"")}}else if(!hasTemplate){if(!filename){throw new Error("Internal EJS error: no file name or template "+"provided")}template=fileLoader(filename).toString().replace(_BOM,"")}func=exports.compile(template,options);if(options.cache){exports.cache.set(filename,func)}return func}function tryHandleCache(options,data,cb){var result;if(!cb){if(typeof exports.promiseImpl=="function"){return new exports.promiseImpl(function(resolve,reject){try{result=handleCache(options)(data);resolve(result)}catch(err){reject(err)}})}else{throw new Error("Please provide a callback function")}}else{try{result=handleCache(options)(data)}catch(err){return cb(err)}cb(null,result)}}function fileLoader(filePath){return exports.fileLoader(filePath)}function includeFile(path,options){var opts=utils.shallowCopy({},options);opts.filename=getIncludePath(path,opts);if(typeof options.includer==="function"){var includerResult=options.includer(path,opts.filename);if(includerResult){if(includerResult.filename){opts.filename=includerResult.filename}if(includerResult.template){return handleCache(opts,includerResult.template)}}}return handleCache(opts)}function rethrow(err,str,flnm,lineno,esc){var lines=str.split("\n");var start=Math.max(lineno-3,0);var end=Math.min(lines.length,lineno+3);var filename=esc(flnm);var context=lines.slice(start,end).map(function(line,i){var curr=i+start+1;return(curr==lineno?" >> ":"    ")+curr+"| "+line}).join("\n");err.path=filename;err.message=(filename||"ejs")+":"+lineno+"\n"+context+"\n\n"+err.message;throw err}function stripSemi(str){return str.replace(/;(\s*$)/,"$1")}exports.compile=function compile(template,opts){var templ;if(opts&&opts.scope){if(!scopeOptionWarned){console.warn("`scope` option is deprecated and will be removed in EJS 3");scopeOptionWarned=true}if(!opts.context){opts.context=opts.scope}delete opts.scope}templ=new Template(template,opts);return templ.compile()};exports.render=function(template,d,o){var data=d||{};var opts=o||{};if(arguments.length==2){utils.shallowCopyFromList(opts,data,_OPTS_PASSABLE_WITH_DATA)}return handleCache(opts,template)(data)};exports.renderFile=function(){var args=Array.prototype.slice.call(arguments);var filename=args.shift();var cb;var opts={filename:filename};var data;var viewOpts;if(typeof arguments[arguments.length-1]=="function"){cb=args.pop()}if(args.length){data=args.shift();if(args.length){utils.shallowCopy(opts,args.pop())}else{if(data.settings){if(data.settings.views){opts.views=data.settings.views}if(data.settings["view cache"]){opts.cache=true}viewOpts=data.settings["view options"];if(viewOpts){utils.shallowCopy(opts,viewOpts)}}utils.shallowCopyFromList(opts,data,_OPTS_PASSABLE_WITH_DATA_EXPRESS)}opts.filename=filename}else{data={}}return tryHandleCache(opts,data,cb)};exports.Template=Template;exports.clearCache=function(){exports.cache.reset()};function Template(text,opts){opts=opts||{};var options={};this.templateText=text;this.mode=null;this.truncate=false;this.currentLine=1;this.source="";options.client=opts.client||false;options.escapeFunction=opts.escape||opts.escapeFunction||utils.escapeXML;options.compileDebug=opts.compileDebug!==false;options.debug=!!opts.debug;options.filename=opts.filename;options.openDelimiter=opts.openDelimiter||exports.openDelimiter||_DEFAULT_OPEN_DELIMITER;options.closeDelimiter=opts.closeDelimiter||exports.closeDelimiter||_DEFAULT_CLOSE_DELIMITER;options.delimiter=opts.delimiter||exports.delimiter||_DEFAULT_DELIMITER;options.strict=opts.strict||false;options.context=opts.context;options.cache=opts.cache||false;options.rmWhitespace=opts.rmWhitespace;options.root=opts.root;options.includer=opts.includer;options.outputFunctionName=opts.outputFunctionName;options.localsName=opts.localsName||exports.localsName||_DEFAULT_LOCALS_NAME;options.views=opts.views;options.async=opts.async;options.destructuredLocals=opts.destructuredLocals;options.legacyInclude=typeof opts.legacyInclude!="undefined"?!!opts.legacyInclude:true;if(options.strict){options._with=false}else{options._with=typeof opts._with!="undefined"?opts._with:true}this.opts=options;this.regex=this.createRegex()}Template.modes={EVAL:"eval",ESCAPED:"escaped",RAW:"raw",COMMENT:"comment",LITERAL:"literal"};Template.prototype={createRegex:function(){var str=_REGEX_STRING;var delim=utils.escapeRegExpChars(this.opts.delimiter);var open=utils.escapeRegExpChars(this.opts.openDelimiter);var close=utils.escapeRegExpChars(this.opts.closeDelimiter);str=str.replace(/%/g,delim).replace(/</g,open).replace(/>/g,close);return new RegExp(str)},compile:function(){var src;var fn;var opts=this.opts;var prepended="";var appended="";var escapeFn=opts.escapeFunction;var ctor;var sanitizedFilename=opts.filename?JSON.stringify(opts.filename):"undefined";if(!this.source){this.generateSource();prepended+='  var __output = "";\n'+"  function __append(s) { if (s !== undefined && s !== null) __output += s }\n";if(opts.outputFunctionName){prepended+="  var "+opts.outputFunctionName+" = __append;"+"\n"}if(opts.destructuredLocals&&opts.destructuredLocals.length){var destructuring="  var __locals = ("+opts.localsName+" || {}),\n";for(var i=0;i<opts.destructuredLocals.length;i++){var name=opts.destructuredLocals[i];if(i>0){destructuring+=",\n  "}destructuring+=name+" = __locals."+name}prepended+=destructuring+";\n"}if(opts._with!==false){prepended+="  with ("+opts.localsName+" || {}) {"+"\n";appended+="  }"+"\n"}appended+="  return __output;"+"\n";this.source=prepended+this.source+appended}if(opts.compileDebug){src="var __line = 1"+"\n"+"  , __lines = "+JSON.stringify(this.templateText)+"\n"+"  , __filename = "+sanitizedFilename+";"+"\n"+"try {"+"\n"+this.source+"} catch (e) {"+"\n"+"  rethrow(e, __lines, __filename, __line, escapeFn);"+"\n"+"}"+"\n"}else{src=this.source}if(opts.client){src="escapeFn = escapeFn || "+escapeFn.toString()+";"+"\n"+src;if(opts.compileDebug){src="rethrow = rethrow || "+rethrow.toString()+";"+"\n"+src}}if(opts.strict){src='"use strict";\n'+src}if(opts.debug){console.log(src)}if(opts.compileDebug&&opts.filename){src=src+"\n"+"//# sourceURL="+sanitizedFilename+"\n"}try{if(opts.async){try{ctor=new Function("return (async function(){}).constructor;")()}catch(e){if(e instanceof SyntaxError){throw new Error("This environment does not support async/await")}else{throw e}}}else{ctor=Function}fn=new ctor(opts.localsName+", escapeFn, include, rethrow",src)}catch(e){if(e instanceof SyntaxError){if(opts.filename){e.message+=" in "+opts.filename}e.message+=" while compiling ejs\n\n";e.message+="If the above error is not helpful, you may want to try EJS-Lint:\n";e.message+="https://github.com/RyanZim/EJS-Lint";if(!opts.async){e.message+="\n";e.message+="Or, if you meant to create an async function, pass `async: true` as an option."}}throw e}var returnedFn=opts.client?fn:function anonymous(data){var include=function(path,includeData){var d=utils.shallowCopy({},data);if(includeData){d=utils.shallowCopy(d,includeData)}return includeFile(path,opts)(d)};return fn.apply(opts.context,[data||{},escapeFn,include,rethrow])};if(opts.filename&&typeof Object.defineProperty==="function"){var filename=opts.filename;var basename=path.basename(filename,path.extname(filename));try{Object.defineProperty(returnedFn,"name",{value:basename,writable:false,enumerable:false,configurable:true})}catch(e){}}return returnedFn},generateSource:function(){var opts=this.opts;if(opts.rmWhitespace){this.templateText=this.templateText.replace(/[\r\n]+/g,"\n").replace(/^\s+|\s+$/gm,"")}this.templateText=this.templateText.replace(/[ \t]*<%_/gm,"<%_").replace(/_%>[ \t]*/gm,"_%>");var self=this;var matches=this.parseTemplateText();var d=this.opts.delimiter;var o=this.opts.openDelimiter;var c=this.opts.closeDelimiter;if(matches&&matches.length){matches.forEach(function(line,index){var closing;if(line.indexOf(o+d)===0&&line.indexOf(o+d+d)!==0){closing=matches[index+2];if(!(closing==d+c||closing=="-"+d+c||closing=="_"+d+c)){throw new Error('Could not find matching close tag for "'+line+'".')}}self.scanLine(line)})}},parseTemplateText:function(){var str=this.templateText;var pat=this.regex;var result=pat.exec(str);var arr=[];var firstPos;while(result){firstPos=result.index;if(firstPos!==0){arr.push(str.substring(0,firstPos));str=str.slice(firstPos)}arr.push(result[0]);str=str.slice(result[0].length);result=pat.exec(str)}if(str){arr.push(str)}return arr},_addOutput:function(line){if(this.truncate){line=line.replace(/^(?:\r\n|\r|\n)/,"");this.truncate=false}if(!line){return line}line=line.replace(/\\/g,"\\\\");line=line.replace(/\n/g,"\\n");line=line.replace(/\r/g,"\\r");line=line.replace(/"/g,'\\"');this.source+='    ; __append("'+line+'")'+"\n"},scanLine:function(line){var self=this;var d=this.opts.delimiter;var o=this.opts.openDelimiter;var c=this.opts.closeDelimiter;var newLineCount=0;newLineCount=line.split("\n").length-1;switch(line){case o+d:case o+d+"_":this.mode=Template.modes.EVAL;break;case o+d+"=":this.mode=Template.modes.ESCAPED;break;case o+d+"-":this.mode=Template.modes.RAW;break;case o+d+"#":this.mode=Template.modes.COMMENT;break;case o+d+d:this.mode=Template.modes.LITERAL;this.source+='    ; __append("'+line.replace(o+d+d,o+d)+'")'+"\n";break;case d+d+c:this.mode=Template.modes.LITERAL;this.source+='    ; __append("'+line.replace(d+d+c,d+c)+'")'+"\n";break;case d+c:case"-"+d+c:case"_"+d+c:if(this.mode==Template.modes.LITERAL){this._addOutput(line)}this.mode=null;this.truncate=line.indexOf("-")===0||line.indexOf("_")===0;break;default:if(this.mode){switch(this.mode){case Template.modes.EVAL:case Template.modes.ESCAPED:case Template.modes.RAW:if(line.lastIndexOf("//")>line.lastIndexOf("\n")){line+="\n"}}switch(this.mode){case Template.modes.EVAL:this.source+="    ; "+line+"\n";break;case Template.modes.ESCAPED:this.source+="    ; __append(escapeFn("+stripSemi(line)+"))"+"\n";break;case Template.modes.RAW:this.source+="    ; __append("+stripSemi(line)+")"+"\n";break;case Template.modes.COMMENT:break;case Template.modes.LITERAL:this._addOutput(line);break}}else{this._addOutput(line)}}if(self.opts.compileDebug&&newLineCount){this.currentLine+=newLineCount;this.source+="    ; __line = "+this.currentLine+"\n"}}};exports.escapeXML=utils.escapeXML;exports.__express=exports.renderFile;exports.VERSION=_VERSION_STRING;exports.name=_NAME;if(typeof window!="undefined"){window.ejs=exports}},{"../package.json":6,"./utils":2,fs:3,path:4}],2:[function(require,module,exports){"use strict";var regExpChars=/[|\\{}()[\]^$+*?.]/g;exports.escapeRegExpChars=function(string){if(!string){return""}return String(string).replace(regExpChars,"\\$&")};var _ENCODE_HTML_RULES={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&#34;","'":"&#39;"};var _MATCH_HTML=/[&<>'"]/g;function encode_char(c){return _ENCODE_HTML_RULES[c]||c}var escapeFuncStr="var _ENCODE_HTML_RULES = {\n"+'      "&": "&amp;"\n'+'    , "<": "&lt;"\n'+'    , ">": "&gt;"\n'+'    , \'"\': "&#34;"\n'+'    , "\'": "&#39;"\n'+"    }\n"+"  , _MATCH_HTML = /[&<>'\"]/g;\n"+"function encode_char(c) {\n"+"  return _ENCODE_HTML_RULES[c] || c;\n"+"};\n";exports.escapeXML=function(markup){return markup==undefined?"":String(markup).replace(_MATCH_HTML,encode_char)};exports.escapeXML.toString=function(){return Function.prototype.toString.call(this)+";\n"+escapeFuncStr};exports.shallowCopy=function(to,from){from=from||{};for(var p in from){to[p]=from[p]}return to};exports.shallowCopyFromList=function(to,from,list){for(var i=0;i<list.length;i++){var p=list[i];if(typeof from[p]!="undefined"){to[p]=from[p]}}return to};exports.cache={_data:{},set:function(key,val){this._data[key]=val},get:function(key){return this._data[key]},remove:function(key){delete this._data[key]},reset:function(){this._data={}}};exports.hyphenToCamel=function(str){return str.replace(/-[a-z]/g,function(match){return match[1].toUpperCase()})}},{}],3:[function(require,module,exports){},{}],4:[function(require,module,exports){(function(process){function normalizeArray(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up--;up){parts.unshift("..")}}return parts}exports.resolve=function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:process.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){continue}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=normalizeArray(filter(resolvedPath.split("/"),function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."};exports.normalize=function(path){var isAbsolute=exports.isAbsolute(path),trailingSlash=substr(path,-1)==="/";path=normalizeArray(filter(path.split("/"),function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path};exports.isAbsolute=function(path){return path.charAt(0)==="/"};exports.join=function(){var paths=Array.prototype.slice.call(arguments,0);return exports.normalize(filter(paths,function(p,index){if(typeof p!=="string"){throw new TypeError("Arguments to path.join must be strings")}return p}).join("/"))};exports.relative=function(from,to){from=exports.resolve(from).substr(1);to=exports.resolve(to).substr(1);function trim(arr){var start=0;for(;start<arr.length;start++){if(arr[start]!=="")break}var end=arr.length-1;for(;end>=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i<length;i++){if(fromParts[i]!==toParts[i]){samePartsLength=i;break}}var outputParts=[];for(var i=samePartsLength;i<fromParts.length;i++){outputParts.push("..")}outputParts=outputParts.concat(toParts.slice(samePartsLength));return outputParts.join("/")};exports.sep="/";exports.delimiter=":";exports.dirname=function(path){if(typeof path!=="string")path=path+"";if(path.length===0)return".";var code=path.charCodeAt(0);var hasRoot=code===47;var end=-1;var matchedSlash=true;for(var i=path.length-1;i>=1;--i){code=path.charCodeAt(i);if(code===47){if(!matchedSlash){end=i;break}}else{matchedSlash=false}}if(end===-1)return hasRoot?"/":".";if(hasRoot&&end===1){return"/"}return path.slice(0,end)};function basename(path){if(typeof path!=="string")path=path+"";var start=0;var end=-1;var matchedSlash=true;var i;for(i=path.length-1;i>=0;--i){if(path.charCodeAt(i)===47){if(!matchedSlash){start=i+1;break}}else if(end===-1){matchedSlash=false;end=i+1}}if(end===-1)return"";return path.slice(start,end)}exports.basename=function(path,ext){var f=basename(path);if(ext&&f.substr(-1*ext.length)===ext){f=f.substr(0,f.length-ext.length)}return f};exports.extname=function(path){if(typeof path!=="string")path=path+"";var startDot=-1;var startPart=0;var end=-1;var matchedSlash=true;var preDotState=0;for(var i=path.length-1;i>=0;--i){var code=path.charCodeAt(i);if(code===47){if(!matchedSlash){startPart=i+1;break}continue}if(end===-1){matchedSlash=false;end=i+1}if(code===46){if(startDot===-1)startDot=i;else if(preDotState!==1)preDotState=1}else if(startDot!==-1){preDotState=-1}}if(startDot===-1||end===-1||preDotState===0||preDotState===1&&startDot===end-1&&startDot===startPart+1){return""}return path.slice(startDot,end)};function filter(xs,f){if(xs.filter)return xs.filter(f);var res=[];for(var i=0;i<xs.length;i++){if(f(xs[i],i,xs))res.push(xs[i])}return res}var substr="ab".substr(-1)==="b"?function(str,start,len){return str.substr(start,len)}:function(str,start,len){if(start<0)start=str.length+start;return str.substr(start,len)}}).call(this,require("_process"))},{_process:5}],5:[function(require,module,exports){var process=module.exports={};var cachedSetTimeout;var cachedClearTimeout;function defaultSetTimout(){throw new Error("setTimeout has not been defined")}function defaultClearTimeout(){throw new Error("clearTimeout has not been defined")}(function(){try{if(typeof setTimeout==="function"){cachedSetTimeout=setTimeout}else{cachedSetTimeout=defaultSetTimout}}catch(e){cachedSetTimeout=defaultSetTimout}try{if(typeof clearTimeout==="function"){cachedClearTimeout=clearTimeout}else{cachedClearTimeout=defaultClearTimeout}}catch(e){cachedClearTimeout=defaultClearTimeout}})();function runTimeout(fun){if(cachedSetTimeout===setTimeout){return setTimeout(fun,0)}if((cachedSetTimeout===defaultSetTimout||!cachedSetTimeout)&&setTimeout){cachedSetTimeout=setTimeout;return setTimeout(fun,0)}try{return cachedSetTimeout(fun,0)}catch(e){try{return cachedSetTimeout.call(null,fun,0)}catch(e){return cachedSetTimeout.call(this,fun,0)}}}function runClearTimeout(marker){if(cachedClearTimeout===clearTimeout){return clearTimeout(marker)}if((cachedClearTimeout===defaultClearTimeout||!cachedClearTimeout)&&clearTimeout){cachedClearTimeout=clearTimeout;return clearTimeout(marker)}try{return cachedClearTimeout(marker)}catch(e){try{return cachedClearTimeout.call(null,marker)}catch(e){return cachedClearTimeout.call(this,marker)}}}var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){if(!draining||!currentQueue){return}draining=false;if(currentQueue.length){queue=currentQueue.concat(queue)}else{queueIndex=-1}if(queue.length){drainQueue()}}function drainQueue(){if(draining){return}var timeout=runTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex<len){if(currentQueue){currentQueue[queueIndex].run()}}queueIndex=-1;len=queue.length}currentQueue=null;draining=false;runClearTimeout(timeout)}process.nextTick=function(fun){var args=new Array(arguments.length-1);if(arguments.length>1){for(var i=1;i<arguments.length;i++){args[i-1]=arguments[i]}}queue.push(new Item(fun,args));if(queue.length===1&&!draining){runTimeout(drainQueue)}};function Item(fun,array){this.fun=fun;this.array=array}Item.prototype.run=function(){this.fun.apply(null,this.array)};process.title="browser";process.browser=true;process.env={};process.argv=[];process.version="";process.versions={};function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.prependListener=noop;process.prependOnceListener=noop;process.listeners=function(name){return[]};process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")};process.umask=function(){return 0}},{}],6:[function(require,module,exports){module.exports={name:"ejs",description:"Embedded JavaScript templates",keywords:["template","engine","ejs"],version:"3.1.6",author:"Matthew Eernisse <mde@fleegix.org> (http://fleegix.org)",license:"Apache-2.0",bin:{ejs:"./bin/cli.js"},main:"./lib/ejs.js",jsdelivr:"ejs.min.js",unpkg:"ejs.min.js",repository:{type:"git",url:"git://github.com/mde/ejs.git"},bugs:"https://github.com/mde/ejs/issues",homepage:"https://github.com/mde/ejs",dependencies:{jake:"^10.6.1"},devDependencies:{browserify:"^16.5.1",eslint:"^6.8.0","git-directory-deploy":"^1.5.1",jsdoc:"^3.6.4","lru-cache":"^4.0.1",mocha:"^7.1.1","uglify-js":"^3.3.16"},engines:{node:">=0.10.0"},scripts:{test:"mocha"}}},{}]},{},[1])(1)});
diff --git a/d2d_app/node_modules/ejs/jakefile.js b/d2d_app/node_modules/ejs/jakefile.js
new file mode 100644 (file)
index 0000000..3953160
--- /dev/null
@@ -0,0 +1,81 @@
+var fs = require('fs');
+var execSync = require('child_process').execSync;
+var exec = function (cmd) {
+  execSync(cmd, {stdio: 'inherit'});
+};
+
+/* global jake, task, desc, publishTask */
+
+task('build', ['lint', 'clean', 'browserify', 'minify'], function () {
+  console.log('Build completed.');
+});
+
+desc('Cleans browerified/minified files and package files');
+task('clean', ['clobber'], function () {
+  jake.rmRf('./ejs.js');
+  jake.rmRf('./ejs.min.js');
+  console.log('Cleaned up compiled files.');
+});
+
+desc('Lints the source code');
+task('lint', ['clean'], function () {
+  exec('./node_modules/.bin/eslint "**/*.js"');
+  console.log('Linting completed.');
+});
+
+task('browserify', function () {
+  exec('./node_modules/browserify/bin/cmd.js --standalone ejs lib/ejs.js > ejs.js');
+  console.log('Browserification completed.');
+});
+
+task('minify', function () {
+  exec('./node_modules/uglify-js/bin/uglifyjs ejs.js > ejs.min.js');
+  console.log('Minification completed.');
+});
+
+desc('Generates the EJS API docs for the public API');
+task('doc', function () {
+  jake.rmRf('out');
+  exec('./node_modules/.bin/jsdoc --verbose -c jsdoc.json lib/* docs/jsdoc/*');
+  console.log('Documentation generated in ./out.');
+});
+
+desc('Generates the EJS API docs for the public and private API');
+task('devdoc', function () {
+  jake.rmRf('out');
+  exec('./node_modules/.bin/jsdoc --verbose -p -c jsdoc.json lib/* docs/jsdoc/*');
+  console.log('Documentation generated in ./out.');
+});
+
+desc('Publishes the EJS API docs');
+task('docPublish', ['doc'], function () {
+  fs.writeFileSync('out/CNAME', 'api.ejs.co');
+  console.log('Pushing docs to gh-pages...');
+  exec('./node_modules/.bin/git-directory-deploy --directory out/');
+  console.log('Docs published to gh-pages.');
+});
+
+desc('Runs the EJS test suite');
+task('test', ['lint'], function () {
+  exec('./node_modules/.bin/mocha');
+});
+
+publishTask('ejs', ['build'], function () {
+  this.packageFiles.include([
+    'jakefile.js',
+    'README.md',
+    'LICENSE',
+    'package.json',
+    'ejs.js',
+    'ejs.min.js',
+    'lib/**',
+    'bin/**',
+    'usage.txt'
+  ]);
+});
+
+jake.Task.publish.on('complete', function () {
+  console.log('Updating hosted docs...');
+  console.log('If this fails, run jake docPublish to re-try.');
+  jake.Task.docPublish.invoke();
+});
diff --git a/d2d_app/node_modules/ejs/lib/ejs.js b/d2d_app/node_modules/ejs/lib/ejs.js
new file mode 100755 (executable)
index 0000000..aa6322e
--- /dev/null
@@ -0,0 +1,939 @@
+/*
+ * EJS Embedded JavaScript templates
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+'use strict';
+
+/**
+ * @file Embedded JavaScript templating engine. {@link http://ejs.co}
+ * @author Matthew Eernisse <mde@fleegix.org>
+ * @author Tiancheng "Timothy" Gu <timothygu99@gmail.com>
+ * @project EJS
+ * @license {@link http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0}
+ */
+
+/**
+ * EJS internal functions.
+ *
+ * Technically this "module" lies in the same file as {@link module:ejs}, for
+ * the sake of organization all the private functions re grouped into this
+ * module.
+ *
+ * @module ejs-internal
+ * @private
+ */
+
+/**
+ * Embedded JavaScript templating engine.
+ *
+ * @module ejs
+ * @public
+ */
+
+var fs = require('fs');
+var path = require('path');
+var utils = require('./utils');
+
+var scopeOptionWarned = false;
+/** @type {string} */
+var _VERSION_STRING = require('../package.json').version;
+var _DEFAULT_OPEN_DELIMITER = '<';
+var _DEFAULT_CLOSE_DELIMITER = '>';
+var _DEFAULT_DELIMITER = '%';
+var _DEFAULT_LOCALS_NAME = 'locals';
+var _NAME = 'ejs';
+var _REGEX_STRING = '(<%%|%%>|<%=|<%-|<%_|<%#|<%|%>|-%>|_%>)';
+var _OPTS_PASSABLE_WITH_DATA = ['delimiter', 'scope', 'context', 'debug', 'compileDebug',
+  'client', '_with', 'rmWhitespace', 'strict', 'filename', 'async'];
+// We don't allow 'cache' option to be passed in the data obj for
+// the normal `render` call, but this is where Express 2 & 3 put it
+// so we make an exception for `renderFile`
+var _OPTS_PASSABLE_WITH_DATA_EXPRESS = _OPTS_PASSABLE_WITH_DATA.concat('cache');
+var _BOM = /^\uFEFF/;
+
+/**
+ * EJS template function cache. This can be a LRU object from lru-cache NPM
+ * module. By default, it is {@link module:utils.cache}, a simple in-process
+ * cache that grows continuously.
+ *
+ * @type {Cache}
+ */
+
+exports.cache = utils.cache;
+
+/**
+ * Custom file loader. Useful for template preprocessing or restricting access
+ * to a certain part of the filesystem.
+ *
+ * @type {fileLoader}
+ */
+
+exports.fileLoader = fs.readFileSync;
+
+/**
+ * Name of the object containing the locals.
+ *
+ * This variable is overridden by {@link Options}`.localsName` if it is not
+ * `undefined`.
+ *
+ * @type {String}
+ * @public
+ */
+
+exports.localsName = _DEFAULT_LOCALS_NAME;
+
+/**
+ * Promise implementation -- defaults to the native implementation if available
+ * This is mostly just for testability
+ *
+ * @type {PromiseConstructorLike}
+ * @public
+ */
+
+exports.promiseImpl = (new Function('return this;'))().Promise;
+
+/**
+ * Get the path to the included file from the parent file path and the
+ * specified path.
+ *
+ * @param {String}  name     specified path
+ * @param {String}  filename parent file path
+ * @param {Boolean} [isDir=false] whether the parent file path is a directory
+ * @return {String}
+ */
+exports.resolveInclude = function(name, filename, isDir) {
+  var dirname = path.dirname;
+  var extname = path.extname;
+  var resolve = path.resolve;
+  var includePath = resolve(isDir ? filename : dirname(filename), name);
+  var ext = extname(name);
+  if (!ext) {
+    includePath += '.ejs';
+  }
+  return includePath;
+};
+
+/**
+ * Try to resolve file path on multiple directories
+ *
+ * @param  {String}        name  specified path
+ * @param  {Array<String>} paths list of possible parent directory paths
+ * @return {String}
+ */
+function resolvePaths(name, paths) {
+  var filePath;
+  if (paths.some(function (v) {
+    filePath = exports.resolveInclude(name, v, true);
+    return fs.existsSync(filePath);
+  })) {
+    return filePath;
+  }
+}
+
+/**
+ * Get the path to the included file by Options
+ *
+ * @param  {String}  path    specified path
+ * @param  {Options} options compilation options
+ * @return {String}
+ */
+function getIncludePath(path, options) {
+  var includePath;
+  var filePath;
+  var views = options.views;
+  var match = /^[A-Za-z]+:\\|^\//.exec(path);
+
+  // Abs path
+  if (match && match.length) {
+    path = path.replace(/^\/*/, '');
+    if (Array.isArray(options.root)) {
+      includePath = resolvePaths(path, options.root);
+    } else {
+      includePath = exports.resolveInclude(path, options.root || '/', true);
+    }
+  }
+  // Relative paths
+  else {
+    // Look relative to a passed filename first
+    if (options.filename) {
+      filePath = exports.resolveInclude(path, options.filename);
+      if (fs.existsSync(filePath)) {
+        includePath = filePath;
+      }
+    }
+    // Then look in any views directories
+    if (!includePath && Array.isArray(views)) {
+      includePath = resolvePaths(path, views);
+    }
+    if (!includePath && typeof options.includer !== 'function') {
+      throw new Error('Could not find the include file "' +
+          options.escapeFunction(path) + '"');
+    }
+  }
+  return includePath;
+}
+
+/**
+ * Get the template from a string or a file, either compiled on-the-fly or
+ * read from cache (if enabled), and cache the template if needed.
+ *
+ * If `template` is not set, the file specified in `options.filename` will be
+ * read.
+ *
+ * If `options.cache` is true, this function reads the file from
+ * `options.filename` so it must be set prior to calling this function.
+ *
+ * @memberof module:ejs-internal
+ * @param {Options} options   compilation options
+ * @param {String} [template] template source
+ * @return {(TemplateFunction|ClientFunction)}
+ * Depending on the value of `options.client`, either type might be returned.
+ * @static
+ */
+
+function handleCache(options, template) {
+  var func;
+  var filename = options.filename;
+  var hasTemplate = arguments.length > 1;
+
+  if (options.cache) {
+    if (!filename) {
+      throw new Error('cache option requires a filename');
+    }
+    func = exports.cache.get(filename);
+    if (func) {
+      return func;
+    }
+    if (!hasTemplate) {
+      template = fileLoader(filename).toString().replace(_BOM, '');
+    }
+  }
+  else if (!hasTemplate) {
+    // istanbul ignore if: should not happen at all
+    if (!filename) {
+      throw new Error('Internal EJS error: no file name or template '
+                    + 'provided');
+    }
+    template = fileLoader(filename).toString().replace(_BOM, '');
+  }
+  func = exports.compile(template, options);
+  if (options.cache) {
+    exports.cache.set(filename, func);
+  }
+  return func;
+}
+
+/**
+ * Try calling handleCache with the given options and data and call the
+ * callback with the result. If an error occurs, call the callback with
+ * the error. Used by renderFile().
+ *
+ * @memberof module:ejs-internal
+ * @param {Options} options    compilation options
+ * @param {Object} data        template data
+ * @param {RenderFileCallback} cb callback
+ * @static
+ */
+
+function tryHandleCache(options, data, cb) {
+  var result;
+  if (!cb) {
+    if (typeof exports.promiseImpl == 'function') {
+      return new exports.promiseImpl(function (resolve, reject) {
+        try {
+          result = handleCache(options)(data);
+          resolve(result);
+        }
+        catch (err) {
+          reject(err);
+        }
+      });
+    }
+    else {
+      throw new Error('Please provide a callback function');
+    }
+  }
+  else {
+    try {
+      result = handleCache(options)(data);
+    }
+    catch (err) {
+      return cb(err);
+    }
+
+    cb(null, result);
+  }
+}
+
+/**
+ * fileLoader is independent
+ *
+ * @param {String} filePath ejs file path.
+ * @return {String} The contents of the specified file.
+ * @static
+ */
+
+function fileLoader(filePath){
+  return exports.fileLoader(filePath);
+}
+
+/**
+ * Get the template function.
+ *
+ * If `options.cache` is `true`, then the template is cached.
+ *
+ * @memberof module:ejs-internal
+ * @param {String}  path    path for the specified file
+ * @param {Options} options compilation options
+ * @return {(TemplateFunction|ClientFunction)}
+ * Depending on the value of `options.client`, either type might be returned
+ * @static
+ */
+
+function includeFile(path, options) {
+  var opts = utils.shallowCopy({}, options);
+  opts.filename = getIncludePath(path, opts);
+  if (typeof options.includer === 'function') {
+    var includerResult = options.includer(path, opts.filename);
+    if (includerResult) {
+      if (includerResult.filename) {
+        opts.filename = includerResult.filename;
+      }
+      if (includerResult.template) {
+        return handleCache(opts, includerResult.template);
+      }
+    }
+  }
+  return handleCache(opts);
+}
+
+/**
+ * Re-throw the given `err` in context to the `str` of ejs, `filename`, and
+ * `lineno`.
+ *
+ * @implements {RethrowCallback}
+ * @memberof module:ejs-internal
+ * @param {Error}  err      Error object
+ * @param {String} str      EJS source
+ * @param {String} flnm     file name of the EJS file
+ * @param {Number} lineno   line number of the error
+ * @param {EscapeCallback} esc
+ * @static
+ */
+
+function rethrow(err, str, flnm, lineno, esc) {
+  var lines = str.split('\n');
+  var start = Math.max(lineno - 3, 0);
+  var end = Math.min(lines.length, lineno + 3);
+  var filename = esc(flnm);
+  // Error context
+  var context = lines.slice(start, end).map(function (line, i){
+    var curr = i + start + 1;
+    return (curr == lineno ? ' >> ' : '    ')
+      + curr
+      + '| '
+      + line;
+  }).join('\n');
+
+  // Alter exception message
+  err.path = filename;
+  err.message = (filename || 'ejs') + ':'
+    + lineno + '\n'
+    + context + '\n\n'
+    + err.message;
+
+  throw err;
+}
+
+function stripSemi(str){
+  return str.replace(/;(\s*$)/, '$1');
+}
+
+/**
+ * Compile the given `str` of ejs into a template function.
+ *
+ * @param {String}  template EJS template
+ *
+ * @param {Options} [opts] compilation options
+ *
+ * @return {(TemplateFunction|ClientFunction)}
+ * Depending on the value of `opts.client`, either type might be returned.
+ * Note that the return type of the function also depends on the value of `opts.async`.
+ * @public
+ */
+
+exports.compile = function compile(template, opts) {
+  var templ;
+
+  // v1 compat
+  // 'scope' is 'context'
+  // FIXME: Remove this in a future version
+  if (opts && opts.scope) {
+    if (!scopeOptionWarned){
+      console.warn('`scope` option is deprecated and will be removed in EJS 3');
+      scopeOptionWarned = true;
+    }
+    if (!opts.context) {
+      opts.context = opts.scope;
+    }
+    delete opts.scope;
+  }
+  templ = new Template(template, opts);
+  return templ.compile();
+};
+
+/**
+ * Render the given `template` of ejs.
+ *
+ * If you would like to include options but not data, you need to explicitly
+ * call this function with `data` being an empty object or `null`.
+ *
+ * @param {String}   template EJS template
+ * @param {Object}  [data={}] template data
+ * @param {Options} [opts={}] compilation and rendering options
+ * @return {(String|Promise<String>)}
+ * Return value type depends on `opts.async`.
+ * @public
+ */
+
+exports.render = function (template, d, o) {
+  var data = d || {};
+  var opts = o || {};
+
+  // No options object -- if there are optiony names
+  // in the data, copy them to options
+  if (arguments.length == 2) {
+    utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA);
+  }
+
+  return handleCache(opts, template)(data);
+};
+
+/**
+ * Render an EJS file at the given `path` and callback `cb(err, str)`.
+ *
+ * If you would like to include options but not data, you need to explicitly
+ * call this function with `data` being an empty object or `null`.
+ *
+ * @param {String}             path     path to the EJS file
+ * @param {Object}            [data={}] template data
+ * @param {Options}           [opts={}] compilation and rendering options
+ * @param {RenderFileCallback} cb callback
+ * @public
+ */
+
+exports.renderFile = function () {
+  var args = Array.prototype.slice.call(arguments);
+  var filename = args.shift();
+  var cb;
+  var opts = {filename: filename};
+  var data;
+  var viewOpts;
+
+  // Do we have a callback?
+  if (typeof arguments[arguments.length - 1] == 'function') {
+    cb = args.pop();
+  }
+  // Do we have data/opts?
+  if (args.length) {
+    // Should always have data obj
+    data = args.shift();
+    // Normal passed opts (data obj + opts obj)
+    if (args.length) {
+      // Use shallowCopy so we don't pollute passed in opts obj with new vals
+      utils.shallowCopy(opts, args.pop());
+    }
+    // Special casing for Express (settings + opts-in-data)
+    else {
+      // Express 3 and 4
+      if (data.settings) {
+        // Pull a few things from known locations
+        if (data.settings.views) {
+          opts.views = data.settings.views;
+        }
+        if (data.settings['view cache']) {
+          opts.cache = true;
+        }
+        // Undocumented after Express 2, but still usable, esp. for
+        // items that are unsafe to be passed along with data, like `root`
+        viewOpts = data.settings['view options'];
+        if (viewOpts) {
+          utils.shallowCopy(opts, viewOpts);
+        }
+      }
+      // Express 2 and lower, values set in app.locals, or people who just
+      // want to pass options in their data. NOTE: These values will override
+      // anything previously set in settings  or settings['view options']
+      utils.shallowCopyFromList(opts, data, _OPTS_PASSABLE_WITH_DATA_EXPRESS);
+    }
+    opts.filename = filename;
+  }
+  else {
+    data = {};
+  }
+
+  return tryHandleCache(opts, data, cb);
+};
+
+/**
+ * Clear intermediate JavaScript cache. Calls {@link Cache#reset}.
+ * @public
+ */
+
+/**
+ * EJS template class
+ * @public
+ */
+exports.Template = Template;
+
+exports.clearCache = function () {
+  exports.cache.reset();
+};
+
+function Template(text, opts) {
+  opts = opts || {};
+  var options = {};
+  this.templateText = text;
+  /** @type {string | null} */
+  this.mode = null;
+  this.truncate = false;
+  this.currentLine = 1;
+  this.source = '';
+  options.client = opts.client || false;
+  options.escapeFunction = opts.escape || opts.escapeFunction || utils.escapeXML;
+  options.compileDebug = opts.compileDebug !== false;
+  options.debug = !!opts.debug;
+  options.filename = opts.filename;
+  options.openDelimiter = opts.openDelimiter || exports.openDelimiter || _DEFAULT_OPEN_DELIMITER;
+  options.closeDelimiter = opts.closeDelimiter || exports.closeDelimiter || _DEFAULT_CLOSE_DELIMITER;
+  options.delimiter = opts.delimiter || exports.delimiter || _DEFAULT_DELIMITER;
+  options.strict = opts.strict || false;
+  options.context = opts.context;
+  options.cache = opts.cache || false;
+  options.rmWhitespace = opts.rmWhitespace;
+  options.root = opts.root;
+  options.includer = opts.includer;
+  options.outputFunctionName = opts.outputFunctionName;
+  options.localsName = opts.localsName || exports.localsName || _DEFAULT_LOCALS_NAME;
+  options.views = opts.views;
+  options.async = opts.async;
+  options.destructuredLocals = opts.destructuredLocals;
+  options.legacyInclude = typeof opts.legacyInclude != 'undefined' ? !!opts.legacyInclude : true;
+
+  if (options.strict) {
+    options._with = false;
+  }
+  else {
+    options._with = typeof opts._with != 'undefined' ? opts._with : true;
+  }
+
+  this.opts = options;
+
+  this.regex = this.createRegex();
+}
+
+Template.modes = {
+  EVAL: 'eval',
+  ESCAPED: 'escaped',
+  RAW: 'raw',
+  COMMENT: 'comment',
+  LITERAL: 'literal'
+};
+
+Template.prototype = {
+  createRegex: function () {
+    var str = _REGEX_STRING;
+    var delim = utils.escapeRegExpChars(this.opts.delimiter);
+    var open = utils.escapeRegExpChars(this.opts.openDelimiter);
+    var close = utils.escapeRegExpChars(this.opts.closeDelimiter);
+    str = str.replace(/%/g, delim)
+      .replace(/</g, open)
+      .replace(/>/g, close);
+    return new RegExp(str);
+  },
+
+  compile: function () {
+    /** @type {string} */
+    var src;
+    /** @type {ClientFunction} */
+    var fn;
+    var opts = this.opts;
+    var prepended = '';
+    var appended = '';
+    /** @type {EscapeCallback} */
+    var escapeFn = opts.escapeFunction;
+    /** @type {FunctionConstructor} */
+    var ctor;
+    /** @type {string} */
+    var sanitizedFilename = opts.filename ? JSON.stringify(opts.filename) : 'undefined';
+
+    if (!this.source) {
+      this.generateSource();
+      prepended +=
+        '  var __output = "";\n' +
+        '  function __append(s) { if (s !== undefined && s !== null) __output += s }\n';
+      if (opts.outputFunctionName) {
+        prepended += '  var ' + opts.outputFunctionName + ' = __append;' + '\n';
+      }
+      if (opts.destructuredLocals && opts.destructuredLocals.length) {
+        var destructuring = '  var __locals = (' + opts.localsName + ' || {}),\n';
+        for (var i = 0; i < opts.destructuredLocals.length; i++) {
+          var name = opts.destructuredLocals[i];
+          if (i > 0) {
+            destructuring += ',\n  ';
+          }
+          destructuring += name + ' = __locals.' + name;
+        }
+        prepended += destructuring + ';\n';
+      }
+      if (opts._with !== false) {
+        prepended +=  '  with (' + opts.localsName + ' || {}) {' + '\n';
+        appended += '  }' + '\n';
+      }
+      appended += '  return __output;' + '\n';
+      this.source = prepended + this.source + appended;
+    }
+
+    if (opts.compileDebug) {
+      src = 'var __line = 1' + '\n'
+        + '  , __lines = ' + JSON.stringify(this.templateText) + '\n'
+        + '  , __filename = ' + sanitizedFilename + ';' + '\n'
+        + 'try {' + '\n'
+        + this.source
+        + '} catch (e) {' + '\n'
+        + '  rethrow(e, __lines, __filename, __line, escapeFn);' + '\n'
+        + '}' + '\n';
+    }
+    else {
+      src = this.source;
+    }
+
+    if (opts.client) {
+      src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '\n' + src;
+      if (opts.compileDebug) {
+        src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '\n' + src;
+      }
+    }
+
+    if (opts.strict) {
+      src = '"use strict";\n' + src;
+    }
+    if (opts.debug) {
+      console.log(src);
+    }
+    if (opts.compileDebug && opts.filename) {
+      src = src + '\n'
+        + '//# sourceURL=' + sanitizedFilename + '\n';
+    }
+
+    try {
+      if (opts.async) {
+        // Have to use generated function for this, since in envs without support,
+        // it breaks in parsing
+        try {
+          ctor = (new Function('return (async function(){}).constructor;'))();
+        }
+        catch(e) {
+          if (e instanceof SyntaxError) {
+            throw new Error('This environment does not support async/await');
+          }
+          else {
+            throw e;
+          }
+        }
+      }
+      else {
+        ctor = Function;
+      }
+      fn = new ctor(opts.localsName + ', escapeFn, include, rethrow', src);
+    }
+    catch(e) {
+      // istanbul ignore else
+      if (e instanceof SyntaxError) {
+        if (opts.filename) {
+          e.message += ' in ' + opts.filename;
+        }
+        e.message += ' while compiling ejs\n\n';
+        e.message += 'If the above error is not helpful, you may want to try EJS-Lint:\n';
+        e.message += 'https://github.com/RyanZim/EJS-Lint';
+        if (!opts.async) {
+          e.message += '\n';
+          e.message += 'Or, if you meant to create an async function, pass `async: true` as an option.';
+        }
+      }
+      throw e;
+    }
+
+    // Return a callable function which will execute the function
+    // created by the source-code, with the passed data as locals
+    // Adds a local `include` function which allows full recursive include
+    var returnedFn = opts.client ? fn : function anonymous(data) {
+      var include = function (path, includeData) {
+        var d = utils.shallowCopy({}, data);
+        if (includeData) {
+          d = utils.shallowCopy(d, includeData);
+        }
+        return includeFile(path, opts)(d);
+      };
+      return fn.apply(opts.context, [data || {}, escapeFn, include, rethrow]);
+    };
+    if (opts.filename && typeof Object.defineProperty === 'function') {
+      var filename = opts.filename;
+      var basename = path.basename(filename, path.extname(filename));
+      try {
+        Object.defineProperty(returnedFn, 'name', {
+          value: basename,
+          writable: false,
+          enumerable: false,
+          configurable: true
+        });
+      } catch (e) {/* ignore */}
+    }
+    return returnedFn;
+  },
+
+  generateSource: function () {
+    var opts = this.opts;
+
+    if (opts.rmWhitespace) {
+      // Have to use two separate replace here as `^` and `$` operators don't
+      // work well with `\r` and empty lines don't work well with the `m` flag.
+      this.templateText =
+        this.templateText.replace(/[\r\n]+/g, '\n').replace(/^\s+|\s+$/gm, '');
+    }
+
+    // Slurp spaces and tabs before <%_ and after _%>
+    this.templateText =
+      this.templateText.replace(/[ \t]*<%_/gm, '<%_').replace(/_%>[ \t]*/gm, '_%>');
+
+    var self = this;
+    var matches = this.parseTemplateText();
+    var d = this.opts.delimiter;
+    var o = this.opts.openDelimiter;
+    var c = this.opts.closeDelimiter;
+
+    if (matches && matches.length) {
+      matches.forEach(function (line, index) {
+        var closing;
+        // If this is an opening tag, check for closing tags
+        // FIXME: May end up with some false positives here
+        // Better to store modes as k/v with openDelimiter + delimiter as key
+        // Then this can simply check against the map
+        if ( line.indexOf(o + d) === 0        // If it is a tag
+          && line.indexOf(o + d + d) !== 0) { // and is not escaped
+          closing = matches[index + 2];
+          if (!(closing == d + c || closing == '-' + d + c || closing == '_' + d + c)) {
+            throw new Error('Could not find matching close tag for "' + line + '".');
+          }
+        }
+        self.scanLine(line);
+      });
+    }
+
+  },
+
+  parseTemplateText: function () {
+    var str = this.templateText;
+    var pat = this.regex;
+    var result = pat.exec(str);
+    var arr = [];
+    var firstPos;
+
+    while (result) {
+      firstPos = result.index;
+
+      if (firstPos !== 0) {
+        arr.push(str.substring(0, firstPos));
+        str = str.slice(firstPos);
+      }
+
+      arr.push(result[0]);
+      str = str.slice(result[0].length);
+      result = pat.exec(str);
+    }
+
+    if (str) {
+      arr.push(str);
+    }
+
+    return arr;
+  },
+
+  _addOutput: function (line) {
+    if (this.truncate) {
+      // Only replace single leading linebreak in the line after
+      // -%> tag -- this is the single, trailing linebreak
+      // after the tag that the truncation mode replaces
+      // Handle Win / Unix / old Mac linebreaks -- do the \r\n
+      // combo first in the regex-or
+      line = line.replace(/^(?:\r\n|\r|\n)/, '');
+      this.truncate = false;
+    }
+    if (!line) {
+      return line;
+    }
+
+    // Preserve literal slashes
+    line = line.replace(/\\/g, '\\\\');
+
+    // Convert linebreaks
+    line = line.replace(/\n/g, '\\n');
+    line = line.replace(/\r/g, '\\r');
+
+    // Escape double-quotes
+    // - this will be the delimiter during execution
+    line = line.replace(/"/g, '\\"');
+    this.source += '    ; __append("' + line + '")' + '\n';
+  },
+
+  scanLine: function (line) {
+    var self = this;
+    var d = this.opts.delimiter;
+    var o = this.opts.openDelimiter;
+    var c = this.opts.closeDelimiter;
+    var newLineCount = 0;
+
+    newLineCount = (line.split('\n').length - 1);
+
+    switch (line) {
+    case o + d:
+    case o + d + '_':
+      this.mode = Template.modes.EVAL;
+      break;
+    case o + d + '=':
+      this.mode = Template.modes.ESCAPED;
+      break;
+    case o + d + '-':
+      this.mode = Template.modes.RAW;
+      break;
+    case o + d + '#':
+      this.mode = Template.modes.COMMENT;
+      break;
+    case o + d + d:
+      this.mode = Template.modes.LITERAL;
+      this.source += '    ; __append("' + line.replace(o + d + d, o + d) + '")' + '\n';
+      break;
+    case d + d + c:
+      this.mode = Template.modes.LITERAL;
+      this.source += '    ; __append("' + line.replace(d + d + c, d + c) + '")' + '\n';
+      break;
+    case d + c:
+    case '-' + d + c:
+    case '_' + d + c:
+      if (this.mode == Template.modes.LITERAL) {
+        this._addOutput(line);
+      }
+
+      this.mode = null;
+      this.truncate = line.indexOf('-') === 0 || line.indexOf('_') === 0;
+      break;
+    default:
+      // In script mode, depends on type of tag
+      if (this.mode) {
+        // If '//' is found without a line break, add a line break.
+        switch (this.mode) {
+        case Template.modes.EVAL:
+        case Template.modes.ESCAPED:
+        case Template.modes.RAW:
+          if (line.lastIndexOf('//') > line.lastIndexOf('\n')) {
+            line += '\n';
+          }
+        }
+        switch (this.mode) {
+        // Just executing code
+        case Template.modes.EVAL:
+          this.source += '    ; ' + line + '\n';
+          break;
+          // Exec, esc, and output
+        case Template.modes.ESCAPED:
+          this.source += '    ; __append(escapeFn(' + stripSemi(line) + '))' + '\n';
+          break;
+          // Exec and output
+        case Template.modes.RAW:
+          this.source += '    ; __append(' + stripSemi(line) + ')' + '\n';
+          break;
+        case Template.modes.COMMENT:
+          // Do nothing
+          break;
+          // Literal <%% mode, append as raw output
+        case Template.modes.LITERAL:
+          this._addOutput(line);
+          break;
+        }
+      }
+      // In string mode, just add the output
+      else {
+        this._addOutput(line);
+      }
+    }
+
+    if (self.opts.compileDebug && newLineCount) {
+      this.currentLine += newLineCount;
+      this.source += '    ; __line = ' + this.currentLine + '\n';
+    }
+  }
+};
+
+/**
+ * Escape characters reserved in XML.
+ *
+ * This is simply an export of {@link module:utils.escapeXML}.
+ *
+ * If `markup` is `undefined` or `null`, the empty string is returned.
+ *
+ * @param {String} markup Input string
+ * @return {String} Escaped string
+ * @public
+ * @func
+ * */
+exports.escapeXML = utils.escapeXML;
+
+/**
+ * Express.js support.
+ *
+ * This is an alias for {@link module:ejs.renderFile}, in order to support
+ * Express.js out-of-the-box.
+ *
+ * @func
+ */
+
+exports.__express = exports.renderFile;
+
+/**
+ * Version of EJS.
+ *
+ * @readonly
+ * @type {String}
+ * @public
+ */
+
+exports.VERSION = _VERSION_STRING;
+
+/**
+ * Name for detection of EJS.
+ *
+ * @readonly
+ * @type {String}
+ * @public
+ */
+
+exports.name = _NAME;
+
+/* istanbul ignore if */
+if (typeof window != 'undefined') {
+  window.ejs = exports;
+}
diff --git a/d2d_app/node_modules/ejs/lib/utils.js b/d2d_app/node_modules/ejs/lib/utils.js
new file mode 100644 (file)
index 0000000..284de06
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * EJS Embedded JavaScript templates
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+/**
+ * Private utility functions
+ * @module utils
+ * @private
+ */
+
+'use strict';
+
+var regExpChars = /[|\\{}()[\]^$+*?.]/g;
+
+/**
+ * Escape characters reserved in regular expressions.
+ *
+ * If `string` is `undefined` or `null`, the empty string is returned.
+ *
+ * @param {String} string Input string
+ * @return {String} Escaped string
+ * @static
+ * @private
+ */
+exports.escapeRegExpChars = function (string) {
+  // istanbul ignore if
+  if (!string) {
+    return '';
+  }
+  return String(string).replace(regExpChars, '\\$&');
+};
+
+var _ENCODE_HTML_RULES = {
+  '&': '&amp;',
+  '<': '&lt;',
+  '>': '&gt;',
+  '"': '&#34;',
+  "'": '&#39;'
+};
+var _MATCH_HTML = /[&<>'"]/g;
+
+function encode_char(c) {
+  return _ENCODE_HTML_RULES[c] || c;
+}
+
+/**
+ * Stringified version of constants used by {@link module:utils.escapeXML}.
+ *
+ * It is used in the process of generating {@link ClientFunction}s.
+ *
+ * @readonly
+ * @type {String}
+ */
+
+var escapeFuncStr =
+  'var _ENCODE_HTML_RULES = {\n'
++ '      "&": "&amp;"\n'
++ '    , "<": "&lt;"\n'
++ '    , ">": "&gt;"\n'
++ '    , \'"\': "&#34;"\n'
++ '    , "\'": "&#39;"\n'
++ '    }\n'
++ '  , _MATCH_HTML = /[&<>\'"]/g;\n'
++ 'function encode_char(c) {\n'
++ '  return _ENCODE_HTML_RULES[c] || c;\n'
++ '};\n';
+
+/**
+ * Escape characters reserved in XML.
+ *
+ * If `markup` is `undefined` or `null`, the empty string is returned.
+ *
+ * @implements {EscapeCallback}
+ * @param {String} markup Input string
+ * @return {String} Escaped string
+ * @static
+ * @private
+ */
+
+exports.escapeXML = function (markup) {
+  return markup == undefined
+    ? ''
+    : String(markup)
+      .replace(_MATCH_HTML, encode_char);
+};
+exports.escapeXML.toString = function () {
+  return Function.prototype.toString.call(this) + ';\n' + escapeFuncStr;
+};
+
+/**
+ * Naive copy of properties from one object to another.
+ * Does not recurse into non-scalar properties
+ * Does not check to see if the property has a value before copying
+ *
+ * @param  {Object} to   Destination object
+ * @param  {Object} from Source object
+ * @return {Object}      Destination object
+ * @static
+ * @private
+ */
+exports.shallowCopy = function (to, from) {
+  from = from || {};
+  for (var p in from) {
+    to[p] = from[p];
+  }
+  return to;
+};
+
+/**
+ * Naive copy of a list of key names, from one object to another.
+ * Only copies property if it is actually defined
+ * Does not recurse into non-scalar properties
+ *
+ * @param  {Object} to   Destination object
+ * @param  {Object} from Source object
+ * @param  {Array} list List of properties to copy
+ * @return {Object}      Destination object
+ * @static
+ * @private
+ */
+exports.shallowCopyFromList = function (to, from, list) {
+  for (var i = 0; i < list.length; i++) {
+    var p = list[i];
+    if (typeof from[p] != 'undefined') {
+      to[p] = from[p];
+    }
+  }
+  return to;
+};
+
+/**
+ * Simple in-process cache implementation. Does not implement limits of any
+ * sort.
+ *
+ * @implements {Cache}
+ * @static
+ * @private
+ */
+exports.cache = {
+  _data: {},
+  set: function (key, val) {
+    this._data[key] = val;
+  },
+  get: function (key) {
+    return this._data[key];
+  },
+  remove: function (key) {
+    delete this._data[key];
+  },
+  reset: function () {
+    this._data = {};
+  }
+};
+
+/**
+ * Transforms hyphen case variable into camel case.
+ *
+ * @param {String} string Hyphen case string
+ * @return {String} Camel case string
+ * @static
+ * @private
+ */
+exports.hyphenToCamel = function (str) {
+  return str.replace(/-[a-z]/g, function (match) { return match[1].toUpperCase(); });
+};
diff --git a/d2d_app/node_modules/ejs/package.json b/d2d_app/node_modules/ejs/package.json
new file mode 100644 (file)
index 0000000..92f88a6
--- /dev/null
@@ -0,0 +1,74 @@
+{
+  "_from": "ejs",
+  "_id": "ejs@3.1.6",
+  "_inBundle": false,
+  "_integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
+  "_location": "/ejs",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "ejs",
+    "name": "ejs",
+    "escapedName": "ejs",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
+  "_shasum": "5bfd0a0689743bb5268b3550cceeebbc1702822a",
+  "_spec": "ejs",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen",
+  "author": {
+    "name": "Matthew Eernisse",
+    "email": "mde@fleegix.org",
+    "url": "http://fleegix.org"
+  },
+  "bin": {
+    "ejs": "./bin/cli.js"
+  },
+  "bugs": {
+    "url": "https://github.com/mde/ejs/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "jake": "^10.6.1"
+  },
+  "deprecated": false,
+  "description": "Embedded JavaScript templates",
+  "devDependencies": {
+    "browserify": "^16.5.1",
+    "eslint": "^6.8.0",
+    "git-directory-deploy": "^1.5.1",
+    "jsdoc": "^3.6.4",
+    "lru-cache": "^4.0.1",
+    "mocha": "^7.1.1",
+    "uglify-js": "^3.3.16"
+  },
+  "engines": {
+    "node": ">=0.10.0"
+  },
+  "homepage": "https://github.com/mde/ejs",
+  "jsdelivr": "ejs.min.js",
+  "keywords": [
+    "template",
+    "engine",
+    "ejs"
+  ],
+  "license": "Apache-2.0",
+  "main": "./lib/ejs.js",
+  "name": "ejs",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/mde/ejs.git"
+  },
+  "scripts": {
+    "test": "mocha"
+  },
+  "unpkg": "ejs.min.js",
+  "version": "3.1.6"
+}
diff --git a/d2d_app/node_modules/ejs/usage.txt b/d2d_app/node_modules/ejs/usage.txt
new file mode 100644 (file)
index 0000000..7469f7f
--- /dev/null
@@ -0,0 +1,24 @@
+EJS Embedded JavaScript templates
+{Usage}: ejs [options ...] template-file [data variables ...]
+
+{Options}:
+  -o,     --output-file FILE            Write the rendered output to FILE rather than stdout.
+  -f,     --data-file FILE              Must be JSON-formatted. Use parsed input from FILE as data for rendering.
+  -i,     --data-input STRING           Must be JSON-formatted and URI-encoded. Use parsed input from STRING as data for rendering.
+  -m,     --delimiter CHARACTER         Use CHARACTER with angle brackets for open/close (defaults to %).
+  -p,     --open-delimiter CHARACTER    Use CHARACTER instead of left angle bracket to open.
+  -c,     --close-delimiter CHARACTER   Use CHARACTER instead of right angle bracket to close.
+  -s,     --strict                      When set to `true`, generated function is in strict mode
+  -n      --no-with                     Use 'locals' object for vars rather than using `with` (implies --strict).
+  -l      --locals-name                 Name to use for the object storing local variables when not using `with`.
+  -w      --rm-whitespace               Remove all safe-to-remove whitespace, including leading and trailing whitespace.
+  -d      --debug                       Outputs generated function body
+  -h,     --help                        Display this help message.
+  -V/v,   --version                     Display the EJS version.
+
+{Examples}:
+  ejs -m $ ./test/fixtures/user.ejs -f ./user_data.json
+  ejs -m $ ./test/fixtures/user.ejs name=Lerxst
+  ejs -p [ -c ] ./template_file.ejs -o ./output.html
+  ejs -n -l _ ./some_template.ejs -f ./data_file.json
+  ejs -w ./template_with_whitspace.ejs -o ./output_file.html
diff --git a/d2d_app/node_modules/escape-string-regexp/index.js b/d2d_app/node_modules/escape-string-regexp/index.js
new file mode 100644 (file)
index 0000000..7834bf9
--- /dev/null
@@ -0,0 +1,11 @@
+'use strict';
+
+var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
+
+module.exports = function (str) {
+       if (typeof str !== 'string') {
+               throw new TypeError('Expected a string');
+       }
+
+       return str.replace(matchOperatorsRe, '\\$&');
+};
diff --git a/d2d_app/node_modules/escape-string-regexp/license b/d2d_app/node_modules/escape-string-regexp/license
new file mode 100644 (file)
index 0000000..654d0bf
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/d2d_app/node_modules/escape-string-regexp/package.json b/d2d_app/node_modules/escape-string-regexp/package.json
new file mode 100644 (file)
index 0000000..d8db217
--- /dev/null
@@ -0,0 +1,81 @@
+{
+  "_from": "escape-string-regexp@^1.0.5",
+  "_id": "escape-string-regexp@1.0.5",
+  "_inBundle": false,
+  "_integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+  "_location": "/escape-string-regexp",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "escape-string-regexp@^1.0.5",
+    "name": "escape-string-regexp",
+    "escapedName": "escape-string-regexp",
+    "rawSpec": "^1.0.5",
+    "saveSpec": null,
+    "fetchSpec": "^1.0.5"
+  },
+  "_requiredBy": [
+    "/chalk"
+  ],
+  "_resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+  "_shasum": "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4",
+  "_spec": "escape-string-regexp@^1.0.5",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/chalk",
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "sindresorhus@gmail.com",
+    "url": "sindresorhus.com"
+  },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/escape-string-regexp/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Escape RegExp special characters",
+  "devDependencies": {
+    "ava": "*",
+    "xo": "*"
+  },
+  "engines": {
+    "node": ">=0.8.0"
+  },
+  "files": [
+    "index.js"
+  ],
+  "homepage": "https://github.com/sindresorhus/escape-string-regexp#readme",
+  "keywords": [
+    "escape",
+    "regex",
+    "regexp",
+    "re",
+    "regular",
+    "expression",
+    "string",
+    "str",
+    "special",
+    "characters"
+  ],
+  "license": "MIT",
+  "maintainers": [
+    {
+      "name": "Sindre Sorhus",
+      "email": "sindresorhus@gmail.com",
+      "url": "sindresorhus.com"
+    },
+    {
+      "name": "Joshua Boy Nicolai Appelman",
+      "email": "joshua@jbna.nl",
+      "url": "jbna.nl"
+    }
+  ],
+  "name": "escape-string-regexp",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/sindresorhus/escape-string-regexp.git"
+  },
+  "scripts": {
+    "test": "xo && ava"
+  },
+  "version": "1.0.5"
+}
diff --git a/d2d_app/node_modules/escape-string-regexp/readme.md b/d2d_app/node_modules/escape-string-regexp/readme.md
new file mode 100644 (file)
index 0000000..87ac82d
--- /dev/null
@@ -0,0 +1,27 @@
+# escape-string-regexp [![Build Status](https://travis-ci.org/sindresorhus/escape-string-regexp.svg?branch=master)](https://travis-ci.org/sindresorhus/escape-string-regexp)
+
+> Escape RegExp special characters
+
+
+## Install
+
+```
+$ npm install --save escape-string-regexp
+```
+
+
+## Usage
+
+```js
+const escapeStringRegexp = require('escape-string-regexp');
+
+const escapedString = escapeStringRegexp('how much $ for a unicorn?');
+//=> 'how much \$ for a unicorn\?'
+
+new RegExp(escapedString);
+```
+
+
+## License
+
+MIT © [Sindre Sorhus](http://sindresorhus.com)
diff --git a/d2d_app/node_modules/express-session/HISTORY.md b/d2d_app/node_modules/express-session/HISTORY.md
new file mode 100644 (file)
index 0000000..c5a97fd
--- /dev/null
@@ -0,0 +1,429 @@
+1.17.1 / 2020-04-16
+===================
+
+  * Fix internal method wrapping error on failed reloads
+
+1.17.0 / 2019-10-10
+===================
+
+  * deps: cookie@0.4.0
+    - Add `SameSite=None` support
+  * deps: safe-buffer@5.2.0
+
+1.16.2 / 2019-06-12
+===================
+
+  * Fix restoring `cookie.originalMaxAge` when store returns `Date`
+  * deps: parseurl@~1.3.3
+
+1.16.1 / 2019-04-11
+===================
+
+  * Fix error passing `data` option to `Cookie` constructor
+  * Fix uncaught error from bad session data
+
+1.16.0 / 2019-04-10
+===================
+
+  * Catch invalid `cookie.maxAge` value earlier
+  * Deprecate setting `cookie.maxAge` to a `Date` object
+  * Fix issue where `resave: false` may not save altered sessions
+  * Remove `utils-merge` dependency
+  * Use `safe-buffer` for improved Buffer API
+  * Use `Set-Cookie` as cookie header name for compatibility
+  * deps: depd@~2.0.0
+    - Replace internal `eval` usage with `Function` constructor
+    - Use instance methods on `process` to check for listeners
+    - perf: remove argument reassignment
+  * deps: on-headers@~1.0.2
+    - Fix `res.writeHead` patch missing return value
+
+1.15.6 / 2017-09-26
+===================
+
+  * deps: debug@2.6.9
+  * deps: parseurl@~1.3.2
+    - perf: reduce overhead for full URLs
+    - perf: unroll the "fast-path" `RegExp`
+  * deps: uid-safe@~2.1.5
+    - perf: remove only trailing `=`
+  * deps: utils-merge@1.0.1
+
+1.15.5 / 2017-08-02
+===================
+
+  * Fix `TypeError` when `req.url` is an empty string
+  * deps: depd@~1.1.1
+    - Remove unnecessary `Buffer` loading
+
+1.15.4 / 2017-07-18
+===================
+
+  * deps: debug@2.6.8
+
+1.15.3 / 2017-05-17
+===================
+
+  * deps: debug@2.6.7
+    - deps: ms@2.0.0
+
+1.15.2 / 2017-03-26
+===================
+
+  * deps: debug@2.6.3
+    - Fix `DEBUG_MAX_ARRAY_LENGTH`
+  * deps: uid-safe@~2.1.4
+    - Remove `base64-url` dependency
+
+1.15.1 / 2017-02-10
+===================
+
+  * deps: debug@2.6.1
+    - Fix deprecation messages in WebStorm and other editors
+    - Undeprecate `DEBUG_FD` set to `1` or `2`
+
+1.15.0 / 2017-01-22
+===================
+
+  * Fix detecting modified session when session contains "cookie" property
+  * Fix resaving already-saved reloaded session at end of request
+  * deps: crc@3.4.4
+    - perf: use `Buffer.from` when available
+  * deps: debug@2.6.0
+    - Allow colors in workers
+    - Deprecated `DEBUG_FD` environment variable
+    - Use same color for same namespace
+    - Fix error when running under React Native
+    - deps: ms@0.7.2
+  * perf: remove unreachable branch in set-cookie method
+
+1.14.2 / 2016-10-30
+===================
+
+  * deps: crc@3.4.1
+    - Fix deprecation warning in Node.js 7.x
+  * deps: uid-safe@~2.1.3
+    - deps: base64-url@1.3.3
+
+1.14.1 / 2016-08-24
+===================
+
+  * Fix not always resetting session max age before session save
+  * Fix the cookie `sameSite` option to actually alter the `Set-Cookie`
+  * deps: uid-safe@~2.1.2
+    - deps: base64-url@1.3.2
+
+1.14.0 / 2016-07-01
+===================
+
+  * Correctly inherit from `EventEmitter` class in `Store` base class
+  * Fix issue where `Set-Cookie` `Expires` was not always updated
+  * Methods are no longer enumerable on `req.session` object
+  * deps: cookie@0.3.1
+    - Add `sameSite` option
+    - Improve error message when `encode` is not a function
+    - Improve error message when `expires` is not a `Date`
+    - perf: enable strict mode
+    - perf: use for loop in parse
+    - perf: use string concatination for serialization
+  * deps: parseurl@~1.3.1
+    - perf: enable strict mode
+  * deps: uid-safe@~2.1.1
+    - Use `random-bytes` for byte source
+    - deps: base64-url@1.2.2
+  * perf: enable strict mode
+  * perf: remove argument reassignment
+
+1.13.0 / 2016-01-10
+===================
+
+  * Fix `rolling: true` to not set cookie when no session exists
+    - Better `saveUninitialized: false` + `rolling: true` behavior
+  * deps: crc@3.4.0
+
+1.12.1 / 2015-10-29
+===================
+
+  * deps: cookie@0.2.3
+    - Fix cookie `Max-Age` to never be a floating point number
+
+1.12.0 / 2015-10-25
+===================
+
+  * Support the value `'auto'` in the `cookie.secure` option
+  * deps: cookie@0.2.2
+    - Throw on invalid values provided to `serialize`
+  * deps: depd@~1.1.0
+    - Enable strict mode in more places
+    - Support web browser loading
+  * deps: on-headers@~1.0.1
+    - perf: enable strict mode
+
+1.11.3 / 2015-05-22
+===================
+
+  * deps: cookie@0.1.3
+    - Slight optimizations
+  * deps: crc@3.3.0
+
+1.11.2 / 2015-05-10
+===================
+
+  * deps: debug@~2.2.0
+    - deps: ms@0.7.1
+  * deps: uid-safe@~2.0.0
+
+1.11.1 / 2015-04-08
+===================
+
+  * Fix mutating `options.secret` value
+
+1.11.0 / 2015-04-07
+===================
+
+  * Support an array in `secret` option for key rotation
+  * deps: depd@~1.0.1
+
+1.10.4 / 2015-03-15
+===================
+
+  * deps: debug@~2.1.3
+    - Fix high intensity foreground color for bold
+    - deps: ms@0.7.0
+
+1.10.3 / 2015-02-16
+===================
+
+  * deps: cookie-signature@1.0.6
+  * deps: uid-safe@1.1.0
+    - Use `crypto.randomBytes`, if available
+    - deps: base64-url@1.2.1
+
+1.10.2 / 2015-01-31
+===================
+
+  * deps: uid-safe@1.0.3
+    - Fix error branch that would throw
+    - deps: base64-url@1.2.0
+
+1.10.1 / 2015-01-08
+===================
+
+  * deps: uid-safe@1.0.2
+    - Remove dependency on `mz`
+
+1.10.0 / 2015-01-05
+===================
+
+  * Add `store.touch` interface for session stores
+  * Fix `MemoryStore` expiration with `resave: false`
+  * deps: debug@~2.1.1
+
+1.9.3 / 2014-12-02
+==================
+
+  * Fix error when `req.sessionID` contains a non-string value
+
+1.9.2 / 2014-11-22
+==================
+
+  * deps: crc@3.2.1
+    - Minor fixes
+
+1.9.1 / 2014-10-22
+==================
+
+  * Remove unnecessary empty write call
+    - Fixes Node.js 0.11.14 behavior change
+    - Helps work-around Node.js 0.10.1 zlib bug
+
+1.9.0 / 2014-09-16
+==================
+
+  * deps: debug@~2.1.0
+    - Implement `DEBUG_FD` env variable support
+  * deps: depd@~1.0.0
+
+1.8.2 / 2014-09-15
+==================
+
+  * Use `crc` instead of `buffer-crc32` for speed
+  * deps: depd@0.4.5
+
+1.8.1 / 2014-09-08
+==================
+
+  * Keep `req.session.save` non-enumerable
+  * Prevent session prototype methods from being overwritten
+
+1.8.0 / 2014-09-07
+==================
+
+  * Do not resave already-saved session at end of request
+  * deps: cookie-signature@1.0.5
+  * deps: debug@~2.0.0
+
+1.7.6 / 2014-08-18
+==================
+
+  * Fix exception on `res.end(null)` calls
+
+1.7.5 / 2014-08-10
+==================
+
+  * Fix parsing original URL
+  * deps: on-headers@~1.0.0
+  * deps: parseurl@~1.3.0
+
+1.7.4 / 2014-08-05
+==================
+
+  * Fix response end delay for non-chunked responses
+
+1.7.3 / 2014-08-05
+==================
+
+  * Fix `res.end` patch to call correct upstream `res.write`
+
+1.7.2 / 2014-07-27
+==================
+
+  * deps: depd@0.4.4
+    - Work-around v8 generating empty stack traces
+
+1.7.1 / 2014-07-26
+==================
+
+  * deps: depd@0.4.3
+    - Fix exception when global `Error.stackTraceLimit` is too low
+
+1.7.0 / 2014-07-22
+==================
+
+  * Improve session-ending error handling
+    - Errors are passed to `next(err)` instead of `console.error`
+  * deps: debug@1.0.4
+  * deps: depd@0.4.2
+    - Add `TRACE_DEPRECATION` environment variable
+    - Remove non-standard grey color from color output
+    - Support `--no-deprecation` argument
+    - Support `--trace-deprecation` argument
+
+1.6.5 / 2014-07-11
+==================
+
+  * Do not require `req.originalUrl`
+  * deps: debug@1.0.3
+    - Add support for multiple wildcards in namespaces
+
+1.6.4 / 2014-07-07
+==================
+
+  * Fix blank responses for stores with synchronous operations
+
+1.6.3 / 2014-07-04
+==================
+
+  * Fix resave deprecation message
+
+1.6.2 / 2014-07-04
+==================
+
+  * Fix confusing option deprecation messages
+
+1.6.1 / 2014-06-28
+==================
+
+  * Fix saveUninitialized deprecation message
+
+1.6.0 / 2014-06-28
+==================
+
+  * Add deprecation message to undefined `resave` option
+  * Add deprecation message to undefined `saveUninitialized` option
+  * Fix `res.end` patch to return correct value
+  * Fix `res.end` patch to handle multiple `res.end` calls
+  * Reject cookies with missing signatures
+
+1.5.2 / 2014-06-26
+==================
+
+  * deps: cookie-signature@1.0.4
+    - fix for timing attacks
+
+1.5.1 / 2014-06-21
+==================
+
+  * Move hard-to-track-down `req.secret` deprecation message
+
+1.5.0 / 2014-06-19
+==================
+
+  * Debug name is now "express-session"
+  * Deprecate integration with `cookie-parser` middleware
+  * Deprecate looking for secret in `req.secret`
+  * Directly read cookies; `cookie-parser` no longer required
+  * Directly set cookies; `res.cookie` no longer required
+  * Generate session IDs with `uid-safe`, faster and even less collisions
+
+1.4.0 / 2014-06-17
+==================
+
+  * Add `genid` option to generate custom session IDs
+  * Add `saveUninitialized` option to control saving uninitialized sessions
+  * Add `unset` option to control unsetting `req.session`
+  * Generate session IDs with `rand-token` by default; reduce collisions
+  * deps: buffer-crc32@0.2.3
+
+1.3.1 / 2014-06-14
+==================
+
+  * Add description in package for npmjs.org listing
+
+1.3.0 / 2014-06-14
+==================
+
+  * Integrate with express "trust proxy" by default
+  * deps: debug@1.0.2
+
+1.2.1 / 2014-05-27
+==================
+
+  * Fix `resave` such that `resave: true` works
+
+1.2.0 / 2014-05-19
+==================
+
+  * Add `resave` option to control saving unmodified sessions
+
+1.1.0 / 2014-05-12
+==================
+
+  * Add `name` option; replacement for `key` option
+  * Use `setImmediate` in MemoryStore for node.js >= 0.10
+
+1.0.4 / 2014-04-27
+==================
+
+  * deps: debug@0.8.1
+
+1.0.3 / 2014-04-19
+==================
+
+  *  Use `res.cookie()` instead of `res.setHeader()`
+  * deps: cookie@0.1.2
+
+1.0.2 / 2014-02-23
+==================
+
+  * Add missing dependency to `package.json`
+
+1.0.1 / 2014-02-15
+==================
+
+  * Add missing dependencies to `package.json`
+
+1.0.0 / 2014-02-15
+==================
+
+  * Genesis from `connect`
diff --git a/d2d_app/node_modules/express-session/LICENSE b/d2d_app/node_modules/express-session/LICENSE
new file mode 100644 (file)
index 0000000..9b59ff8
--- /dev/null
@@ -0,0 +1,24 @@
+(The MIT License)
+
+Copyright (c) 2010 Sencha Inc.
+Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
+Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/express-session/README.md b/d2d_app/node_modules/express-session/README.md
new file mode 100644 (file)
index 0000000..fe5076d
--- /dev/null
@@ -0,0 +1,862 @@
+# express-session
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][node-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install express-session
+```
+
+## API
+
+```js
+var session = require('express-session')
+```
+
+### session(options)
+
+Create a session middleware with the given `options`.
+
+**Note** Session data is _not_ saved in the cookie itself, just the session ID.
+Session data is stored server-side.
+
+**Note** Since version 1.5.0, the [`cookie-parser` middleware](https://www.npmjs.com/package/cookie-parser)
+no longer needs to be used for this module to work. This module now directly reads
+and writes cookies on `req`/`res`. Using `cookie-parser` may result in issues
+if the `secret` is not the same between this module and `cookie-parser`.
+
+**Warning** The default server-side session storage, `MemoryStore`, is _purposely_
+not designed for a production environment. It will leak memory under most
+conditions, does not scale past a single process, and is meant for debugging and
+developing.
+
+For a list of stores, see [compatible session stores](#compatible-session-stores).
+
+#### Options
+
+`express-session` accepts these properties in the options object.
+
+##### cookie
+
+Settings object for the session ID cookie. The default value is
+`{ path: '/', httpOnly: true, secure: false, maxAge: null }`.
+
+The following are options that can be set in this object.
+
+##### cookie.domain
+
+Specifies the value for the `Domain` `Set-Cookie` attribute. By default, no domain
+is set, and most clients will consider the cookie to apply to only the current
+domain.
+
+##### cookie.expires
+
+Specifies the `Date` object to be the value for the `Expires` `Set-Cookie` attribute.
+By default, no expiration is set, and most clients will consider this a
+"non-persistent cookie" and will delete it on a condition like exiting a web browser
+application.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+**Note** The `expires` option should not be set directly; instead only use the `maxAge`
+option.
+
+##### cookie.httpOnly
+
+Specifies the `boolean` value for the `HttpOnly` `Set-Cookie` attribute. When truthy,
+the `HttpOnly` attribute is set, otherwise it is not. By default, the `HttpOnly`
+attribute is set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not allow
+client-side JavaScript to see the cookie in `document.cookie`.
+
+##### cookie.maxAge
+
+Specifies the `number` (in milliseconds) to use when calculating the `Expires`
+`Set-Cookie` attribute. This is done by taking the current server time and adding
+`maxAge` milliseconds to the value to calculate an `Expires` datetime. By default,
+no maximum age is set.
+
+**Note** If both `expires` and `maxAge` are set in the options, then the last one
+defined in the object is what is used.
+
+##### cookie.path
+
+Specifies the value for the `Path` `Set-Cookie`. By default, this is set to `'/'`, which
+is the root path of the domain.
+
+##### cookie.sameSite
+
+Specifies the `boolean` or `string` to be the value for the `SameSite` `Set-Cookie` attribute.
+
+  - `true` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+  - `false` will not set the `SameSite` attribute.
+  - `'lax'` will set the `SameSite` attribute to `Lax` for lax same site enforcement.
+  - `'none'` will set the `SameSite` attribute to `None` for an explicit cross-site cookie.
+  - `'strict'` will set the `SameSite` attribute to `Strict` for strict same site enforcement.
+
+More information about the different enforcement levels can be found in
+[the specification][rfc-6265bis-03-4.1.2.7].
+
+**Note** This is an attribute that has not yet been fully standardized, and may change in
+the future. This also means many clients may ignore this attribute until they understand it.
+
+##### cookie.secure
+
+Specifies the `boolean` value for the `Secure` `Set-Cookie` attribute. When truthy,
+the `Secure` attribute is set, otherwise it is not. By default, the `Secure`
+attribute is not set.
+
+**Note** be careful when setting this to `true`, as compliant clients will not send
+the cookie back to the server in the future if the browser does not have an HTTPS
+connection.
+
+Please note that `secure: true` is a **recommended** option. However, it requires
+an https-enabled website, i.e., HTTPS is necessary for secure cookies. If `secure`
+is set, and you access your site over HTTP, the cookie will not be set. If you
+have your node.js behind a proxy and are using `secure: true`, you need to set
+"trust proxy" in express:
+
+```js
+var app = express()
+app.set('trust proxy', 1) // trust first proxy
+app.use(session({
+  secret: 'keyboard cat',
+  resave: false,
+  saveUninitialized: true,
+  cookie: { secure: true }
+}))
+```
+
+For using secure cookies in production, but allowing for testing in development,
+the following is an example of enabling this setup based on `NODE_ENV` in express:
+
+```js
+var app = express()
+var sess = {
+  secret: 'keyboard cat',
+  cookie: {}
+}
+
+if (app.get('env') === 'production') {
+  app.set('trust proxy', 1) // trust first proxy
+  sess.cookie.secure = true // serve secure cookies
+}
+
+app.use(session(sess))
+```
+
+The `cookie.secure` option can also be set to the special value `'auto'` to have
+this setting automatically match the determined security of the connection. Be
+careful when using this setting if the site is available both as HTTP and HTTPS,
+as once the cookie is set on HTTPS, it will no longer be visible over HTTP. This
+is useful when the Express `"trust proxy"` setting is properly setup to simplify
+development vs production configuration.
+
+##### genid
+
+Function to call to generate a new session ID. Provide a function that returns
+a string that will be used as a session ID. The function is given `req` as the
+first argument if you want to use some value attached to `req` when generating
+the ID.
+
+The default value is a function which uses the `uid-safe` library to generate IDs.
+
+**NOTE** be careful to generate unique IDs so your sessions do not conflict.
+
+```js
+app.use(session({
+  genid: function(req) {
+    return genuuid() // use UUIDs for session IDs
+  },
+  secret: 'keyboard cat'
+}))
+```
+
+##### name
+
+The name of the session ID cookie to set in the response (and read from in the
+request).
+
+The default value is `'connect.sid'`.
+
+**Note** if you have multiple apps running on the same hostname (this is just
+the name, i.e. `localhost` or `127.0.0.1`; different schemes and ports do not
+name a different hostname), then you need to separate the session cookies from
+each other. The simplest method is to simply set different `name`s per app.
+
+##### proxy
+
+Trust the reverse proxy when setting secure cookies (via the "X-Forwarded-Proto"
+header).
+
+The default value is `undefined`.
+
+  - `true` The "X-Forwarded-Proto" header will be used.
+  - `false` All headers are ignored and the connection is considered secure only
+    if there is a direct TLS/SSL connection.
+  - `undefined` Uses the "trust proxy" setting from express
+
+##### resave
+
+Forces the session to be saved back to the session store, even if the session
+was never modified during the request. Depending on your store this may be
+necessary, but it can also create race conditions where a client makes two
+parallel requests to your server and changes made to the session in one
+request may get overwritten when the other request ends, even if it made no
+changes (this behavior also depends on what store you're using).
+
+The default value is `true`, but using the default has been deprecated,
+as the default will change in the future. Please research into this setting
+and choose what is appropriate to your use-case. Typically, you'll want
+`false`.
+
+How do I know if this is necessary for my store? The best way to know is to
+check with your store if it implements the `touch` method. If it does, then
+you can safely set `resave: false`. If it does not implement the `touch`
+method and your store sets an expiration date on stored sessions, then you
+likely need `resave: true`.
+
+##### rolling
+
+Force the session identifier cookie to be set on every response. The expiration
+is reset to the original [`maxAge`](#cookiemaxage), resetting the expiration
+countdown.
+
+The default value is `false`.
+
+With this enabled, the session identifier cookie will expire in
+[`maxAge`](#cookiemaxage) since the last response was sent instead of in
+[`maxAge`](#cookiemaxage) since the session was last modified by the server.
+
+This is typically used in conjuction with short, non-session-length
+[`maxAge`](#cookiemaxage) values to provide a quick timeout of the session data
+with reduced potentional of it occurring during on going server interactions.
+
+**Note** When this option is set to `true` but the `saveUninitialized` option is
+set to `false`, the cookie will not be set on a response with an uninitialized
+session. This option only modifies the behavior when an existing session was
+loaded for the request.
+
+##### saveUninitialized
+
+Forces a session that is "uninitialized" to be saved to the store. A session is
+uninitialized when it is new but not modified. Choosing `false` is useful for
+implementing login sessions, reducing server storage usage, or complying with
+laws that require permission before setting a cookie. Choosing `false` will also
+help with race conditions where a client makes multiple parallel requests
+without a session.
+
+The default value is `true`, but using the default has been deprecated, as the
+default will change in the future. Please research into this setting and
+choose what is appropriate to your use-case.
+
+**Note** if you are using Session in conjunction with PassportJS, Passport
+will add an empty Passport object to the session for use after a user is
+authenticated, which will be treated as a modification to the session, causing
+it to be saved. *This has been fixed in PassportJS 0.3.0*
+
+##### secret
+
+**Required option**
+
+This is the secret used to sign the session ID cookie. This can be either a string
+for a single secret, or an array of multiple secrets. If an array of secrets is
+provided, only the first element will be used to sign the session ID cookie, while
+all the elements will be considered when verifying the signature in requests.
+
+##### store
+
+The session store instance, defaults to a new `MemoryStore` instance.
+
+##### unset
+
+Control the result of unsetting `req.session` (through `delete`, setting to `null`,
+etc.).
+
+The default value is `'keep'`.
+
+  - `'destroy'` The session will be destroyed (deleted) when the response ends.
+  - `'keep'` The session in the store will be kept, but modifications made during
+    the request are ignored and not saved.
+
+### req.session
+
+To store or access session data, simply use the request property `req.session`,
+which is (generally) serialized as JSON by the store, so nested objects
+are typically fine. For example below is a user-specific view counter:
+
+```js
+// Use the session middleware
+app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
+
+// Access the session as req.session
+app.get('/', function(req, res, next) {
+  if (req.session.views) {
+    req.session.views++
+    res.setHeader('Content-Type', 'text/html')
+    res.write('<p>views: ' + req.session.views + '</p>')
+    res.write('<p>expires in: ' + (req.session.cookie.maxAge / 1000) + 's</p>')
+    res.end()
+  } else {
+    req.session.views = 1
+    res.end('welcome to the session demo. refresh!')
+  }
+})
+```
+
+#### Session.regenerate(callback)
+
+To regenerate the session simply invoke the method. Once complete,
+a new SID and `Session` instance will be initialized at `req.session`
+and the `callback` will be invoked.
+
+```js
+req.session.regenerate(function(err) {
+  // will have a new session here
+})
+```
+
+#### Session.destroy(callback)
+
+Destroys the session and will unset the `req.session` property.
+Once complete, the `callback` will be invoked.
+
+```js
+req.session.destroy(function(err) {
+  // cannot access session here
+})
+```
+
+#### Session.reload(callback)
+
+Reloads the session data from the store and re-populates the
+`req.session` object. Once complete, the `callback` will be invoked.
+
+```js
+req.session.reload(function(err) {
+  // session updated
+})
+```
+
+#### Session.save(callback)
+
+Save the session back to the store, replacing the contents on the store with the
+contents in memory (though a store may do something else--consult the store's
+documentation for exact behavior).
+
+This method is automatically called at the end of the HTTP response if the
+session data has been altered (though this behavior can be altered with various
+options in the middleware constructor). Because of this, typically this method
+does not need to be called.
+
+There are some cases where it is useful to call this method, for example,
+redirects, long-lived requests or in WebSockets.
+
+```js
+req.session.save(function(err) {
+  // session saved
+})
+```
+
+#### Session.touch()
+
+Updates the `.maxAge` property. Typically this is
+not necessary to call, as the session middleware does this for you.
+
+### req.session.id
+
+Each session has a unique ID associated with it. This property is an
+alias of [`req.sessionID`](#reqsessionid-1) and cannot be modified.
+It has been added to make the session ID accessible from the `session`
+object.
+
+### req.session.cookie
+
+Each session has a unique cookie object accompany it. This allows
+you to alter the session cookie per visitor. For example we can
+set `req.session.cookie.expires` to `false` to enable the cookie
+to remain for only the duration of the user-agent.
+
+#### Cookie.maxAge
+
+Alternatively `req.session.cookie.maxAge` will return the time
+remaining in milliseconds, which we may also re-assign a new value
+to adjust the `.expires` property appropriately. The following
+are essentially equivalent
+
+```js
+var hour = 3600000
+req.session.cookie.expires = new Date(Date.now() + hour)
+req.session.cookie.maxAge = hour
+```
+
+For example when `maxAge` is set to `60000` (one minute), and 30 seconds
+has elapsed it will return `30000` until the current request has completed,
+at which time `req.session.touch()` is called to reset
+`req.session.cookie.maxAge` to its original value.
+
+```js
+req.session.cookie.maxAge // => 30000
+```
+
+#### Cookie.originalMaxAge
+
+The `req.session.cookie.originalMaxAge` property returns the original
+`maxAge` (time-to-live), in milliseconds, of the session cookie.
+
+### req.sessionID
+
+To get the ID of the loaded session, access the request property
+`req.sessionID`. This is simply a read-only value set when a session
+is loaded/created.
+
+## Session Store Implementation
+
+Every session store _must_ be an `EventEmitter` and implement specific
+methods. The following methods are the list of **required**, **recommended**,
+and **optional**.
+
+  * Required methods are ones that this module will always call on the store.
+  * Recommended methods are ones that this module will call on the store if
+    available.
+  * Optional methods are ones this module does not call at all, but helps
+    present uniform stores to users.
+
+For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
+
+### store.all(callback)
+
+**Optional**
+
+This optional method is used to get all sessions in the store as an array. The
+`callback` should be called as `callback(error, sessions)`.
+
+### store.destroy(sid, callback)
+
+**Required**
+
+This required method is used to destroy/delete a session from the store given
+a session ID (`sid`). The `callback` should be called as `callback(error)` once
+the session is destroyed.
+
+### store.clear(callback)
+
+**Optional**
+
+This optional method is used to delete all sessions from the store. The
+`callback` should be called as `callback(error)` once the store is cleared.
+
+### store.length(callback)
+
+**Optional**
+
+This optional method is used to get the count of all sessions in the store.
+The `callback` should be called as `callback(error, len)`.
+
+### store.get(sid, callback)
+
+**Required**
+
+This required method is used to get a session from the store given a session
+ID (`sid`). The `callback` should be called as `callback(error, session)`.
+
+The `session` argument should be a session if found, otherwise `null` or
+`undefined` if the session was not found (and there was no error). A special
+case is made when `error.code === 'ENOENT'` to act like `callback(null, null)`.
+
+### store.set(sid, session, callback)
+
+**Required**
+
+This required method is used to upsert a session into the store given a
+session ID (`sid`) and session (`session`) object. The callback should be
+called as `callback(error)` once the session has been set in the store.
+
+### store.touch(sid, session, callback)
+
+**Recommended**
+
+This recommended method is used to "touch" a given session given a
+session ID (`sid`) and session (`session`) object. The `callback` should be
+called as `callback(error)` once the session has been touched.
+
+This is primarily used when the store will automatically delete idle sessions
+and this method is used to signal to the store the given session is active,
+potentially resetting the idle timer.
+
+## Compatible Session Stores
+
+The following modules implement a session store that is compatible with this
+module. Please make a PR to add additional modules :)
+
+[![★][aerospike-session-store-image] aerospike-session-store][aerospike-session-store-url] A session store using [Aerospike](http://www.aerospike.com/).
+
+[aerospike-session-store-url]: https://www.npmjs.com/package/aerospike-session-store
+[aerospike-session-store-image]: https://badgen.net/github/stars/aerospike/aerospike-session-store-expressjs?label=%E2%98%85
+
+[![★][cassandra-store-image] cassandra-store][cassandra-store-url] An Apache Cassandra-based session store.
+
+[cassandra-store-url]: https://www.npmjs.com/package/cassandra-store
+[cassandra-store-image]: https://badgen.net/github/stars/webcc/cassandra-store?label=%E2%98%85
+
+[![★][cluster-store-image] cluster-store][cluster-store-url] A wrapper for using in-process / embedded
+stores - such as SQLite (via knex), leveldb, files, or memory - with node cluster (desirable for Raspberry Pi 2
+and other multi-core embedded devices).
+
+[cluster-store-url]: https://www.npmjs.com/package/cluster-store
+[cluster-store-image]: https://badgen.net/github/stars/coolaj86/cluster-store?label=%E2%98%85
+
+[![★][connect-arango-image] connect-arango][connect-arango-url] An ArangoDB-based session store.
+
+[connect-arango-url]: https://www.npmjs.com/package/connect-arango
+[connect-arango-image]: https://badgen.net/github/stars/AlexanderArvidsson/connect-arango?label=%E2%98%85
+
+[![★][connect-azuretables-image] connect-azuretables][connect-azuretables-url] An [Azure Table Storage](https://azure.microsoft.com/en-gb/services/storage/tables/)-based session store.
+
+[connect-azuretables-url]: https://www.npmjs.com/package/connect-azuretables
+[connect-azuretables-image]: https://badgen.net/github/stars/mike-goodwin/connect-azuretables?label=%E2%98%85
+
+[![★][connect-cloudant-store-image] connect-cloudant-store][connect-cloudant-store-url] An [IBM Cloudant](https://cloudant.com/)-based session store.
+
+[connect-cloudant-store-url]: https://www.npmjs.com/package/connect-cloudant-store
+[connect-cloudant-store-image]: https://badgen.net/github/stars/adriantanasa/connect-cloudant-store?label=%E2%98%85
+
+[![★][connect-couchbase-image] connect-couchbase][connect-couchbase-url] A [couchbase](http://www.couchbase.com/)-based session store.
+
+[connect-couchbase-url]: https://www.npmjs.com/package/connect-couchbase
+[connect-couchbase-image]: https://badgen.net/github/stars/christophermina/connect-couchbase?label=%E2%98%85
+
+[![★][connect-datacache-image] connect-datacache][connect-datacache-url] An [IBM Bluemix Data Cache](http://www.ibm.com/cloud-computing/bluemix/)-based session store.
+
+[connect-datacache-url]: https://www.npmjs.com/package/connect-datacache
+[connect-datacache-image]: https://badgen.net/github/stars/adriantanasa/connect-datacache?label=%E2%98%85
+
+[![★][@google-cloud/connect-datastore-image] @google-cloud/connect-datastore][@google-cloud/connect-datastore-url] A [Google Cloud Datastore](https://cloud.google.com/datastore/docs/concepts/overview)-based session store.
+
+[@google-cloud/connect-datastore-url]: https://www.npmjs.com/package/@google-cloud/connect-datastore
+[@google-cloud/connect-datastore-image]: https://badgen.net/github/stars/GoogleCloudPlatform/cloud-datastore-session-node?label=%E2%98%85
+
+[![★][connect-db2-image] connect-db2][connect-db2-url] An IBM DB2-based session store built using [ibm_db](https://www.npmjs.com/package/ibm_db) module.
+
+[connect-db2-url]: https://www.npmjs.com/package/connect-db2
+[connect-db2-image]: https://badgen.net/github/stars/wallali/connect-db2?label=%E2%98%85
+
+[![★][connect-dynamodb-image] connect-dynamodb][connect-dynamodb-url] A DynamoDB-based session store.
+
+[connect-dynamodb-url]: https://www.npmjs.com/package/connect-dynamodb
+[connect-dynamodb-image]: https://badgen.net/github/stars/ca98am79/connect-dynamodb?label=%E2%98%85
+
+[![★][@google-cloud/connect-firestore-image] @google-cloud/connect-firestore][@google-cloud/connect-firestore-url] A [Google Cloud Firestore](https://cloud.google.com/firestore/docs/overview)-based session store.
+
+[@google-cloud/connect-firestore-url]: https://www.npmjs.com/package/@google-cloud/connect-firestore
+[@google-cloud/connect-firestore-image]: https://badgen.net/github/stars/googleapis/nodejs-firestore-session?label=%E2%98%85
+
+[![★][connect-hazelcast-image] connect-hazelcast][connect-hazelcast-url] Hazelcast session store for Connect and Express.
+
+[connect-hazelcast-url]: https://www.npmjs.com/package/connect-hazelcast
+[connect-hazelcast-image]: https://badgen.net/github/stars/huseyinbabal/connect-hazelcast?label=%E2%98%85
+
+[![★][connect-loki-image] connect-loki][connect-loki-url] A Loki.js-based session store.
+
+[connect-loki-url]: https://www.npmjs.com/package/connect-loki
+[connect-loki-image]: https://badgen.net/github/stars/Requarks/connect-loki?label=%E2%98%85
+
+[![★][connect-memcached-image] connect-memcached][connect-memcached-url] A memcached-based session store.
+
+[connect-memcached-url]: https://www.npmjs.com/package/connect-memcached
+[connect-memcached-image]: https://badgen.net/github/stars/balor/connect-memcached?label=%E2%98%85
+
+[![★][connect-memjs-image] connect-memjs][connect-memjs-url] A memcached-based session store using
+[memjs](https://www.npmjs.com/package/memjs) as the memcached client.
+
+[connect-memjs-url]: https://www.npmjs.com/package/connect-memjs
+[connect-memjs-image]: https://badgen.net/github/stars/liamdon/connect-memjs?label=%E2%98%85
+
+[![★][connect-ml-image] connect-ml][connect-ml-url] A MarkLogic Server-based session store.
+
+[connect-ml-url]: https://www.npmjs.com/package/connect-ml
+[connect-ml-image]: https://badgen.net/github/stars/bluetorch/connect-ml?label=%E2%98%85
+
+[![★][connect-monetdb-image] connect-monetdb][connect-monetdb-url] A MonetDB-based session store.
+
+[connect-monetdb-url]: https://www.npmjs.com/package/connect-monetdb
+[connect-monetdb-image]: https://badgen.net/github/stars/MonetDB/npm-connect-monetdb?label=%E2%98%85
+
+[![★][connect-mongo-image] connect-mongo][connect-mongo-url] A MongoDB-based session store.
+
+[connect-mongo-url]: https://www.npmjs.com/package/connect-mongo
+[connect-mongo-image]: https://badgen.net/github/stars/kcbanner/connect-mongo?label=%E2%98%85
+
+[![★][connect-mongodb-session-image] connect-mongodb-session][connect-mongodb-session-url] Lightweight MongoDB-based session store built and maintained by MongoDB.
+
+[connect-mongodb-session-url]: https://www.npmjs.com/package/connect-mongodb-session
+[connect-mongodb-session-image]: https://badgen.net/github/stars/mongodb-js/connect-mongodb-session?label=%E2%98%85
+
+[![★][connect-mssql-image] connect-mssql][connect-mssql-url] A SQL Server-based session store.
+
+[connect-mssql-url]: https://www.npmjs.com/package/connect-mssql
+[connect-mssql-image]: https://badgen.net/github/stars/patriksimek/connect-mssql?label=%E2%98%85
+
+[![★][connect-pg-simple-image] connect-pg-simple][connect-pg-simple-url] A PostgreSQL-based session store.
+
+[connect-pg-simple-url]: https://www.npmjs.com/package/connect-pg-simple
+[connect-pg-simple-image]: https://badgen.net/github/stars/voxpelli/node-connect-pg-simple?label=%E2%98%85
+
+[![★][connect-redis-image] connect-redis][connect-redis-url] A Redis-based session store.
+
+[connect-redis-url]: https://www.npmjs.com/package/connect-redis
+[connect-redis-image]: https://badgen.net/github/stars/tj/connect-redis?label=%E2%98%85
+
+[![★][connect-session-firebase-image] connect-session-firebase][connect-session-firebase-url] A session store based on the [Firebase Realtime Database](https://firebase.google.com/docs/database/)
+
+[connect-session-firebase-url]: https://www.npmjs.com/package/connect-session-firebase
+[connect-session-firebase-image]: https://badgen.net/github/stars/benweier/connect-session-firebase?label=%E2%98%85
+
+[![★][connect-session-knex-image] connect-session-knex][connect-session-knex-url] A session store using
+[Knex.js](http://knexjs.org/), which is a SQL query builder for PostgreSQL, MySQL, MariaDB, SQLite3, and Oracle.
+
+[connect-session-knex-url]: https://www.npmjs.com/package/connect-session-knex
+[connect-session-knex-image]: https://badgen.net/github/stars/llambda/connect-session-knex?label=%E2%98%85
+
+[![★][connect-session-sequelize-image] connect-session-sequelize][connect-session-sequelize-url] A session store using
+[Sequelize.js](http://sequelizejs.com/), which is a Node.js / io.js ORM for PostgreSQL, MySQL, SQLite and MSSQL.
+
+[connect-session-sequelize-url]: https://www.npmjs.com/package/connect-session-sequelize
+[connect-session-sequelize-image]: https://badgen.net/github/stars/mweibel/connect-session-sequelize?label=%E2%98%85
+
+[![★][connect-sqlite3-image] connect-sqlite3][connect-sqlite3-url] A [SQLite3](https://github.com/mapbox/node-sqlite3) session store modeled after the TJ's `connect-redis` store.
+
+[connect-sqlite3-url]: https://www.npmjs.com/package/connect-sqlite3
+[connect-sqlite3-image]: https://badgen.net/github/stars/rawberg/connect-sqlite3?label=%E2%98%85
+
+[![★][connect-typeorm-image] connect-typeorm][connect-typeorm-url] A [TypeORM](https://github.com/typeorm/typeorm)-based session store.
+
+[connect-typeorm-url]: https://www.npmjs.com/package/connect-typeorm
+[connect-typeorm-image]: https://badgen.net/github/stars/makepost/connect-typeorm?label=%E2%98%85
+
+[![★][couchdb-expression-image] couchdb-expression][couchdb-expression-url] A [CouchDB](https://couchdb.apache.org/)-based session store.
+
+[couchdb-expression-url]: https://www.npmjs.com/package/couchdb-expression
+[couchdb-expression-image]: https://badgen.net/github/stars/tkshnwesper/couchdb-expression?label=%E2%98%85
+
+[![★][documentdb-session-image] documentdb-session][documentdb-session-url] A session store for Microsoft Azure's [DocumentDB](https://azure.microsoft.com/en-us/services/documentdb/) NoSQL database service.
+
+[documentdb-session-url]: https://www.npmjs.com/package/documentdb-session
+[documentdb-session-image]: https://badgen.net/github/stars/dwhieb/documentdb-session?label=%E2%98%85
+
+[![★][dynamodb-store-image] dynamodb-store][dynamodb-store-url] A DynamoDB-based session store.
+
+[dynamodb-store-url]: https://www.npmjs.com/package/dynamodb-store
+[dynamodb-store-image]: https://badgen.net/github/stars/rafaelrpinto/dynamodb-store?label=%E2%98%85
+
+[![★][express-etcd-image] express-etcd][express-etcd-url] An [etcd](https://github.com/stianeikeland/node-etcd) based session store.
+
+[express-etcd-url]: https://www.npmjs.com/package/express-etcd
+[express-etcd-image]: https://badgen.net/github/stars/gildean/express-etcd?label=%E2%98%85
+
+[![★][express-mysql-session-image] express-mysql-session][express-mysql-session-url] A session store using native
+[MySQL](https://www.mysql.com/) via the [node-mysql](https://github.com/felixge/node-mysql) module.
+
+[express-mysql-session-url]: https://www.npmjs.com/package/express-mysql-session
+[express-mysql-session-image]: https://badgen.net/github/stars/chill117/express-mysql-session?label=%E2%98%85
+
+[![★][express-nedb-session-image] express-nedb-session][express-nedb-session-url] A NeDB-based session store.
+
+[express-nedb-session-url]: https://www.npmjs.com/package/express-nedb-session
+[express-nedb-session-image]: https://badgen.net/github/stars/louischatriot/express-nedb-session?label=%E2%98%85
+
+[![★][express-oracle-session-image] express-oracle-session][express-oracle-session-url] A session store using native
+[oracle](https://www.oracle.com/) via the [node-oracledb](https://www.npmjs.com/package/oracledb) module.
+
+[express-oracle-session-url]: https://www.npmjs.com/package/express-oracle-session
+[express-oracle-session-image]: https://badgen.net/github/stars/slumber86/express-oracle-session?label=%E2%98%85
+
+[![★][express-session-cache-manager-image] express-session-cache-manager][express-session-cache-manager-url]
+A store that implements [cache-manager](https://www.npmjs.com/package/cache-manager), which supports
+a [variety of storage types](https://www.npmjs.com/package/cache-manager#store-engines).
+
+[express-session-cache-manager-url]: https://www.npmjs.com/package/express-session-cache-manager
+[express-session-cache-manager-image]: https://badgen.net/github/stars/theogravity/express-session-cache-manager?label=%E2%98%85
+
+[![★][express-session-etcd3-image] express-session-etcd3][express-session-etcd3-url] An [etcd3](https://github.com/mixer/etcd3) based session store.
+
+[express-session-etcd3-url]: https://www.npmjs.com/package/express-session-etcd3
+[express-session-etcd3-image]: https://badgen.net/github/stars/willgm/express-session-etcd3?label=%E2%98%85
+
+[![★][express-session-level-image] express-session-level][express-session-level-url] A [LevelDB](https://github.com/Level/levelup) based session store.
+
+[express-session-level-url]: https://www.npmjs.com/package/express-session-level
+[express-session-level-image]: https://badgen.net/github/stars/tgohn/express-session-level?label=%E2%98%85
+
+[![★][express-session-rsdb-image] express-session-rsdb][express-session-rsdb-url] Session store based on Rocket-Store: A very simple, super fast and yet powerfull, flat file database.
+
+[express-session-rsdb-url]: https://www.npmjs.com/package/express-session-rsdb
+[express-session-rsdb-image]: https://badgen.net/github/stars/paragi/express-session-rsdb?label=%E2%98%85
+
+[![★][express-sessions-image] express-sessions][express-sessions-url] A session store supporting both MongoDB and Redis.
+
+[express-sessions-url]: https://www.npmjs.com/package/express-sessions
+[express-sessions-image]: https://badgen.net/github/stars/konteck/express-sessions?label=%E2%98%85
+
+[![★][firestore-store-image] firestore-store][firestore-store-url] A [Firestore](https://github.com/hendrysadrak/firestore-store)-based session store.
+
+[firestore-store-url]: https://www.npmjs.com/package/firestore-store
+[firestore-store-image]: https://badgen.net/github/stars/hendrysadrak/firestore-store?label=%E2%98%85
+
+[![★][fortune-session-image] fortune-session][fortune-session-url] A [Fortune.js](https://github.com/fortunejs/fortune)
+based session store. Supports all backends supported by Fortune (MongoDB, Redis, Postgres, NeDB).
+
+[fortune-session-url]: https://www.npmjs.com/package/fortune-session
+[fortune-session-image]: https://badgen.net/github/stars/aliceklipper/fortune-session?label=%E2%98%85
+
+[![★][hazelcast-store-image] hazelcast-store][hazelcast-store-url] A Hazelcast-based session store built on the [Hazelcast Node Client](https://www.npmjs.com/package/hazelcast-client).
+
+[hazelcast-store-url]: https://www.npmjs.com/package/hazelcast-store
+[hazelcast-store-image]: https://badgen.net/github/stars/jackspaniel/hazelcast-store?label=%E2%98%85
+
+[![★][level-session-store-image] level-session-store][level-session-store-url] A LevelDB-based session store.
+
+[level-session-store-url]: https://www.npmjs.com/package/level-session-store
+[level-session-store-image]: https://badgen.net/github/stars/toddself/level-session-store?label=%E2%98%85
+
+[![★][lowdb-session-store-image] lowdb-session-store][lowdb-session-store-url] A [lowdb](https://www.npmjs.com/package/lowdb)-based session store.
+
+[lowdb-session-store-url]: https://www.npmjs.com/package/lowdb-session-store
+[lowdb-session-store-image]: https://badgen.net/github/stars/fhellwig/lowdb-session-store?label=%E2%98%85
+
+[![★][medea-session-store-image] medea-session-store][medea-session-store-url] A Medea-based session store.
+
+[medea-session-store-url]: https://www.npmjs.com/package/medea-session-store
+[medea-session-store-image]: https://badgen.net/github/stars/BenjaminVadant/medea-session-store?label=%E2%98%85
+
+[![★][memorystore-image] memorystore][memorystore-url] A memory session store made for production.
+
+[memorystore-url]: https://www.npmjs.com/package/memorystore
+[memorystore-image]: https://badgen.net/github/stars/roccomuso/memorystore?label=%E2%98%85
+
+[![★][mssql-session-store-image] mssql-session-store][mssql-session-store-url] A SQL Server-based session store.
+
+[mssql-session-store-url]: https://www.npmjs.com/package/mssql-session-store
+[mssql-session-store-image]: https://badgen.net/github/stars/jwathen/mssql-session-store?label=%E2%98%85
+
+[![★][nedb-session-store-image] nedb-session-store][nedb-session-store-url] An alternate NeDB-based (either in-memory or file-persisted) session store.
+
+[nedb-session-store-url]: https://www.npmjs.com/package/nedb-session-store
+[nedb-session-store-image]: https://badgen.net/github/stars/JamesMGreene/nedb-session-store?label=%E2%98%85
+
+[![★][restsession-image] restsession][restsession-url] Store sessions utilizing a RESTful API
+
+[restsession-url]: https://www.npmjs.com/package/restsession
+[restsession-image]: https://badgen.net/github/stars/jankal/restsession?label=%E2%98%85
+
+[![★][sequelstore-connect-image] sequelstore-connect][sequelstore-connect-url] A session store using [Sequelize.js](http://sequelizejs.com/).
+
+[sequelstore-connect-url]: https://www.npmjs.com/package/sequelstore-connect
+[sequelstore-connect-image]: https://badgen.net/github/stars/MattMcFarland/sequelstore-connect?label=%E2%98%85
+
+[![★][session-file-store-image] session-file-store][session-file-store-url] A file system-based session store.
+
+[session-file-store-url]: https://www.npmjs.com/package/session-file-store
+[session-file-store-image]: https://badgen.net/github/stars/valery-barysok/session-file-store?label=%E2%98%85
+
+[![★][session-pouchdb-store-image] session-pouchdb-store][session-pouchdb-store-url] Session store for PouchDB / CouchDB. Accepts embedded, custom, or remote PouchDB instance and realtime synchronization.
+
+[session-pouchdb-store-url]: https://www.npmjs.com/package/session-pouchdb-store
+[session-pouchdb-store-image]: https://badgen.net/github/stars/solzimer/session-pouchdb-store?label=%E2%98%85
+
+[![★][session-rethinkdb-image] session-rethinkdb][session-rethinkdb-url] A [RethinkDB](http://rethinkdb.com/)-based session store.
+
+[session-rethinkdb-url]: https://www.npmjs.com/package/session-rethinkdb
+[session-rethinkdb-image]: https://badgen.net/github/stars/llambda/session-rethinkdb?label=%E2%98%85
+
+[![★][sessionstore-image] sessionstore][sessionstore-url] A session store that works with various databases.
+
+[sessionstore-url]: https://www.npmjs.com/package/sessionstore
+[sessionstore-image]: https://badgen.net/github/stars/adrai/sessionstore?label=%E2%98%85
+
+[![★][tch-nedb-session-image] tch-nedb-session][tch-nedb-session-url] A file system session store based on NeDB.
+
+[tch-nedb-session-url]: https://www.npmjs.com/package/tch-nedb-session
+[tch-nedb-session-image]: https://badgen.net/github/stars/tomaschyly/NeDBSession?label=%E2%98%85
+
+## Example
+
+A simple example using `express-session` to store page views for a user.
+
+```js
+var express = require('express')
+var parseurl = require('parseurl')
+var session = require('express-session')
+
+var app = express()
+
+app.use(session({
+  secret: 'keyboard cat',
+  resave: false,
+  saveUninitialized: true
+}))
+
+app.use(function (req, res, next) {
+  if (!req.session.views) {
+    req.session.views = {}
+  }
+
+  // get the url pathname
+  var pathname = parseurl(req).pathname
+
+  // count the views
+  req.session.views[pathname] = (req.session.views[pathname] || 0) + 1
+
+  next()
+})
+
+app.get('/foo', function (req, res, next) {
+  res.send('you viewed this page ' + req.session.views['/foo'] + ' times')
+})
+
+app.get('/bar', function (req, res, next) {
+  res.send('you viewed this page ' + req.session.views['/bar'] + ' times')
+})
+```
+
+## Debugging
+
+This module uses the [debug](https://www.npmjs.com/package/debug) module
+internally to log information about session operations.
+
+To see all the internal logs, set the `DEBUG` environment variable to
+`express-session` when launching your app (`npm start`, in this example):
+
+```sh
+$ DEBUG=express-session npm start
+```
+
+On Windows, use the corresponding command;
+
+```sh
+> set DEBUG=express-session & npm start
+```
+
+## License
+
+[MIT](LICENSE)
+
+[rfc-6265bis-03-4.1.2.7]: https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7
+[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/session/master
+[coveralls-url]: https://coveralls.io/r/expressjs/session?branch=master
+[node-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/express-session
+[npm-url]: https://npmjs.org/package/express-session
+[npm-version-image]: https://badgen.net/npm/v/express-session
+[travis-image]: https://badgen.net/travis/expressjs/session/master
+[travis-url]: https://travis-ci.org/expressjs/session
diff --git a/d2d_app/node_modules/express-session/index.js b/d2d_app/node_modules/express-session/index.js
new file mode 100644 (file)
index 0000000..9615346
--- /dev/null
@@ -0,0 +1,681 @@
+/*!
+ * express-session
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * Copyright(c) 2014-2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var Buffer = require('safe-buffer').Buffer
+var cookie = require('cookie');
+var crypto = require('crypto')
+var debug = require('debug')('express-session');
+var deprecate = require('depd')('express-session');
+var onHeaders = require('on-headers')
+var parseUrl = require('parseurl');
+var signature = require('cookie-signature')
+var uid = require('uid-safe').sync
+
+var Cookie = require('./session/cookie')
+var MemoryStore = require('./session/memory')
+var Session = require('./session/session')
+var Store = require('./session/store')
+
+// environment
+
+var env = process.env.NODE_ENV;
+
+/**
+ * Expose the middleware.
+ */
+
+exports = module.exports = session;
+
+/**
+ * Expose constructors.
+ */
+
+exports.Store = Store;
+exports.Cookie = Cookie;
+exports.Session = Session;
+exports.MemoryStore = MemoryStore;
+
+/**
+ * Warning message for `MemoryStore` usage in production.
+ * @private
+ */
+
+var warning = 'Warning: connect.session() MemoryStore is not\n'
+  + 'designed for a production environment, as it will leak\n'
+  + 'memory, and will not scale past a single process.';
+
+/**
+ * Node.js 0.8+ async implementation.
+ * @private
+ */
+
+/* istanbul ignore next */
+var defer = typeof setImmediate === 'function'
+  ? setImmediate
+  : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
+
+/**
+ * Setup session store with the given `options`.
+ *
+ * @param {Object} [options]
+ * @param {Object} [options.cookie] Options for cookie
+ * @param {Function} [options.genid]
+ * @param {String} [options.name=connect.sid] Session ID cookie name
+ * @param {Boolean} [options.proxy]
+ * @param {Boolean} [options.resave] Resave unmodified sessions back to the store
+ * @param {Boolean} [options.rolling] Enable/disable rolling session expiration
+ * @param {Boolean} [options.saveUninitialized] Save uninitialized sessions to the store
+ * @param {String|Array} [options.secret] Secret for signing session ID
+ * @param {Object} [options.store=MemoryStore] Session store
+ * @param {String} [options.unset]
+ * @return {Function} middleware
+ * @public
+ */
+
+function session(options) {
+  var opts = options || {}
+
+  // get the cookie options
+  var cookieOptions = opts.cookie || {}
+
+  // get the session id generate function
+  var generateId = opts.genid || generateSessionId
+
+  // get the session cookie name
+  var name = opts.name || opts.key || 'connect.sid'
+
+  // get the session store
+  var store = opts.store || new MemoryStore()
+
+  // get the trust proxy setting
+  var trustProxy = opts.proxy
+
+  // get the resave session option
+  var resaveSession = opts.resave;
+
+  // get the rolling session option
+  var rollingSessions = Boolean(opts.rolling)
+
+  // get the save uninitialized session option
+  var saveUninitializedSession = opts.saveUninitialized
+
+  // get the cookie signing secret
+  var secret = opts.secret
+
+  if (typeof generateId !== 'function') {
+    throw new TypeError('genid option must be a function');
+  }
+
+  if (resaveSession === undefined) {
+    deprecate('undefined resave option; provide resave option');
+    resaveSession = true;
+  }
+
+  if (saveUninitializedSession === undefined) {
+    deprecate('undefined saveUninitialized option; provide saveUninitialized option');
+    saveUninitializedSession = true;
+  }
+
+  if (opts.unset && opts.unset !== 'destroy' && opts.unset !== 'keep') {
+    throw new TypeError('unset option must be "destroy" or "keep"');
+  }
+
+  // TODO: switch to "destroy" on next major
+  var unsetDestroy = opts.unset === 'destroy'
+
+  if (Array.isArray(secret) && secret.length === 0) {
+    throw new TypeError('secret option array must contain one or more strings');
+  }
+
+  if (secret && !Array.isArray(secret)) {
+    secret = [secret];
+  }
+
+  if (!secret) {
+    deprecate('req.secret; provide secret option');
+  }
+
+  // notify user that this store is not
+  // meant for a production environment
+  /* istanbul ignore next: not tested */
+  if (env === 'production' && store instanceof MemoryStore) {
+    console.warn(warning);
+  }
+
+  // generates the new session
+  store.generate = function(req){
+    req.sessionID = generateId(req);
+    req.session = new Session(req);
+    req.session.cookie = new Cookie(cookieOptions);
+
+    if (cookieOptions.secure === 'auto') {
+      req.session.cookie.secure = issecure(req, trustProxy);
+    }
+  };
+
+  var storeImplementsTouch = typeof store.touch === 'function';
+
+  // register event listeners for the store to track readiness
+  var storeReady = true
+  store.on('disconnect', function ondisconnect() {
+    storeReady = false
+  })
+  store.on('connect', function onconnect() {
+    storeReady = true
+  })
+
+  return function session(req, res, next) {
+    // self-awareness
+    if (req.session) {
+      next()
+      return
+    }
+
+    // Handle connection as if there is no session if
+    // the store has temporarily disconnected etc
+    if (!storeReady) {
+      debug('store is disconnected')
+      next()
+      return
+    }
+
+    // pathname mismatch
+    var originalPath = parseUrl.original(req).pathname || '/'
+    if (originalPath.indexOf(cookieOptions.path || '/') !== 0) return next();
+
+    // ensure a secret is available or bail
+    if (!secret && !req.secret) {
+      next(new Error('secret option required for sessions'));
+      return;
+    }
+
+    // backwards compatibility for signed cookies
+    // req.secret is passed from the cookie parser middleware
+    var secrets = secret || [req.secret];
+
+    var originalHash;
+    var originalId;
+    var savedHash;
+    var touched = false
+
+    // expose store
+    req.sessionStore = store;
+
+    // get the session ID from the cookie
+    var cookieId = req.sessionID = getcookie(req, name, secrets);
+
+    // set-cookie
+    onHeaders(res, function(){
+      if (!req.session) {
+        debug('no session');
+        return;
+      }
+
+      if (!shouldSetCookie(req)) {
+        return;
+      }
+
+      // only send secure cookies via https
+      if (req.session.cookie.secure && !issecure(req, trustProxy)) {
+        debug('not secured');
+        return;
+      }
+
+      if (!touched) {
+        // touch session
+        req.session.touch()
+        touched = true
+      }
+
+      // set cookie
+      setcookie(res, name, req.sessionID, secrets[0], req.session.cookie.data);
+    });
+
+    // proxy end() to commit the session
+    var _end = res.end;
+    var _write = res.write;
+    var ended = false;
+    res.end = function end(chunk, encoding) {
+      if (ended) {
+        return false;
+      }
+
+      ended = true;
+
+      var ret;
+      var sync = true;
+
+      function writeend() {
+        if (sync) {
+          ret = _end.call(res, chunk, encoding);
+          sync = false;
+          return;
+        }
+
+        _end.call(res);
+      }
+
+      function writetop() {
+        if (!sync) {
+          return ret;
+        }
+
+        if (chunk == null) {
+          ret = true;
+          return ret;
+        }
+
+        var contentLength = Number(res.getHeader('Content-Length'));
+
+        if (!isNaN(contentLength) && contentLength > 0) {
+          // measure chunk
+          chunk = !Buffer.isBuffer(chunk)
+            ? Buffer.from(chunk, encoding)
+            : chunk;
+          encoding = undefined;
+
+          if (chunk.length !== 0) {
+            debug('split response');
+            ret = _write.call(res, chunk.slice(0, chunk.length - 1));
+            chunk = chunk.slice(chunk.length - 1, chunk.length);
+            return ret;
+          }
+        }
+
+        ret = _write.call(res, chunk, encoding);
+        sync = false;
+
+        return ret;
+      }
+
+      if (shouldDestroy(req)) {
+        // destroy session
+        debug('destroying');
+        store.destroy(req.sessionID, function ondestroy(err) {
+          if (err) {
+            defer(next, err);
+          }
+
+          debug('destroyed');
+          writeend();
+        });
+
+        return writetop();
+      }
+
+      // no session to save
+      if (!req.session) {
+        debug('no session');
+        return _end.call(res, chunk, encoding);
+      }
+
+      if (!touched) {
+        // touch session
+        req.session.touch()
+        touched = true
+      }
+
+      if (shouldSave(req)) {
+        req.session.save(function onsave(err) {
+          if (err) {
+            defer(next, err);
+          }
+
+          writeend();
+        });
+
+        return writetop();
+      } else if (storeImplementsTouch && shouldTouch(req)) {
+        // store implements touch method
+        debug('touching');
+        store.touch(req.sessionID, req.session, function ontouch(err) {
+          if (err) {
+            defer(next, err);
+          }
+
+          debug('touched');
+          writeend();
+        });
+
+        return writetop();
+      }
+
+      return _end.call(res, chunk, encoding);
+    };
+
+    // generate the session
+    function generate() {
+      store.generate(req);
+      originalId = req.sessionID;
+      originalHash = hash(req.session);
+      wrapmethods(req.session);
+    }
+
+    // inflate the session
+    function inflate (req, sess) {
+      store.createSession(req, sess)
+      originalId = req.sessionID
+      originalHash = hash(sess)
+
+      if (!resaveSession) {
+        savedHash = originalHash
+      }
+
+      wrapmethods(req.session)
+    }
+
+    function rewrapmethods (sess, callback) {
+      return function () {
+        if (req.session !== sess) {
+          wrapmethods(req.session)
+        }
+
+        callback.apply(this, arguments)
+      }
+    }
+
+    // wrap session methods
+    function wrapmethods(sess) {
+      var _reload = sess.reload
+      var _save = sess.save;
+
+      function reload(callback) {
+        debug('reloading %s', this.id)
+        _reload.call(this, rewrapmethods(this, callback))
+      }
+
+      function save() {
+        debug('saving %s', this.id);
+        savedHash = hash(this);
+        _save.apply(this, arguments);
+      }
+
+      Object.defineProperty(sess, 'reload', {
+        configurable: true,
+        enumerable: false,
+        value: reload,
+        writable: true
+      })
+
+      Object.defineProperty(sess, 'save', {
+        configurable: true,
+        enumerable: false,
+        value: save,
+        writable: true
+      });
+    }
+
+    // check if session has been modified
+    function isModified(sess) {
+      return originalId !== sess.id || originalHash !== hash(sess);
+    }
+
+    // check if session has been saved
+    function isSaved(sess) {
+      return originalId === sess.id && savedHash === hash(sess);
+    }
+
+    // determine if session should be destroyed
+    function shouldDestroy(req) {
+      return req.sessionID && unsetDestroy && req.session == null;
+    }
+
+    // determine if session should be saved to store
+    function shouldSave(req) {
+      // cannot set cookie without a session ID
+      if (typeof req.sessionID !== 'string') {
+        debug('session ignored because of bogus req.sessionID %o', req.sessionID);
+        return false;
+      }
+
+      return !saveUninitializedSession && cookieId !== req.sessionID
+        ? isModified(req.session)
+        : !isSaved(req.session)
+    }
+
+    // determine if session should be touched
+    function shouldTouch(req) {
+      // cannot set cookie without a session ID
+      if (typeof req.sessionID !== 'string') {
+        debug('session ignored because of bogus req.sessionID %o', req.sessionID);
+        return false;
+      }
+
+      return cookieId === req.sessionID && !shouldSave(req);
+    }
+
+    // determine if cookie should be set on response
+    function shouldSetCookie(req) {
+      // cannot set cookie without a session ID
+      if (typeof req.sessionID !== 'string') {
+        return false;
+      }
+
+      return cookieId !== req.sessionID
+        ? saveUninitializedSession || isModified(req.session)
+        : rollingSessions || req.session.cookie.expires != null && isModified(req.session);
+    }
+
+    // generate a session if the browser doesn't send a sessionID
+    if (!req.sessionID) {
+      debug('no SID sent, generating session');
+      generate();
+      next();
+      return;
+    }
+
+    // generate the session object
+    debug('fetching %s', req.sessionID);
+    store.get(req.sessionID, function(err, sess){
+      // error handling
+      if (err && err.code !== 'ENOENT') {
+        debug('error %j', err);
+        next(err)
+        return
+      }
+
+      try {
+        if (err || !sess) {
+          debug('no session found')
+          generate()
+        } else {
+          debug('session found')
+          inflate(req, sess)
+        }
+      } catch (e) {
+        next(e)
+        return
+      }
+
+      next()
+    });
+  };
+};
+
+/**
+ * Generate a session ID for a new session.
+ *
+ * @return {String}
+ * @private
+ */
+
+function generateSessionId(sess) {
+  return uid(24);
+}
+
+/**
+ * Get the session ID cookie from request.
+ *
+ * @return {string}
+ * @private
+ */
+
+function getcookie(req, name, secrets) {
+  var header = req.headers.cookie;
+  var raw;
+  var val;
+
+  // read from cookie header
+  if (header) {
+    var cookies = cookie.parse(header);
+
+    raw = cookies[name];
+
+    if (raw) {
+      if (raw.substr(0, 2) === 's:') {
+        val = unsigncookie(raw.slice(2), secrets);
+
+        if (val === false) {
+          debug('cookie signature invalid');
+          val = undefined;
+        }
+      } else {
+        debug('cookie unsigned')
+      }
+    }
+  }
+
+  // back-compat read from cookieParser() signedCookies data
+  if (!val && req.signedCookies) {
+    val = req.signedCookies[name];
+
+    if (val) {
+      deprecate('cookie should be available in req.headers.cookie');
+    }
+  }
+
+  // back-compat read from cookieParser() cookies data
+  if (!val && req.cookies) {
+    raw = req.cookies[name];
+
+    if (raw) {
+      if (raw.substr(0, 2) === 's:') {
+        val = unsigncookie(raw.slice(2), secrets);
+
+        if (val) {
+          deprecate('cookie should be available in req.headers.cookie');
+        }
+
+        if (val === false) {
+          debug('cookie signature invalid');
+          val = undefined;
+        }
+      } else {
+        debug('cookie unsigned')
+      }
+    }
+  }
+
+  return val;
+}
+
+/**
+ * Hash the given `sess` object omitting changes to `.cookie`.
+ *
+ * @param {Object} sess
+ * @return {String}
+ * @private
+ */
+
+function hash(sess) {
+  // serialize
+  var str = JSON.stringify(sess, function (key, val) {
+    // ignore sess.cookie property
+    if (this === sess && key === 'cookie') {
+      return
+    }
+
+    return val
+  })
+
+  // hash
+  return crypto
+    .createHash('sha1')
+    .update(str, 'utf8')
+    .digest('hex')
+}
+
+/**
+ * Determine if request is secure.
+ *
+ * @param {Object} req
+ * @param {Boolean} [trustProxy]
+ * @return {Boolean}
+ * @private
+ */
+
+function issecure(req, trustProxy) {
+  // socket is https server
+  if (req.connection && req.connection.encrypted) {
+    return true;
+  }
+
+  // do not trust proxy
+  if (trustProxy === false) {
+    return false;
+  }
+
+  // no explicit trust; try req.secure from express
+  if (trustProxy !== true) {
+    return req.secure === true
+  }
+
+  // read the proto from x-forwarded-proto header
+  var header = req.headers['x-forwarded-proto'] || '';
+  var index = header.indexOf(',');
+  var proto = index !== -1
+    ? header.substr(0, index).toLowerCase().trim()
+    : header.toLowerCase().trim()
+
+  return proto === 'https';
+}
+
+/**
+ * Set cookie on response.
+ *
+ * @private
+ */
+
+function setcookie(res, name, val, secret, options) {
+  var signed = 's:' + signature.sign(val, secret);
+  var data = cookie.serialize(name, signed, options);
+
+  debug('set-cookie %s', data);
+
+  var prev = res.getHeader('Set-Cookie') || []
+  var header = Array.isArray(prev) ? prev.concat(data) : [prev, data];
+
+  res.setHeader('Set-Cookie', header)
+}
+
+/**
+ * Verify and decode the given `val` with `secrets`.
+ *
+ * @param {String} val
+ * @param {Array} secrets
+ * @returns {String|Boolean}
+ * @private
+ */
+function unsigncookie(val, secrets) {
+  for (var i = 0; i < secrets.length; i++) {
+    var result = signature.unsign(val, secrets[i]);
+
+    if (result !== false) {
+      return result;
+    }
+  }
+
+  return false;
+}
diff --git a/d2d_app/node_modules/express-session/package.json b/d2d_app/node_modules/express-session/package.json
new file mode 100644 (file)
index 0000000..5301978
--- /dev/null
@@ -0,0 +1,91 @@
+{
+  "_from": "express-session",
+  "_id": "express-session@1.17.1",
+  "_inBundle": false,
+  "_integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==",
+  "_location": "/express-session",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "express-session",
+    "name": "express-session",
+    "escapedName": "express-session",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",
+  "_shasum": "36ecbc7034566d38c8509885c044d461c11bf357",
+  "_spec": "express-session",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen",
+  "author": {
+    "name": "TJ Holowaychuk",
+    "email": "tj@vision-media.ca",
+    "url": "http://tjholowaychuk.com"
+  },
+  "bugs": {
+    "url": "https://github.com/expressjs/session/issues"
+  },
+  "bundleDependencies": false,
+  "contributors": [
+    {
+      "name": "Douglas Christopher Wilson",
+      "email": "doug@somethingdoug.com"
+    },
+    {
+      "name": "Joe Wagner",
+      "email": "njwjs722@gmail.com"
+    }
+  ],
+  "dependencies": {
+    "cookie": "0.4.0",
+    "cookie-signature": "1.0.6",
+    "debug": "2.6.9",
+    "depd": "~2.0.0",
+    "on-headers": "~1.0.2",
+    "parseurl": "~1.3.3",
+    "safe-buffer": "5.2.0",
+    "uid-safe": "~2.1.5"
+  },
+  "deprecated": false,
+  "description": "Simple session middleware for Express",
+  "devDependencies": {
+    "after": "0.8.2",
+    "cookie-parser": "1.4.5",
+    "eslint": "3.19.0",
+    "eslint-plugin-markdown": "1.0.2",
+    "express": "4.17.1",
+    "mocha": "7.1.1",
+    "nyc": "15.0.1",
+    "supertest": "4.0.2"
+  },
+  "engines": {
+    "node": ">= 0.8.0"
+  },
+  "files": [
+    "session/",
+    "HISTORY.md",
+    "LICENSE",
+    "index.js"
+  ],
+  "homepage": "https://github.com/expressjs/session#readme",
+  "license": "MIT",
+  "name": "express-session",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/expressjs/session.git"
+  },
+  "scripts": {
+    "lint": "eslint --plugin markdown --ext js,md . && node ./scripts/lint-readme.js",
+    "test": "mocha --require test/support/env --check-leaks --bail --no-exit --reporter spec test/",
+    "test-cov": "nyc npm test",
+    "test-travis": "nyc npm test -- --no-exit",
+    "version": "node scripts/version-history.js && git add HISTORY.md"
+  },
+  "version": "1.17.1"
+}
diff --git a/d2d_app/node_modules/express-session/session/cookie.js b/d2d_app/node_modules/express-session/session/cookie.js
new file mode 100644 (file)
index 0000000..a8b4e57
--- /dev/null
@@ -0,0 +1,150 @@
+/*!
+ * Connect - session - Cookie
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+
+var cookie = require('cookie')
+var deprecate = require('depd')('express-session')
+
+/**
+ * Initialize a new `Cookie` with the given `options`.
+ *
+ * @param {IncomingMessage} req
+ * @param {Object} options
+ * @api private
+ */
+
+var Cookie = module.exports = function Cookie(options) {
+  this.path = '/';
+  this.maxAge = null;
+  this.httpOnly = true;
+
+  if (options) {
+    if (typeof options !== 'object') {
+      throw new TypeError('argument options must be a object')
+    }
+
+    for (var key in options) {
+      if (key !== 'data') {
+        this[key] = options[key]
+      }
+    }
+  }
+
+  if (this.originalMaxAge === undefined || this.originalMaxAge === null) {
+    this.originalMaxAge = this.maxAge
+  }
+};
+
+/*!
+ * Prototype.
+ */
+
+Cookie.prototype = {
+
+  /**
+   * Set expires `date`.
+   *
+   * @param {Date} date
+   * @api public
+   */
+
+  set expires(date) {
+    this._expires = date;
+    this.originalMaxAge = this.maxAge;
+  },
+
+  /**
+   * Get expires `date`.
+   *
+   * @return {Date}
+   * @api public
+   */
+
+  get expires() {
+    return this._expires;
+  },
+
+  /**
+   * Set expires via max-age in `ms`.
+   *
+   * @param {Number} ms
+   * @api public
+   */
+
+  set maxAge(ms) {
+    if (ms && typeof ms !== 'number' && !(ms instanceof Date)) {
+      throw new TypeError('maxAge must be a number or Date')
+    }
+
+    if (ms instanceof Date) {
+      deprecate('maxAge as Date; pass number of milliseconds instead')
+    }
+
+    this.expires = typeof ms === 'number'
+      ? new Date(Date.now() + ms)
+      : ms;
+  },
+
+  /**
+   * Get expires max-age in `ms`.
+   *
+   * @return {Number}
+   * @api public
+   */
+
+  get maxAge() {
+    return this.expires instanceof Date
+      ? this.expires.valueOf() - Date.now()
+      : this.expires;
+  },
+
+  /**
+   * Return cookie data object.
+   *
+   * @return {Object}
+   * @api private
+   */
+
+  get data() {
+    return {
+      originalMaxAge: this.originalMaxAge
+      , expires: this._expires
+      , secure: this.secure
+      , httpOnly: this.httpOnly
+      , domain: this.domain
+      , path: this.path
+      , sameSite: this.sameSite
+    }
+  },
+
+  /**
+   * Return a serialized cookie string.
+   *
+   * @return {String}
+   * @api public
+   */
+
+  serialize: function(name, val){
+    return cookie.serialize(name, val, this.data);
+  },
+
+  /**
+   * Return JSON representation of this cookie.
+   *
+   * @return {Object}
+   * @api private
+   */
+
+  toJSON: function(){
+    return this.data;
+  }
+};
diff --git a/d2d_app/node_modules/express-session/session/memory.js b/d2d_app/node_modules/express-session/session/memory.js
new file mode 100644 (file)
index 0000000..11ed686
--- /dev/null
@@ -0,0 +1,187 @@
+/*!
+ * express-session
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * Copyright(c) 2015 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var Store = require('./store')
+var util = require('util')
+
+/**
+ * Shim setImmediate for node.js < 0.10
+ * @private
+ */
+
+/* istanbul ignore next */
+var defer = typeof setImmediate === 'function'
+  ? setImmediate
+  : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) }
+
+/**
+ * Module exports.
+ */
+
+module.exports = MemoryStore
+
+/**
+ * A session store in memory.
+ * @public
+ */
+
+function MemoryStore() {
+  Store.call(this)
+  this.sessions = Object.create(null)
+}
+
+/**
+ * Inherit from Store.
+ */
+
+util.inherits(MemoryStore, Store)
+
+/**
+ * Get all active sessions.
+ *
+ * @param {function} callback
+ * @public
+ */
+
+MemoryStore.prototype.all = function all(callback) {
+  var sessionIds = Object.keys(this.sessions)
+  var sessions = Object.create(null)
+
+  for (var i = 0; i < sessionIds.length; i++) {
+    var sessionId = sessionIds[i]
+    var session = getSession.call(this, sessionId)
+
+    if (session) {
+      sessions[sessionId] = session;
+    }
+  }
+
+  callback && defer(callback, null, sessions)
+}
+
+/**
+ * Clear all sessions.
+ *
+ * @param {function} callback
+ * @public
+ */
+
+MemoryStore.prototype.clear = function clear(callback) {
+  this.sessions = Object.create(null)
+  callback && defer(callback)
+}
+
+/**
+ * Destroy the session associated with the given session ID.
+ *
+ * @param {string} sessionId
+ * @public
+ */
+
+MemoryStore.prototype.destroy = function destroy(sessionId, callback) {
+  delete this.sessions[sessionId]
+  callback && defer(callback)
+}
+
+/**
+ * Fetch session by the given session ID.
+ *
+ * @param {string} sessionId
+ * @param {function} callback
+ * @public
+ */
+
+MemoryStore.prototype.get = function get(sessionId, callback) {
+  defer(callback, null, getSession.call(this, sessionId))
+}
+
+/**
+ * Commit the given session associated with the given sessionId to the store.
+ *
+ * @param {string} sessionId
+ * @param {object} session
+ * @param {function} callback
+ * @public
+ */
+
+MemoryStore.prototype.set = function set(sessionId, session, callback) {
+  this.sessions[sessionId] = JSON.stringify(session)
+  callback && defer(callback)
+}
+
+/**
+ * Get number of active sessions.
+ *
+ * @param {function} callback
+ * @public
+ */
+
+MemoryStore.prototype.length = function length(callback) {
+  this.all(function (err, sessions) {
+    if (err) return callback(err)
+    callback(null, Object.keys(sessions).length)
+  })
+}
+
+/**
+ * Touch the given session object associated with the given session ID.
+ *
+ * @param {string} sessionId
+ * @param {object} session
+ * @param {function} callback
+ * @public
+ */
+
+MemoryStore.prototype.touch = function touch(sessionId, session, callback) {
+  var currentSession = getSession.call(this, sessionId)
+
+  if (currentSession) {
+    // update expiration
+    currentSession.cookie = session.cookie
+    this.sessions[sessionId] = JSON.stringify(currentSession)
+  }
+
+  callback && defer(callback)
+}
+
+/**
+ * Get session from the store.
+ * @private
+ */
+
+function getSession(sessionId) {
+  var sess = this.sessions[sessionId]
+
+  if (!sess) {
+    return
+  }
+
+  // parse
+  sess = JSON.parse(sess)
+
+  if (sess.cookie) {
+    var expires = typeof sess.cookie.expires === 'string'
+      ? new Date(sess.cookie.expires)
+      : sess.cookie.expires
+
+    // destroy expired session
+    if (expires && expires <= Date.now()) {
+      delete this.sessions[sessionId]
+      return
+    }
+  }
+
+  return sess
+}
diff --git a/d2d_app/node_modules/express-session/session/session.js b/d2d_app/node_modules/express-session/session/session.js
new file mode 100644 (file)
index 0000000..fee7608
--- /dev/null
@@ -0,0 +1,143 @@
+/*!
+ * Connect - session - Session
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Expose Session.
+ */
+
+module.exports = Session;
+
+/**
+ * Create a new `Session` with the given request and `data`.
+ *
+ * @param {IncomingRequest} req
+ * @param {Object} data
+ * @api private
+ */
+
+function Session(req, data) {
+  Object.defineProperty(this, 'req', { value: req });
+  Object.defineProperty(this, 'id', { value: req.sessionID });
+
+  if (typeof data === 'object' && data !== null) {
+    // merge data into this, ignoring prototype properties
+    for (var prop in data) {
+      if (!(prop in this)) {
+        this[prop] = data[prop]
+      }
+    }
+  }
+}
+
+/**
+ * Update reset `.cookie.maxAge` to prevent
+ * the cookie from expiring when the
+ * session is still active.
+ *
+ * @return {Session} for chaining
+ * @api public
+ */
+
+defineMethod(Session.prototype, 'touch', function touch() {
+  return this.resetMaxAge();
+});
+
+/**
+ * Reset `.maxAge` to `.originalMaxAge`.
+ *
+ * @return {Session} for chaining
+ * @api public
+ */
+
+defineMethod(Session.prototype, 'resetMaxAge', function resetMaxAge() {
+  this.cookie.maxAge = this.cookie.originalMaxAge;
+  return this;
+});
+
+/**
+ * Save the session data with optional callback `fn(err)`.
+ *
+ * @param {Function} fn
+ * @return {Session} for chaining
+ * @api public
+ */
+
+defineMethod(Session.prototype, 'save', function save(fn) {
+  this.req.sessionStore.set(this.id, this, fn || function(){});
+  return this;
+});
+
+/**
+ * Re-loads the session data _without_ altering
+ * the maxAge properties. Invokes the callback `fn(err)`,
+ * after which time if no exception has occurred the
+ * `req.session` property will be a new `Session` object,
+ * although representing the same session.
+ *
+ * @param {Function} fn
+ * @return {Session} for chaining
+ * @api public
+ */
+
+defineMethod(Session.prototype, 'reload', function reload(fn) {
+  var req = this.req
+  var store = this.req.sessionStore
+
+  store.get(this.id, function(err, sess){
+    if (err) return fn(err);
+    if (!sess) return fn(new Error('failed to load session'));
+    store.createSession(req, sess);
+    fn();
+  });
+  return this;
+});
+
+/**
+ * Destroy `this` session.
+ *
+ * @param {Function} fn
+ * @return {Session} for chaining
+ * @api public
+ */
+
+defineMethod(Session.prototype, 'destroy', function destroy(fn) {
+  delete this.req.session;
+  this.req.sessionStore.destroy(this.id, fn);
+  return this;
+});
+
+/**
+ * Regenerate this request's session.
+ *
+ * @param {Function} fn
+ * @return {Session} for chaining
+ * @api public
+ */
+
+defineMethod(Session.prototype, 'regenerate', function regenerate(fn) {
+  this.req.sessionStore.regenerate(this.req, fn);
+  return this;
+});
+
+/**
+ * Helper function for creating a method on a prototype.
+ *
+ * @param {Object} obj
+ * @param {String} name
+ * @param {Function} fn
+ * @private
+ */
+function defineMethod(obj, name, fn) {
+  Object.defineProperty(obj, name, {
+    configurable: true,
+    enumerable: false,
+    value: fn,
+    writable: true
+  });
+};
diff --git a/d2d_app/node_modules/express-session/session/store.js b/d2d_app/node_modules/express-session/session/store.js
new file mode 100644 (file)
index 0000000..3793877
--- /dev/null
@@ -0,0 +1,102 @@
+/*!
+ * Connect - session - Store
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * MIT Licensed
+ */
+
+'use strict';
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var Cookie = require('./cookie')
+var EventEmitter = require('events').EventEmitter
+var Session = require('./session')
+var util = require('util')
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = Store
+
+/**
+ * Abstract base class for session stores.
+ * @public
+ */
+
+function Store () {
+  EventEmitter.call(this)
+}
+
+/**
+ * Inherit from EventEmitter.
+ */
+
+util.inherits(Store, EventEmitter)
+
+/**
+ * Re-generate the given requests's session.
+ *
+ * @param {IncomingRequest} req
+ * @return {Function} fn
+ * @api public
+ */
+
+Store.prototype.regenerate = function(req, fn){
+  var self = this;
+  this.destroy(req.sessionID, function(err){
+    self.generate(req);
+    fn(err);
+  });
+};
+
+/**
+ * Load a `Session` instance via the given `sid`
+ * and invoke the callback `fn(err, sess)`.
+ *
+ * @param {String} sid
+ * @param {Function} fn
+ * @api public
+ */
+
+Store.prototype.load = function(sid, fn){
+  var self = this;
+  this.get(sid, function(err, sess){
+    if (err) return fn(err);
+    if (!sess) return fn();
+    var req = { sessionID: sid, sessionStore: self };
+    fn(null, self.createSession(req, sess))
+  });
+};
+
+/**
+ * Create session from JSON `sess` data.
+ *
+ * @param {IncomingRequest} req
+ * @param {Object} sess
+ * @return {Session}
+ * @api private
+ */
+
+Store.prototype.createSession = function(req, sess){
+  var expires = sess.cookie.expires
+  var originalMaxAge = sess.cookie.originalMaxAge
+
+  sess.cookie = new Cookie(sess.cookie);
+
+  if (typeof expires === 'string') {
+    // convert expires to a Date object
+    sess.cookie.expires = new Date(expires)
+  }
+
+  // keep originalMaxAge intact
+  sess.cookie.originalMaxAge = originalMaxAge
+
+  req.session = new Session(req, sess);
+  return req.session;
+};
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.coveralls.yml b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.coveralls.yml
deleted file mode 100644 (file)
index 20a7068..0000000
+++ /dev/null
@@ -1 +0,0 @@
-repo_token: SIAeZjKYlHK74rbcFvNHMUzjRiMpflxve
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.eslintrc b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.eslintrc
deleted file mode 100644 (file)
index 8a37ae2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "env": {
-    "browser": true,
-    "node": true
-  },
-  "rules": {
-    "no-console": 0,
-    "no-empty": [1, { "allowEmptyCatch": true }]
-  },
-  "extends": "eslint:recommended"
-}
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.npmignore b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.npmignore
deleted file mode 100644 (file)
index 5f60eec..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-support
-test
-examples
-example
-*.sock
-dist
-yarn.lock
-coverage
-bower.json
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.travis.yml b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/.travis.yml
deleted file mode 100644 (file)
index 6c6090c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-language: node_js
-node_js:
-  - "6"
-  - "5"
-  - "4"
-
-install:
-  - make node_modules
-
-script:
-  - make lint
-  - make test
-  - make coveralls
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/CHANGELOG.md b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/CHANGELOG.md
deleted file mode 100644 (file)
index 553da15..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-
-2.6.9 / 2017-09-22
-==================
-
-  * remove ReDoS regexp in %o formatter (#504)
-
-2.6.8 / 2017-05-18
-==================
-
-  * Fix: Check for undefined on browser globals (#462, @marbemac)
-
-2.6.7 / 2017-05-16
-==================
-
-  * Fix: Update ms to 2.0.0 to fix regular expression denial of service vulnerability (#458, @hubdotcom)
-  * Fix: Inline extend function in node implementation (#452, @dougwilson)
-  * Docs: Fix typo (#455, @msasad)
-
-2.6.5 / 2017-04-27
-==================
-
-  * Fix: null reference check on window.documentElement.style.WebkitAppearance (#447, @thebigredgeek)
-  * Misc: clean up browser reference checks (#447, @thebigredgeek)
-  * Misc: add npm-debug.log to .gitignore (@thebigredgeek)
-
-
-2.6.4 / 2017-04-20
-==================
-
-  * Fix: bug that would occure if process.env.DEBUG is a non-string value. (#444, @LucianBuzzo)
-  * Chore: ignore bower.json in npm installations. (#437, @joaovieira)
-  * Misc: update "ms" to v0.7.3 (@tootallnate)
-
-2.6.3 / 2017-03-13
-==================
-
-  * Fix: Electron reference to `process.env.DEBUG` (#431, @paulcbetts)
-  * Docs: Changelog fix (@thebigredgeek)
-
-2.6.2 / 2017-03-10
-==================
-
-  * Fix: DEBUG_MAX_ARRAY_LENGTH (#420, @slavaGanzin)
-  * Docs: Add backers and sponsors from Open Collective (#422, @piamancini)
-  * Docs: Add Slackin invite badge (@tootallnate)
-
-2.6.1 / 2017-02-10
-==================
-
-  * Fix: Module's `export default` syntax fix for IE8 `Expected identifier` error
-  * Fix: Whitelist DEBUG_FD for values 1 and 2 only (#415, @pi0)
-  * Fix: IE8 "Expected identifier" error (#414, @vgoma)
-  * Fix: Namespaces would not disable once enabled (#409, @musikov)
-
-2.6.0 / 2016-12-28
-==================
-
-  * Fix: added better null pointer checks for browser useColors (@thebigredgeek)
-  * Improvement: removed explicit `window.debug` export (#404, @tootallnate)
-  * Improvement: deprecated `DEBUG_FD` environment variable (#405, @tootallnate)
-
-2.5.2 / 2016-12-25
-==================
-
-  * Fix: reference error on window within webworkers (#393, @KlausTrainer)
-  * Docs: fixed README typo (#391, @lurch)
-  * Docs: added notice about v3 api discussion (@thebigredgeek)
-
-2.5.1 / 2016-12-20
-==================
-
-  * Fix: babel-core compatibility
-
-2.5.0 / 2016-12-20
-==================
-
-  * Fix: wrong reference in bower file (@thebigredgeek)
-  * Fix: webworker compatibility (@thebigredgeek)
-  * Fix: output formatting issue (#388, @kribblo)
-  * Fix: babel-loader compatibility (#383, @escwald)
-  * Misc: removed built asset from repo and publications (@thebigredgeek)
-  * Misc: moved source files to /src (#378, @yamikuronue)
-  * Test: added karma integration and replaced babel with browserify for browser tests (#378, @yamikuronue)
-  * Test: coveralls integration (#378, @yamikuronue)
-  * Docs: simplified language in the opening paragraph (#373, @yamikuronue)
-
-2.4.5 / 2016-12-17
-==================
-
-  * Fix: `navigator` undefined in Rhino (#376, @jochenberger)
-  * Fix: custom log function (#379, @hsiliev)
-  * Improvement: bit of cleanup + linting fixes (@thebigredgeek)
-  * Improvement: rm non-maintainted `dist/` dir (#375, @freewil)
-  * Docs: simplified language in the opening paragraph. (#373, @yamikuronue)
-
-2.4.4 / 2016-12-14
-==================
-
-  * Fix: work around debug being loaded in preload scripts for electron (#368, @paulcbetts)
-
-2.4.3 / 2016-12-14
-==================
-
-  * Fix: navigation.userAgent error for react native (#364, @escwald)
-
-2.4.2 / 2016-12-14
-==================
-
-  * Fix: browser colors (#367, @tootallnate)
-  * Misc: travis ci integration (@thebigredgeek)
-  * Misc: added linting and testing boilerplate with sanity check (@thebigredgeek)
-
-2.4.1 / 2016-12-13
-==================
-
-  * Fix: typo that broke the package (#356)
-
-2.4.0 / 2016-12-13
-==================
-
-  * Fix: bower.json references unbuilt src entry point (#342, @justmatt)
-  * Fix: revert "handle regex special characters" (@tootallnate)
-  * Feature: configurable util.inspect()`options for NodeJS (#327, @tootallnate)
-  * Feature: %O`(big O) pretty-prints objects (#322, @tootallnate)
-  * Improvement: allow colors in workers (#335, @botverse)
-  * Improvement: use same color for same namespace. (#338, @lchenay)
-
-2.3.3 / 2016-11-09
-==================
-
-  * Fix: Catch `JSON.stringify()` errors (#195, Jovan Alleyne)
-  * Fix: Returning `localStorage` saved values (#331, Levi Thomason)
-  * Improvement: Don't create an empty object when no `process` (Nathan Rajlich)
-
-2.3.2 / 2016-11-09
-==================
-
-  * Fix: be super-safe in index.js as well (@TooTallNate)
-  * Fix: should check whether process exists (Tom Newby)
-
-2.3.1 / 2016-11-09
-==================
-
-  * Fix: Added electron compatibility (#324, @paulcbetts)
-  * Improvement: Added performance optimizations (@tootallnate)
-  * Readme: Corrected PowerShell environment variable example (#252, @gimre)
-  * Misc: Removed yarn lock file from source control (#321, @fengmk2)
-
-2.3.0 / 2016-11-07
-==================
-
-  * Fix: Consistent placement of ms diff at end of output (#215, @gorangajic)
-  * Fix: Escaping of regex special characters in namespace strings (#250, @zacronos)
-  * Fix: Fixed bug causing crash on react-native (#282, @vkarpov15)
-  * Feature: Enabled ES6+ compatible import via default export (#212 @bucaran)
-  * Feature: Added %O formatter to reflect Chrome's console.log capability (#279, @oncletom)
-  * Package: Update "ms" to 0.7.2 (#315, @DevSide)
-  * Package: removed superfluous version property from bower.json (#207 @kkirsche)
-  * Readme: fix USE_COLORS to DEBUG_COLORS
-  * Readme: Doc fixes for format string sugar (#269, @mlucool)
-  * Readme: Updated docs for DEBUG_FD and DEBUG_COLORS environment variables (#232, @mattlyons0)
-  * Readme: doc fixes for PowerShell (#271 #243, @exoticknight @unreadable)
-  * Readme: better docs for browser support (#224, @matthewmueller)
-  * Tooling: Added yarn integration for development (#317, @thebigredgeek)
-  * Misc: Renamed History.md to CHANGELOG.md (@thebigredgeek)
-  * Misc: Added license file (#226 #274, @CantemoInternal @sdaitzman)
-  * Misc: Updated contributors (@thebigredgeek)
-
-2.2.0 / 2015-05-09
-==================
-
-  * package: update "ms" to v0.7.1 (#202, @dougwilson)
-  * README: add logging to file example (#193, @DanielOchoa)
-  * README: fixed a typo (#191, @amir-s)
-  * browser: expose `storage` (#190, @stephenmathieson)
-  * Makefile: add a `distclean` target (#189, @stephenmathieson)
-
-2.1.3 / 2015-03-13
-==================
-
-  * Updated stdout/stderr example (#186)
-  * Updated example/stdout.js to match debug current behaviour
-  * Renamed example/stderr.js to stdout.js
-  * Update Readme.md (#184)
-  * replace high intensity foreground color for bold (#182, #183)
-
-2.1.2 / 2015-03-01
-==================
-
-  * dist: recompile
-  * update "ms" to v0.7.0
-  * package: update "browserify" to v9.0.3
-  * component: fix "ms.js" repo location
-  * changed bower package name
-  * updated documentation about using debug in a browser
-  * fix: security error on safari (#167, #168, @yields)
-
-2.1.1 / 2014-12-29
-==================
-
-  * browser: use `typeof` to check for `console` existence
-  * browser: check for `console.log` truthiness (fix IE 8/9)
-  * browser: add support for Chrome apps
-  * Readme: added Windows usage remarks
-  * Add `bower.json` to properly support bower install
-
-2.1.0 / 2014-10-15
-==================
-
-  * node: implement `DEBUG_FD` env variable support
-  * package: update "browserify" to v6.1.0
-  * package: add "license" field to package.json (#135, @panuhorsmalahti)
-
-2.0.0 / 2014-09-01
-==================
-
-  * package: update "browserify" to v5.11.0
-  * node: use stderr rather than stdout for logging (#29, @stephenmathieson)
-
-1.0.4 / 2014-07-15
-==================
-
-  * dist: recompile
-  * example: remove `console.info()` log usage
-  * example: add "Content-Type" UTF-8 header to browser example
-  * browser: place %c marker after the space character
-  * browser: reset the "content" color via `color: inherit`
-  * browser: add colors support for Firefox >= v31
-  * debug: prefer an instance `log()` function over the global one (#119)
-  * Readme: update documentation about styled console logs for FF v31 (#116, @wryk)
-
-1.0.3 / 2014-07-09
-==================
-
-  * Add support for multiple wildcards in namespaces (#122, @seegno)
-  * browser: fix lint
-
-1.0.2 / 2014-06-10
-==================
-
-  * browser: update color palette (#113, @gscottolson)
-  * common: make console logging function configurable (#108, @timoxley)
-  * node: fix %o colors on old node <= 0.8.x
-  * Makefile: find node path using shell/which (#109, @timoxley)
-
-1.0.1 / 2014-06-06
-==================
-
-  * browser: use `removeItem()` to clear localStorage
-  * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
-  * package: add "contributors" section
-  * node: fix comment typo
-  * README: list authors
-
-1.0.0 / 2014-06-04
-==================
-
-  * make ms diff be global, not be scope
-  * debug: ignore empty strings in enable()
-  * node: make DEBUG_COLORS able to disable coloring
-  * *: export the `colors` array
-  * npmignore: don't publish the `dist` dir
-  * Makefile: refactor to use browserify
-  * package: add "browserify" as a dev dependency
-  * Readme: add Web Inspector Colors section
-  * node: reset terminal color for the debug content
-  * node: map "%o" to `util.inspect()`
-  * browser: map "%j" to `JSON.stringify()`
-  * debug: add custom "formatters"
-  * debug: use "ms" module for humanizing the diff
-  * Readme: add "bash" syntax highlighting
-  * browser: add Firebug color support
-  * browser: add colors for WebKit browsers
-  * node: apply log to `console`
-  * rewrite: abstract common logic for Node & browsers
-  * add .jshintrc file
-
-0.8.1 / 2014-04-14
-==================
-
-  * package: re-add the "component" section
-
-0.8.0 / 2014-03-30
-==================
-
-  * add `enable()` method for nodejs. Closes #27
-  * change from stderr to stdout
-  * remove unnecessary index.js file
-
-0.7.4 / 2013-11-13
-==================
-
-  * remove "browserify" key from package.json (fixes something in browserify)
-
-0.7.3 / 2013-10-30
-==================
-
-  * fix: catch localStorage security error when cookies are blocked (Chrome)
-  * add debug(err) support. Closes #46
-  * add .browser prop to package.json. Closes #42
-
-0.7.2 / 2013-02-06
-==================
-
-  * fix package.json
-  * fix: Mobile Safari (private mode) is broken with debug
-  * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
-
-0.7.1 / 2013-02-05
-==================
-
-  * add repository URL to package.json
-  * add DEBUG_COLORED to force colored output
-  * add browserify support
-  * fix component. Closes #24
-
-0.7.0 / 2012-05-04
-==================
-
-  * Added .component to package.json
-  * Added debug.component.js build
-
-0.6.0 / 2012-03-16
-==================
-
-  * Added support for "-" prefix in DEBUG [Vinay Pulim]
-  * Added `.enabled` flag to the node version [TooTallNate]
-
-0.5.0 / 2012-02-02
-==================
-
-  * Added: humanize diffs. Closes #8
-  * Added `debug.disable()` to the CS variant
-  * Removed padding. Closes #10
-  * Fixed: persist client-side variant again. Closes #9
-
-0.4.0 / 2012-02-01
-==================
-
-  * Added browser variant support for older browsers [TooTallNate]
-  * Added `debug.enable('project:*')` to browser variant [TooTallNate]
-  * Added padding to diff (moved it to the right)
-
-0.3.0 / 2012-01-26
-==================
-
-  * Added millisecond diff when isatty, otherwise UTC string
-
-0.2.0 / 2012-01-22
-==================
-
-  * Added wildcard support
-
-0.1.0 / 2011-12-02
-==================
-
-  * Added: remove colors unless stderr isatty [TooTallNate]
-
-0.0.1 / 2010-01-03
-==================
-
-  * Initial release
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/LICENSE b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/LICENSE
deleted file mode 100644 (file)
index 658c933..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
-and associated documentation files (the 'Software'), to deal in the Software without restriction, 
-including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
-and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial 
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
-LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/Makefile b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/Makefile
deleted file mode 100644 (file)
index 584da8b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
-THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
-THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
-
-# BIN directory
-BIN := $(THIS_DIR)/node_modules/.bin
-
-# Path
-PATH := node_modules/.bin:$(PATH)
-SHELL := /bin/bash
-
-# applications
-NODE ?= $(shell which node)
-YARN ?= $(shell which yarn)
-PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm))
-BROWSERIFY ?= $(NODE) $(BIN)/browserify
-
-.FORCE:
-
-install: node_modules
-
-node_modules: package.json
-       @NODE_ENV= $(PKG) install
-       @touch node_modules
-
-lint: .FORCE
-       eslint browser.js debug.js index.js node.js
-
-test-node: .FORCE
-       istanbul cover node_modules/mocha/bin/_mocha -- test/**.js
-
-test-browser: .FORCE
-       mkdir -p dist
-
-       @$(BROWSERIFY) \
-               --standalone debug \
-               . > dist/debug.js
-
-       karma start --single-run
-       rimraf dist
-
-test: .FORCE
-       concurrently \
-               "make test-node" \
-               "make test-browser"
-
-coveralls:
-       cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
-
-.PHONY: all install clean distclean
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/README.md b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/README.md
deleted file mode 100644 (file)
index f67be6b..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-# debug
-[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug)  [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master)  [![Slack](https://visionmedia-community-slackin.now.sh/badge.svg)](https://visionmedia-community-slackin.now.sh/) [![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers) 
-[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)
-
-
-
-A tiny node.js debugging utility modelled after node core's debugging technique.
-
-**Discussion around the V3 API is under way [here](https://github.com/visionmedia/debug/issues/370)**
-
-## Installation
-
-```bash
-$ npm install debug
-```
-
-## Usage
-
-`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
-
-Example _app.js_:
-
-```js
-var debug = require('debug')('http')
-  , http = require('http')
-  , name = 'My App';
-
-// fake app
-
-debug('booting %s', name);
-
-http.createServer(function(req, res){
-  debug(req.method + ' ' + req.url);
-  res.end('hello\n');
-}).listen(3000, function(){
-  debug('listening');
-});
-
-// fake worker of some kind
-
-require('./worker');
-```
-
-Example _worker.js_:
-
-```js
-var debug = require('debug')('worker');
-
-setInterval(function(){
-  debug('doing some work');
-}, 1000);
-```
-
- The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
-
-  ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)
-
-  ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)
-
-#### Windows note
-
- On Windows the environment variable is set using the `set` command.
-
- ```cmd
- set DEBUG=*,-not_this
- ```
-
- Note that PowerShell uses different syntax to set environment variables.
-
- ```cmd
- $env:DEBUG = "*,-not_this"
-  ```
-
-Then, run the program to be debugged as usual.
-
-## Millisecond diff
-
-  When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
-
-  ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)
-
-  When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
-
-  ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)
-
-## Conventions
-
-  If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
-
-## Wildcards
-
-  The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
-
-  You can also exclude specific debuggers by prefixing them with a "-" character.  For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
-
-## Environment Variables
-
-  When running through Node.js, you can set a few environment variables that will
-  change the behavior of the debug logging:
-
-| Name      | Purpose                                         |
-|-----------|-------------------------------------------------|
-| `DEBUG`   | Enables/disables specific debugging namespaces. |
-| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
-| `DEBUG_DEPTH` | Object inspection depth. |
-| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
-
-
-  __Note:__ The environment variables beginning with `DEBUG_` end up being
-  converted into an Options object that gets used with `%o`/`%O` formatters.
-  See the Node.js documentation for
-  [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
-  for the complete list.
-
-## Formatters
-
-
-  Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. Below are the officially supported formatters:
-
-| Formatter | Representation |
-|-----------|----------------|
-| `%O`      | Pretty-print an Object on multiple lines. |
-| `%o`      | Pretty-print an Object all on a single line. |
-| `%s`      | String. |
-| `%d`      | Number (both integer and float). |
-| `%j`      | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
-| `%%`      | Single percent sign ('%'). This does not consume an argument. |
-
-### Custom formatters
-
-  You can add custom formatters by extending the `debug.formatters` object. For example, if you wanted to add support for rendering a Buffer as hex with `%h`, you could do something like:
-
-```js
-const createDebug = require('debug')
-createDebug.formatters.h = (v) => {
-  return v.toString('hex')
-}
-
-// …elsewhere
-const debug = createDebug('foo')
-debug('this is hex: %h', new Buffer('hello world'))
-//   foo this is hex: 68656c6c6f20776f726c6421 +0ms
-```
-
-## Browser support
-  You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
-  or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
-  if you don't want to build it yourself.
-
-  Debug's enable state is currently persisted by `localStorage`.
-  Consider the situation shown below where you have `worker:a` and `worker:b`,
-  and wish to debug both. You can enable this using `localStorage.debug`:
-
-```js
-localStorage.debug = 'worker:*'
-```
-
-And then refresh the page.
-
-```js
-a = debug('worker:a');
-b = debug('worker:b');
-
-setInterval(function(){
-  a('doing some work');
-}, 1000);
-
-setInterval(function(){
-  b('doing some work');
-}, 1200);
-```
-
-#### Web Inspector Colors
-
-  Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
-  option. These are WebKit web inspectors, Firefox ([since version
-  31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
-  and the Firebug plugin for Firefox (any version).
-
-  Colored output looks something like:
-
-  ![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)
-
-
-## Output streams
-
-  By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
-
-Example _stdout.js_:
-
-```js
-var debug = require('debug');
-var error = debug('app:error');
-
-// by default stderr is used
-error('goes to stderr!');
-
-var log = debug('app:log');
-// set this namespace to log via console.log
-log.log = console.log.bind(console); // don't forget to bind to console!
-log('goes to stdout');
-error('still goes to stderr!');
-
-// set all output to go via console.info
-// overrides all per-namespace log settings
-debug.log = console.info.bind(console);
-error('now goes to stdout via console.info');
-log('still goes to stdout, but via console.info now');
-```
-
-
-## Authors
-
- - TJ Holowaychuk
- - Nathan Rajlich
- - Andrew Rhyne
-## Backers
-
-Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
-
-<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
-
-
-## Sponsors
-
-Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
-
-<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
-
-## License
-
-(The MIT License)
-
-Copyright (c) 2014-2016 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/component.json b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/component.json
deleted file mode 100644 (file)
index 9de2641..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "debug",
-  "repo": "visionmedia/debug",
-  "description": "small debugging utility",
-  "version": "2.6.9",
-  "keywords": [
-    "debug",
-    "log",
-    "debugger"
-  ],
-  "main": "src/browser.js",
-  "scripts": [
-    "src/browser.js",
-    "src/debug.js"
-  ],
-  "dependencies": {
-    "rauchg/ms.js": "0.7.1"
-  }
-}
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/karma.conf.js b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/karma.conf.js
deleted file mode 100644 (file)
index 103a82d..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// Karma configuration
-// Generated on Fri Dec 16 2016 13:09:51 GMT+0000 (UTC)
-
-module.exports = function(config) {
-  config.set({
-
-    // base path that will be used to resolve all patterns (eg. files, exclude)
-    basePath: '',
-
-
-    // frameworks to use
-    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
-    frameworks: ['mocha', 'chai', 'sinon'],
-
-
-    // list of files / patterns to load in the browser
-    files: [
-      'dist/debug.js',
-      'test/*spec.js'
-    ],
-
-
-    // list of files to exclude
-    exclude: [
-      'src/node.js'
-    ],
-
-
-    // preprocess matching files before serving them to the browser
-    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
-    preprocessors: {
-    },
-
-    // test results reporter to use
-    // possible values: 'dots', 'progress'
-    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
-    reporters: ['progress'],
-
-
-    // web server port
-    port: 9876,
-
-
-    // enable / disable colors in the output (reporters and logs)
-    colors: true,
-
-
-    // level of logging
-    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
-    logLevel: config.LOG_INFO,
-
-
-    // enable / disable watching file and executing tests whenever any file changes
-    autoWatch: true,
-
-
-    // start these browsers
-    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
-    browsers: ['PhantomJS'],
-
-
-    // Continuous Integration mode
-    // if true, Karma captures browsers, runs the tests and exits
-    singleRun: false,
-
-    // Concurrency level
-    // how many browser should be started simultaneous
-    concurrency: Infinity
-  })
-}
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/node.js b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/node.js
deleted file mode 100644 (file)
index 7fc36fe..0000000
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./src/node');
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/package.json b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/package.json
deleted file mode 100644 (file)
index 0d0fe9a..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-{
-  "_from": "debug@2.6.9",
-  "_id": "debug@2.6.9",
-  "_inBundle": false,
-  "_integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-  "_location": "/body-parser/debug",
-  "_phantomChildren": {},
-  "_requested": {
-    "type": "version",
-    "registry": true,
-    "raw": "debug@2.6.9",
-    "name": "debug",
-    "escapedName": "debug",
-    "rawSpec": "2.6.9",
-    "saveSpec": null,
-    "fetchSpec": "2.6.9"
-  },
-  "_requiredBy": [
-    "/body-parser"
-  ],
-  "_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-  "_shasum": "5d128515df134ff327e90a4c93f4e077a536341f",
-  "_spec": "debug@2.6.9",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/body-parser",
-  "author": {
-    "name": "TJ Holowaychuk",
-    "email": "tj@vision-media.ca"
-  },
-  "browser": "./src/browser.js",
-  "bugs": {
-    "url": "https://github.com/visionmedia/debug/issues"
-  },
-  "bundleDependencies": false,
-  "component": {
-    "scripts": {
-      "debug/index.js": "browser.js",
-      "debug/debug.js": "debug.js"
-    }
-  },
-  "contributors": [
-    {
-      "name": "Nathan Rajlich",
-      "email": "nathan@tootallnate.net",
-      "url": "http://n8.io"
-    },
-    {
-      "name": "Andrew Rhyne",
-      "email": "rhyneandrew@gmail.com"
-    }
-  ],
-  "dependencies": {
-    "ms": "2.0.0"
-  },
-  "deprecated": false,
-  "description": "small debugging utility",
-  "devDependencies": {
-    "browserify": "9.0.3",
-    "chai": "^3.5.0",
-    "concurrently": "^3.1.0",
-    "coveralls": "^2.11.15",
-    "eslint": "^3.12.1",
-    "istanbul": "^0.4.5",
-    "karma": "^1.3.0",
-    "karma-chai": "^0.1.0",
-    "karma-mocha": "^1.3.0",
-    "karma-phantomjs-launcher": "^1.0.2",
-    "karma-sinon": "^1.0.5",
-    "mocha": "^3.2.0",
-    "mocha-lcov-reporter": "^1.2.0",
-    "rimraf": "^2.5.4",
-    "sinon": "^1.17.6",
-    "sinon-chai": "^2.8.0"
-  },
-  "homepage": "https://github.com/visionmedia/debug#readme",
-  "keywords": [
-    "debug",
-    "log",
-    "debugger"
-  ],
-  "license": "MIT",
-  "main": "./src/index.js",
-  "name": "debug",
-  "repository": {
-    "type": "git",
-    "url": "git://github.com/visionmedia/debug.git"
-  },
-  "version": "2.6.9"
-}
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/browser.js b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/browser.js
deleted file mode 100644 (file)
index 7106924..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * This is the web browser implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-exports.storage = 'undefined' != typeof chrome
-               && 'undefined' != typeof chrome.storage
-                  ? chrome.storage.local
-                  : localstorage();
-
-/**
- * Colors.
- */
-
-exports.colors = [
-  'lightseagreen',
-  'forestgreen',
-  'goldenrod',
-  'dodgerblue',
-  'darkorchid',
-  'crimson'
-];
-
-/**
- * Currently only WebKit-based Web Inspectors, Firefox >= v31,
- * and the Firebug extension (any Firefox version) are known
- * to support "%c" CSS customizations.
- *
- * TODO: add a `localStorage` variable to explicitly enable/disable colors
- */
-
-function useColors() {
-  // NB: In an Electron preload script, document will be defined but not fully
-  // initialized. Since we know we're in Chrome, we'll just detect this case
-  // explicitly
-  if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
-    return true;
-  }
-
-  // is webkit? http://stackoverflow.com/a/16459606/376773
-  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
-  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
-    // is firebug? http://stackoverflow.com/a/398120/376773
-    (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
-    // is firefox >= v31?
-    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
-    (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
-    // double check webkit in userAgent just in case we are in a worker
-    (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
-}
-
-/**
- * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
- */
-
-exports.formatters.j = function(v) {
-  try {
-    return JSON.stringify(v);
-  } catch (err) {
-    return '[UnexpectedJSONParseError]: ' + err.message;
-  }
-};
-
-
-/**
- * Colorize log arguments if enabled.
- *
- * @api public
- */
-
-function formatArgs(args) {
-  var useColors = this.useColors;
-
-  args[0] = (useColors ? '%c' : '')
-    + this.namespace
-    + (useColors ? ' %c' : ' ')
-    + args[0]
-    + (useColors ? '%c ' : ' ')
-    + '+' + exports.humanize(this.diff);
-
-  if (!useColors) return;
-
-  var c = 'color: ' + this.color;
-  args.splice(1, 0, c, 'color: inherit')
-
-  // the final "%c" is somewhat tricky, because there could be other
-  // arguments passed either before or after the %c, so we need to
-  // figure out the correct index to insert the CSS into
-  var index = 0;
-  var lastC = 0;
-  args[0].replace(/%[a-zA-Z%]/g, function(match) {
-    if ('%%' === match) return;
-    index++;
-    if ('%c' === match) {
-      // we only are interested in the *last* %c
-      // (the user may have provided their own)
-      lastC = index;
-    }
-  });
-
-  args.splice(lastC, 0, c);
-}
-
-/**
- * Invokes `console.log()` when available.
- * No-op when `console.log` is not a "function".
- *
- * @api public
- */
-
-function log() {
-  // this hackery is required for IE8/9, where
-  // the `console.log` function doesn't have 'apply'
-  return 'object' === typeof console
-    && console.log
-    && Function.prototype.apply.call(console.log, console, arguments);
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
-  try {
-    if (null == namespaces) {
-      exports.storage.removeItem('debug');
-    } else {
-      exports.storage.debug = namespaces;
-    }
-  } catch(e) {}
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
-  var r;
-  try {
-    r = exports.storage.debug;
-  } catch(e) {}
-
-  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
-  if (!r && typeof process !== 'undefined' && 'env' in process) {
-    r = process.env.DEBUG;
-  }
-
-  return r;
-}
-
-/**
- * Enable namespaces listed in `localStorage.debug` initially.
- */
-
-exports.enable(load());
-
-/**
- * Localstorage attempts to return the localstorage.
- *
- * This is necessary because safari throws
- * when a user disables cookies/localstorage
- * and you attempt to access it.
- *
- * @return {LocalStorage}
- * @api private
- */
-
-function localstorage() {
-  try {
-    return window.localStorage;
-  } catch (e) {}
-}
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/debug.js b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/debug.js
deleted file mode 100644 (file)
index 6a5e3fc..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-
-/**
- * This is the common logic for both the Node.js and web browser
- * implementations of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
-exports.coerce = coerce;
-exports.disable = disable;
-exports.enable = enable;
-exports.enabled = enabled;
-exports.humanize = require('ms');
-
-/**
- * The currently active debug mode names, and names to skip.
- */
-
-exports.names = [];
-exports.skips = [];
-
-/**
- * Map of special "%n" handling functions, for the debug "format" argument.
- *
- * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
- */
-
-exports.formatters = {};
-
-/**
- * Previous log timestamp.
- */
-
-var prevTime;
-
-/**
- * Select a color.
- * @param {String} namespace
- * @return {Number}
- * @api private
- */
-
-function selectColor(namespace) {
-  var hash = 0, i;
-
-  for (i in namespace) {
-    hash  = ((hash << 5) - hash) + namespace.charCodeAt(i);
-    hash |= 0; // Convert to 32bit integer
-  }
-
-  return exports.colors[Math.abs(hash) % exports.colors.length];
-}
-
-/**
- * Create a debugger with the given `namespace`.
- *
- * @param {String} namespace
- * @return {Function}
- * @api public
- */
-
-function createDebug(namespace) {
-
-  function debug() {
-    // disabled?
-    if (!debug.enabled) return;
-
-    var self = debug;
-
-    // set `diff` timestamp
-    var curr = +new Date();
-    var ms = curr - (prevTime || curr);
-    self.diff = ms;
-    self.prev = prevTime;
-    self.curr = curr;
-    prevTime = curr;
-
-    // turn the `arguments` into a proper Array
-    var args = new Array(arguments.length);
-    for (var i = 0; i < args.length; i++) {
-      args[i] = arguments[i];
-    }
-
-    args[0] = exports.coerce(args[0]);
-
-    if ('string' !== typeof args[0]) {
-      // anything else let's inspect with %O
-      args.unshift('%O');
-    }
-
-    // apply any `formatters` transformations
-    var index = 0;
-    args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
-      // if we encounter an escaped % then don't increase the array index
-      if (match === '%%') return match;
-      index++;
-      var formatter = exports.formatters[format];
-      if ('function' === typeof formatter) {
-        var val = args[index];
-        match = formatter.call(self, val);
-
-        // now we need to remove `args[index]` since it's inlined in the `format`
-        args.splice(index, 1);
-        index--;
-      }
-      return match;
-    });
-
-    // apply env-specific formatting (colors, etc.)
-    exports.formatArgs.call(self, args);
-
-    var logFn = debug.log || exports.log || console.log.bind(console);
-    logFn.apply(self, args);
-  }
-
-  debug.namespace = namespace;
-  debug.enabled = exports.enabled(namespace);
-  debug.useColors = exports.useColors();
-  debug.color = selectColor(namespace);
-
-  // env-specific initialization logic for debug instances
-  if ('function' === typeof exports.init) {
-    exports.init(debug);
-  }
-
-  return debug;
-}
-
-/**
- * Enables a debug mode by namespaces. This can include modes
- * separated by a colon and wildcards.
- *
- * @param {String} namespaces
- * @api public
- */
-
-function enable(namespaces) {
-  exports.save(namespaces);
-
-  exports.names = [];
-  exports.skips = [];
-
-  var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
-  var len = split.length;
-
-  for (var i = 0; i < len; i++) {
-    if (!split[i]) continue; // ignore empty strings
-    namespaces = split[i].replace(/\*/g, '.*?');
-    if (namespaces[0] === '-') {
-      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
-    } else {
-      exports.names.push(new RegExp('^' + namespaces + '$'));
-    }
-  }
-}
-
-/**
- * Disable debug output.
- *
- * @api public
- */
-
-function disable() {
-  exports.enable('');
-}
-
-/**
- * Returns true if the given mode name is enabled, false otherwise.
- *
- * @param {String} name
- * @return {Boolean}
- * @api public
- */
-
-function enabled(name) {
-  var i, len;
-  for (i = 0, len = exports.skips.length; i < len; i++) {
-    if (exports.skips[i].test(name)) {
-      return false;
-    }
-  }
-  for (i = 0, len = exports.names.length; i < len; i++) {
-    if (exports.names[i].test(name)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-/**
- * Coerce `val`.
- *
- * @param {Mixed} val
- * @return {Mixed}
- * @api private
- */
-
-function coerce(val) {
-  if (val instanceof Error) return val.stack || val.message;
-  return val;
-}
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/index.js b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/index.js
deleted file mode 100644 (file)
index e12cf4d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Detect Electron renderer process, which is node, but we should
- * treat as a browser.
- */
-
-if (typeof process !== 'undefined' && process.type === 'renderer') {
-  module.exports = require('./browser.js');
-} else {
-  module.exports = require('./node.js');
-}
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/inspector-log.js b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/inspector-log.js
deleted file mode 100644 (file)
index 60ea6c0..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-module.exports = inspectorLog;
-
-// black hole
-const nullStream = new (require('stream').Writable)();
-nullStream._write = () => {};
-
-/**
- * Outputs a `console.log()` to the Node.js Inspector console *only*.
- */
-function inspectorLog() {
-  const stdout = console._stdout;
-  console._stdout = nullStream;
-  console.log.apply(console, arguments);
-  console._stdout = stdout;
-}
diff --git a/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/node.js b/d2d_app/node_modules/express/node_modules/body-parser/node_modules/debug/src/node.js
deleted file mode 100644 (file)
index b15109c..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var tty = require('tty');
-var util = require('util');
-
-/**
- * This is the Node.js implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.init = init;
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-
-/**
- * Colors.
- */
-
-exports.colors = [6, 2, 3, 4, 5, 1];
-
-/**
- * Build up the default `inspectOpts` object from the environment variables.
- *
- *   $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
- */
-
-exports.inspectOpts = Object.keys(process.env).filter(function (key) {
-  return /^debug_/i.test(key);
-}).reduce(function (obj, key) {
-  // camel-case
-  var prop = key
-    .substring(6)
-    .toLowerCase()
-    .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() });
-
-  // coerce string value into JS value
-  var val = process.env[key];
-  if (/^(yes|on|true|enabled)$/i.test(val)) val = true;
-  else if (/^(no|off|false|disabled)$/i.test(val)) val = false;
-  else if (val === 'null') val = null;
-  else val = Number(val);
-
-  obj[prop] = val;
-  return obj;
-}, {});
-
-/**
- * The file descriptor to write the `debug()` calls to.
- * Set the `DEBUG_FD` env variable to override with another value. i.e.:
- *
- *   $ DEBUG_FD=3 node script.js 3>debug.log
- */
-
-var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
-
-if (1 !== fd && 2 !== fd) {
-  util.deprecate(function(){}, 'except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)')()
-}
-
-var stream = 1 === fd ? process.stdout :
-             2 === fd ? process.stderr :
-             createWritableStdioStream(fd);
-
-/**
- * Is stdout a TTY? Colored output is enabled when `true`.
- */
-
-function useColors() {
-  return 'colors' in exports.inspectOpts
-    ? Boolean(exports.inspectOpts.colors)
-    : tty.isatty(fd);
-}
-
-/**
- * Map %o to `util.inspect()`, all on a single line.
- */
-
-exports.formatters.o = function(v) {
-  this.inspectOpts.colors = this.useColors;
-  return util.inspect(v, this.inspectOpts)
-    .split('\n').map(function(str) {
-      return str.trim()
-    }).join(' ');
-};
-
-/**
- * Map %o to `util.inspect()`, allowing multiple lines if needed.
- */
-
-exports.formatters.O = function(v) {
-  this.inspectOpts.colors = this.useColors;
-  return util.inspect(v, this.inspectOpts);
-};
-
-/**
- * Adds ANSI color escape codes if enabled.
- *
- * @api public
- */
-
-function formatArgs(args) {
-  var name = this.namespace;
-  var useColors = this.useColors;
-
-  if (useColors) {
-    var c = this.color;
-    var prefix = '  \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m';
-
-    args[0] = prefix + args[0].split('\n').join('\n' + prefix);
-    args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
-  } else {
-    args[0] = new Date().toUTCString()
-      + ' ' + name + ' ' + args[0];
-  }
-}
-
-/**
- * Invokes `util.format()` with the specified arguments and writes to `stream`.
- */
-
-function log() {
-  return stream.write(util.format.apply(util, arguments) + '\n');
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
-  if (null == namespaces) {
-    // If you set a process.env field to null or undefined, it gets cast to the
-    // string 'null' or 'undefined'. Just delete instead.
-    delete process.env.DEBUG;
-  } else {
-    process.env.DEBUG = namespaces;
-  }
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
-  return process.env.DEBUG;
-}
-
-/**
- * Copied from `node/src/node.js`.
- *
- * XXX: It's lame that node doesn't expose this API out-of-the-box. It also
- * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
- */
-
-function createWritableStdioStream (fd) {
-  var stream;
-  var tty_wrap = process.binding('tty_wrap');
-
-  // Note stream._type is used for test-module-load-list.js
-
-  switch (tty_wrap.guessHandleType(fd)) {
-    case 'TTY':
-      stream = new tty.WriteStream(fd);
-      stream._type = 'tty';
-
-      // Hack to have stream not keep the event loop alive.
-      // See https://github.com/joyent/node/issues/1726
-      if (stream._handle && stream._handle.unref) {
-        stream._handle.unref();
-      }
-      break;
-
-    case 'FILE':
-      var fs = require('fs');
-      stream = new fs.SyncWriteStream(fd, { autoClose: false });
-      stream._type = 'fs';
-      break;
-
-    case 'PIPE':
-    case 'TCP':
-      var net = require('net');
-      stream = new net.Socket({
-        fd: fd,
-        readable: false,
-        writable: true
-      });
-
-      // FIXME Should probably have an option in net.Socket to create a
-      // stream from an existing fd which is writable only. But for now
-      // we'll just add this hack and set the `readable` member to false.
-      // Test: ./node test/fixtures/echo.js < /etc/passwd
-      stream.readable = false;
-      stream.read = null;
-      stream._type = 'pipe';
-
-      // FIXME Hack to have stream not keep the event loop alive.
-      // See https://github.com/joyent/node/issues/1726
-      if (stream._handle && stream._handle.unref) {
-        stream._handle.unref();
-      }
-      break;
-
-    default:
-      // Probably an error on in uv_guess_handle()
-      throw new Error('Implement me. Unknown stream file type!');
-  }
-
-  // For supporting legacy API we put the FD here.
-  stream.fd = fd;
-
-  stream._isStdio = true;
-
-  return stream;
-}
-
-/**
- * Init logic for `debug` instances.
- *
- * Create a new `inspectOpts` object in case `useColors` is set
- * differently for a particular `debug` instance.
- */
-
-function init (debug) {
-  debug.inspectOpts = {};
-
-  var keys = Object.keys(exports.inspectOpts);
-  for (var i = 0; i < keys.length; i++) {
-    debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
-  }
-}
-
-/**
- * Enable namespaces listed in `process.env.DEBUG` initially.
- */
-
-exports.enable(load());
diff --git a/d2d_app/node_modules/express/node_modules/debug/.coveralls.yml b/d2d_app/node_modules/express/node_modules/debug/.coveralls.yml
deleted file mode 100644 (file)
index 20a7068..0000000
+++ /dev/null
@@ -1 +0,0 @@
-repo_token: SIAeZjKYlHK74rbcFvNHMUzjRiMpflxve
diff --git a/d2d_app/node_modules/express/node_modules/debug/.eslintrc b/d2d_app/node_modules/express/node_modules/debug/.eslintrc
deleted file mode 100644 (file)
index 8a37ae2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "env": {
-    "browser": true,
-    "node": true
-  },
-  "rules": {
-    "no-console": 0,
-    "no-empty": [1, { "allowEmptyCatch": true }]
-  },
-  "extends": "eslint:recommended"
-}
diff --git a/d2d_app/node_modules/express/node_modules/debug/.npmignore b/d2d_app/node_modules/express/node_modules/debug/.npmignore
deleted file mode 100644 (file)
index 5f60eec..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-support
-test
-examples
-example
-*.sock
-dist
-yarn.lock
-coverage
-bower.json
diff --git a/d2d_app/node_modules/express/node_modules/debug/.travis.yml b/d2d_app/node_modules/express/node_modules/debug/.travis.yml
deleted file mode 100644 (file)
index 6c6090c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-language: node_js
-node_js:
-  - "6"
-  - "5"
-  - "4"
-
-install:
-  - make node_modules
-
-script:
-  - make lint
-  - make test
-  - make coveralls
diff --git a/d2d_app/node_modules/express/node_modules/debug/CHANGELOG.md b/d2d_app/node_modules/express/node_modules/debug/CHANGELOG.md
deleted file mode 100644 (file)
index eadaa18..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-
-2.6.9 / 2017-09-22
-==================
-
-  * remove ReDoS regexp in %o formatter (#504)
-
-2.6.8 / 2017-05-18
-==================
-
-  * Fix: Check for undefined on browser globals (#462, @marbemac)
-
-2.6.7 / 2017-05-16
-==================
-
-  * Fix: Update ms to 2.0.0 to fix regular expression denial of service vulnerability (#458, @hubdotcom)
-  * Fix: Inline extend function in node implementation (#452, @dougwilson)
-  * Docs: Fix typo (#455, @msasad)
-
-2.6.5 / 2017-04-27
-==================
-  
-  * Fix: null reference check on window.documentElement.style.WebkitAppearance (#447, @thebigredgeek)
-  * Misc: clean up browser reference checks (#447, @thebigredgeek)
-  * Misc: add npm-debug.log to .gitignore (@thebigredgeek)
-
-
-2.6.4 / 2017-04-20
-==================
-
-  * Fix: bug that would occure if process.env.DEBUG is a non-string value. (#444, @LucianBuzzo)
-  * Chore: ignore bower.json in npm installations. (#437, @joaovieira)
-  * Misc: update "ms" to v0.7.3 (@tootallnate)
-
-2.6.3 / 2017-03-13
-==================
-
-  * Fix: Electron reference to `process.env.DEBUG` (#431, @paulcbetts)
-  * Docs: Changelog fix (@thebigredgeek)
-
-2.6.2 / 2017-03-10
-==================
-
-  * Fix: DEBUG_MAX_ARRAY_LENGTH (#420, @slavaGanzin)
-  * Docs: Add backers and sponsors from Open Collective (#422, @piamancini)
-  * Docs: Add Slackin invite badge (@tootallnate)
-
-2.6.1 / 2017-02-10
-==================
-
-  * Fix: Module's `export default` syntax fix for IE8 `Expected identifier` error
-  * Fix: Whitelist DEBUG_FD for values 1 and 2 only (#415, @pi0)
-  * Fix: IE8 "Expected identifier" error (#414, @vgoma)
-  * Fix: Namespaces would not disable once enabled (#409, @musikov)
-
-2.6.0 / 2016-12-28
-==================
-
-  * Fix: added better null pointer checks for browser useColors (@thebigredgeek)
-  * Improvement: removed explicit `window.debug` export (#404, @tootallnate)
-  * Improvement: deprecated `DEBUG_FD` environment variable (#405, @tootallnate)
-
-2.5.2 / 2016-12-25
-==================
-
-  * Fix: reference error on window within webworkers (#393, @KlausTrainer)
-  * Docs: fixed README typo (#391, @lurch)
-  * Docs: added notice about v3 api discussion (@thebigredgeek)
-
-2.5.1 / 2016-12-20
-==================
-
-  * Fix: babel-core compatibility
-
-2.5.0 / 2016-12-20
-==================
-
-  * Fix: wrong reference in bower file (@thebigredgeek)
-  * Fix: webworker compatibility (@thebigredgeek)
-  * Fix: output formatting issue (#388, @kribblo)
-  * Fix: babel-loader compatibility (#383, @escwald)
-  * Misc: removed built asset from repo and publications (@thebigredgeek)
-  * Misc: moved source files to /src (#378, @yamikuronue)
-  * Test: added karma integration and replaced babel with browserify for browser tests (#378, @yamikuronue)
-  * Test: coveralls integration (#378, @yamikuronue)
-  * Docs: simplified language in the opening paragraph (#373, @yamikuronue)
-
-2.4.5 / 2016-12-17
-==================
-
-  * Fix: `navigator` undefined in Rhino (#376, @jochenberger)
-  * Fix: custom log function (#379, @hsiliev)
-  * Improvement: bit of cleanup + linting fixes (@thebigredgeek)
-  * Improvement: rm non-maintainted `dist/` dir (#375, @freewil)
-  * Docs: simplified language in the opening paragraph. (#373, @yamikuronue)
-
-2.4.4 / 2016-12-14
-==================
-
-  * Fix: work around debug being loaded in preload scripts for electron (#368, @paulcbetts)
-
-2.4.3 / 2016-12-14
-==================
-
-  * Fix: navigation.userAgent error for react native (#364, @escwald)
-
-2.4.2 / 2016-12-14
-==================
-
-  * Fix: browser colors (#367, @tootallnate)
-  * Misc: travis ci integration (@thebigredgeek)
-  * Misc: added linting and testing boilerplate with sanity check (@thebigredgeek)
-
-2.4.1 / 2016-12-13
-==================
-
-  * Fix: typo that broke the package (#356)
-
-2.4.0 / 2016-12-13
-==================
-
-  * Fix: bower.json references unbuilt src entry point (#342, @justmatt)
-  * Fix: revert "handle regex special characters" (@tootallnate)
-  * Feature: configurable util.inspect()`options for NodeJS (#327, @tootallnate)
-  * Feature: %O`(big O) pretty-prints objects (#322, @tootallnate)
-  * Improvement: allow colors in workers (#335, @botverse)
-  * Improvement: use same color for same namespace. (#338, @lchenay)
-
-2.3.3 / 2016-11-09
-==================
-
-  * Fix: Catch `JSON.stringify()` errors (#195, Jovan Alleyne)
-  * Fix: Returning `localStorage` saved values (#331, Levi Thomason)
-  * Improvement: Don't create an empty object when no `process` (Nathan Rajlich)
-
-2.3.2 / 2016-11-09
-==================
-
-  * Fix: be super-safe in index.js as well (@TooTallNate)
-  * Fix: should check whether process exists (Tom Newby)
-
-2.3.1 / 2016-11-09
-==================
-
-  * Fix: Added electron compatibility (#324, @paulcbetts)
-  * Improvement: Added performance optimizations (@tootallnate)
-  * Readme: Corrected PowerShell environment variable example (#252, @gimre)
-  * Misc: Removed yarn lock file from source control (#321, @fengmk2)
-
-2.3.0 / 2016-11-07
-==================
-
-  * Fix: Consistent placement of ms diff at end of output (#215, @gorangajic)
-  * Fix: Escaping of regex special characters in namespace strings (#250, @zacronos)
-  * Fix: Fixed bug causing crash on react-native (#282, @vkarpov15)
-  * Feature: Enabled ES6+ compatible import via default export (#212 @bucaran)
-  * Feature: Added %O formatter to reflect Chrome's console.log capability (#279, @oncletom)
-  * Package: Update "ms" to 0.7.2 (#315, @DevSide)
-  * Package: removed superfluous version property from bower.json (#207 @kkirsche)
-  * Readme: fix USE_COLORS to DEBUG_COLORS
-  * Readme: Doc fixes for format string sugar (#269, @mlucool)
-  * Readme: Updated docs for DEBUG_FD and DEBUG_COLORS environment variables (#232, @mattlyons0)
-  * Readme: doc fixes for PowerShell (#271 #243, @exoticknight @unreadable)
-  * Readme: better docs for browser support (#224, @matthewmueller)
-  * Tooling: Added yarn integration for development (#317, @thebigredgeek)
-  * Misc: Renamed History.md to CHANGELOG.md (@thebigredgeek)
-  * Misc: Added license file (#226 #274, @CantemoInternal @sdaitzman)
-  * Misc: Updated contributors (@thebigredgeek)
-
-2.2.0 / 2015-05-09
-==================
-
-  * package: update "ms" to v0.7.1 (#202, @dougwilson)
-  * README: add logging to file example (#193, @DanielOchoa)
-  * README: fixed a typo (#191, @amir-s)
-  * browser: expose `storage` (#190, @stephenmathieson)
-  * Makefile: add a `distclean` target (#189, @stephenmathieson)
-
-2.1.3 / 2015-03-13
-==================
-
-  * Updated stdout/stderr example (#186)
-  * Updated example/stdout.js to match debug current behaviour
-  * Renamed example/stderr.js to stdout.js
-  * Update Readme.md (#184)
-  * replace high intensity foreground color for bold (#182, #183)
-
-2.1.2 / 2015-03-01
-==================
-
-  * dist: recompile
-  * update "ms" to v0.7.0
-  * package: update "browserify" to v9.0.3
-  * component: fix "ms.js" repo location
-  * changed bower package name
-  * updated documentation about using debug in a browser
-  * fix: security error on safari (#167, #168, @yields)
-
-2.1.1 / 2014-12-29
-==================
-
-  * browser: use `typeof` to check for `console` existence
-  * browser: check for `console.log` truthiness (fix IE 8/9)
-  * browser: add support for Chrome apps
-  * Readme: added Windows usage remarks
-  * Add `bower.json` to properly support bower install
-
-2.1.0 / 2014-10-15
-==================
-
-  * node: implement `DEBUG_FD` env variable support
-  * package: update "browserify" to v6.1.0
-  * package: add "license" field to package.json (#135, @panuhorsmalahti)
-
-2.0.0 / 2014-09-01
-==================
-
-  * package: update "browserify" to v5.11.0
-  * node: use stderr rather than stdout for logging (#29, @stephenmathieson)
-
-1.0.4 / 2014-07-15
-==================
-
-  * dist: recompile
-  * example: remove `console.info()` log usage
-  * example: add "Content-Type" UTF-8 header to browser example
-  * browser: place %c marker after the space character
-  * browser: reset the "content" color via `color: inherit`
-  * browser: add colors support for Firefox >= v31
-  * debug: prefer an instance `log()` function over the global one (#119)
-  * Readme: update documentation about styled console logs for FF v31 (#116, @wryk)
-
-1.0.3 / 2014-07-09
-==================
-
-  * Add support for multiple wildcards in namespaces (#122, @seegno)
-  * browser: fix lint
-
-1.0.2 / 2014-06-10
-==================
-
-  * browser: update color palette (#113, @gscottolson)
-  * common: make console logging function configurable (#108, @timoxley)
-  * node: fix %o colors on old node <= 0.8.x
-  * Makefile: find node path using shell/which (#109, @timoxley)
-
-1.0.1 / 2014-06-06
-==================
-
-  * browser: use `removeItem()` to clear localStorage
-  * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
-  * package: add "contributors" section
-  * node: fix comment typo
-  * README: list authors
-
-1.0.0 / 2014-06-04
-==================
-
-  * make ms diff be global, not be scope
-  * debug: ignore empty strings in enable()
-  * node: make DEBUG_COLORS able to disable coloring
-  * *: export the `colors` array
-  * npmignore: don't publish the `dist` dir
-  * Makefile: refactor to use browserify
-  * package: add "browserify" as a dev dependency
-  * Readme: add Web Inspector Colors section
-  * node: reset terminal color for the debug content
-  * node: map "%o" to `util.inspect()`
-  * browser: map "%j" to `JSON.stringify()`
-  * debug: add custom "formatters"
-  * debug: use "ms" module for humanizing the diff
-  * Readme: add "bash" syntax highlighting
-  * browser: add Firebug color support
-  * browser: add colors for WebKit browsers
-  * node: apply log to `console`
-  * rewrite: abstract common logic for Node & browsers
-  * add .jshintrc file
-
-0.8.1 / 2014-04-14
-==================
-
-  * package: re-add the "component" section
-
-0.8.0 / 2014-03-30
-==================
-
-  * add `enable()` method for nodejs. Closes #27
-  * change from stderr to stdout
-  * remove unnecessary index.js file
-
-0.7.4 / 2013-11-13
-==================
-
-  * remove "browserify" key from package.json (fixes something in browserify)
-
-0.7.3 / 2013-10-30
-==================
-
-  * fix: catch localStorage security error when cookies are blocked (Chrome)
-  * add debug(err) support. Closes #46
-  * add .browser prop to package.json. Closes #42
-
-0.7.2 / 2013-02-06
-==================
-
-  * fix package.json
-  * fix: Mobile Safari (private mode) is broken with debug
-  * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
-
-0.7.1 / 2013-02-05
-==================
-
-  * add repository URL to package.json
-  * add DEBUG_COLORED to force colored output
-  * add browserify support
-  * fix component. Closes #24
-
-0.7.0 / 2012-05-04
-==================
-
-  * Added .component to package.json
-  * Added debug.component.js build
-
-0.6.0 / 2012-03-16
-==================
-
-  * Added support for "-" prefix in DEBUG [Vinay Pulim]
-  * Added `.enabled` flag to the node version [TooTallNate]
-
-0.5.0 / 2012-02-02
-==================
-
-  * Added: humanize diffs. Closes #8
-  * Added `debug.disable()` to the CS variant
-  * Removed padding. Closes #10
-  * Fixed: persist client-side variant again. Closes #9
-
-0.4.0 / 2012-02-01
-==================
-
-  * Added browser variant support for older browsers [TooTallNate]
-  * Added `debug.enable('project:*')` to browser variant [TooTallNate]
-  * Added padding to diff (moved it to the right)
-
-0.3.0 / 2012-01-26
-==================
-
-  * Added millisecond diff when isatty, otherwise UTC string
-
-0.2.0 / 2012-01-22
-==================
-
-  * Added wildcard support
-
-0.1.0 / 2011-12-02
-==================
-
-  * Added: remove colors unless stderr isatty [TooTallNate]
-
-0.0.1 / 2010-01-03
-==================
-
-  * Initial release
diff --git a/d2d_app/node_modules/express/node_modules/debug/LICENSE b/d2d_app/node_modules/express/node_modules/debug/LICENSE
deleted file mode 100644 (file)
index 658c933..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
-and associated documentation files (the 'Software'), to deal in the Software without restriction, 
-including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
-and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial 
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
-LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/d2d_app/node_modules/express/node_modules/debug/Makefile b/d2d_app/node_modules/express/node_modules/debug/Makefile
deleted file mode 100644 (file)
index 584da8b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
-THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
-THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
-
-# BIN directory
-BIN := $(THIS_DIR)/node_modules/.bin
-
-# Path
-PATH := node_modules/.bin:$(PATH)
-SHELL := /bin/bash
-
-# applications
-NODE ?= $(shell which node)
-YARN ?= $(shell which yarn)
-PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm))
-BROWSERIFY ?= $(NODE) $(BIN)/browserify
-
-.FORCE:
-
-install: node_modules
-
-node_modules: package.json
-       @NODE_ENV= $(PKG) install
-       @touch node_modules
-
-lint: .FORCE
-       eslint browser.js debug.js index.js node.js
-
-test-node: .FORCE
-       istanbul cover node_modules/mocha/bin/_mocha -- test/**.js
-
-test-browser: .FORCE
-       mkdir -p dist
-
-       @$(BROWSERIFY) \
-               --standalone debug \
-               . > dist/debug.js
-
-       karma start --single-run
-       rimraf dist
-
-test: .FORCE
-       concurrently \
-               "make test-node" \
-               "make test-browser"
-
-coveralls:
-       cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
-
-.PHONY: all install clean distclean
diff --git a/d2d_app/node_modules/express/node_modules/debug/README.md b/d2d_app/node_modules/express/node_modules/debug/README.md
deleted file mode 100644 (file)
index f67be6b..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-# debug
-[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug)  [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master)  [![Slack](https://visionmedia-community-slackin.now.sh/badge.svg)](https://visionmedia-community-slackin.now.sh/) [![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers) 
-[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)
-
-
-
-A tiny node.js debugging utility modelled after node core's debugging technique.
-
-**Discussion around the V3 API is under way [here](https://github.com/visionmedia/debug/issues/370)**
-
-## Installation
-
-```bash
-$ npm install debug
-```
-
-## Usage
-
-`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
-
-Example _app.js_:
-
-```js
-var debug = require('debug')('http')
-  , http = require('http')
-  , name = 'My App';
-
-// fake app
-
-debug('booting %s', name);
-
-http.createServer(function(req, res){
-  debug(req.method + ' ' + req.url);
-  res.end('hello\n');
-}).listen(3000, function(){
-  debug('listening');
-});
-
-// fake worker of some kind
-
-require('./worker');
-```
-
-Example _worker.js_:
-
-```js
-var debug = require('debug')('worker');
-
-setInterval(function(){
-  debug('doing some work');
-}, 1000);
-```
-
- The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
-
-  ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)
-
-  ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)
-
-#### Windows note
-
- On Windows the environment variable is set using the `set` command.
-
- ```cmd
- set DEBUG=*,-not_this
- ```
-
- Note that PowerShell uses different syntax to set environment variables.
-
- ```cmd
- $env:DEBUG = "*,-not_this"
-  ```
-
-Then, run the program to be debugged as usual.
-
-## Millisecond diff
-
-  When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
-
-  ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)
-
-  When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
-
-  ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)
-
-## Conventions
-
-  If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
-
-## Wildcards
-
-  The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
-
-  You can also exclude specific debuggers by prefixing them with a "-" character.  For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
-
-## Environment Variables
-
-  When running through Node.js, you can set a few environment variables that will
-  change the behavior of the debug logging:
-
-| Name      | Purpose                                         |
-|-----------|-------------------------------------------------|
-| `DEBUG`   | Enables/disables specific debugging namespaces. |
-| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
-| `DEBUG_DEPTH` | Object inspection depth. |
-| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
-
-
-  __Note:__ The environment variables beginning with `DEBUG_` end up being
-  converted into an Options object that gets used with `%o`/`%O` formatters.
-  See the Node.js documentation for
-  [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
-  for the complete list.
-
-## Formatters
-
-
-  Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. Below are the officially supported formatters:
-
-| Formatter | Representation |
-|-----------|----------------|
-| `%O`      | Pretty-print an Object on multiple lines. |
-| `%o`      | Pretty-print an Object all on a single line. |
-| `%s`      | String. |
-| `%d`      | Number (both integer and float). |
-| `%j`      | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
-| `%%`      | Single percent sign ('%'). This does not consume an argument. |
-
-### Custom formatters
-
-  You can add custom formatters by extending the `debug.formatters` object. For example, if you wanted to add support for rendering a Buffer as hex with `%h`, you could do something like:
-
-```js
-const createDebug = require('debug')
-createDebug.formatters.h = (v) => {
-  return v.toString('hex')
-}
-
-// …elsewhere
-const debug = createDebug('foo')
-debug('this is hex: %h', new Buffer('hello world'))
-//   foo this is hex: 68656c6c6f20776f726c6421 +0ms
-```
-
-## Browser support
-  You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
-  or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
-  if you don't want to build it yourself.
-
-  Debug's enable state is currently persisted by `localStorage`.
-  Consider the situation shown below where you have `worker:a` and `worker:b`,
-  and wish to debug both. You can enable this using `localStorage.debug`:
-
-```js
-localStorage.debug = 'worker:*'
-```
-
-And then refresh the page.
-
-```js
-a = debug('worker:a');
-b = debug('worker:b');
-
-setInterval(function(){
-  a('doing some work');
-}, 1000);
-
-setInterval(function(){
-  b('doing some work');
-}, 1200);
-```
-
-#### Web Inspector Colors
-
-  Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
-  option. These are WebKit web inspectors, Firefox ([since version
-  31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
-  and the Firebug plugin for Firefox (any version).
-
-  Colored output looks something like:
-
-  ![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)
-
-
-## Output streams
-
-  By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
-
-Example _stdout.js_:
-
-```js
-var debug = require('debug');
-var error = debug('app:error');
-
-// by default stderr is used
-error('goes to stderr!');
-
-var log = debug('app:log');
-// set this namespace to log via console.log
-log.log = console.log.bind(console); // don't forget to bind to console!
-log('goes to stdout');
-error('still goes to stderr!');
-
-// set all output to go via console.info
-// overrides all per-namespace log settings
-debug.log = console.info.bind(console);
-error('now goes to stdout via console.info');
-log('still goes to stdout, but via console.info now');
-```
-
-
-## Authors
-
- - TJ Holowaychuk
- - Nathan Rajlich
- - Andrew Rhyne
-## Backers
-
-Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
-
-<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
-
-
-## Sponsors
-
-Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
-
-<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
-
-## License
-
-(The MIT License)
-
-Copyright (c) 2014-2016 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/express/node_modules/debug/component.json b/d2d_app/node_modules/express/node_modules/debug/component.json
deleted file mode 100644 (file)
index 9de2641..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "debug",
-  "repo": "visionmedia/debug",
-  "description": "small debugging utility",
-  "version": "2.6.9",
-  "keywords": [
-    "debug",
-    "log",
-    "debugger"
-  ],
-  "main": "src/browser.js",
-  "scripts": [
-    "src/browser.js",
-    "src/debug.js"
-  ],
-  "dependencies": {
-    "rauchg/ms.js": "0.7.1"
-  }
-}
diff --git a/d2d_app/node_modules/express/node_modules/debug/karma.conf.js b/d2d_app/node_modules/express/node_modules/debug/karma.conf.js
deleted file mode 100644 (file)
index 103a82d..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// Karma configuration
-// Generated on Fri Dec 16 2016 13:09:51 GMT+0000 (UTC)
-
-module.exports = function(config) {
-  config.set({
-
-    // base path that will be used to resolve all patterns (eg. files, exclude)
-    basePath: '',
-
-
-    // frameworks to use
-    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
-    frameworks: ['mocha', 'chai', 'sinon'],
-
-
-    // list of files / patterns to load in the browser
-    files: [
-      'dist/debug.js',
-      'test/*spec.js'
-    ],
-
-
-    // list of files to exclude
-    exclude: [
-      'src/node.js'
-    ],
-
-
-    // preprocess matching files before serving them to the browser
-    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
-    preprocessors: {
-    },
-
-    // test results reporter to use
-    // possible values: 'dots', 'progress'
-    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
-    reporters: ['progress'],
-
-
-    // web server port
-    port: 9876,
-
-
-    // enable / disable colors in the output (reporters and logs)
-    colors: true,
-
-
-    // level of logging
-    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
-    logLevel: config.LOG_INFO,
-
-
-    // enable / disable watching file and executing tests whenever any file changes
-    autoWatch: true,
-
-
-    // start these browsers
-    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
-    browsers: ['PhantomJS'],
-
-
-    // Continuous Integration mode
-    // if true, Karma captures browsers, runs the tests and exits
-    singleRun: false,
-
-    // Concurrency level
-    // how many browser should be started simultaneous
-    concurrency: Infinity
-  })
-}
diff --git a/d2d_app/node_modules/express/node_modules/debug/node.js b/d2d_app/node_modules/express/node_modules/debug/node.js
deleted file mode 100644 (file)
index 7fc36fe..0000000
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./src/node');
diff --git a/d2d_app/node_modules/express/node_modules/debug/src/browser.js b/d2d_app/node_modules/express/node_modules/debug/src/browser.js
deleted file mode 100644 (file)
index 7106924..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * This is the web browser implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-exports.storage = 'undefined' != typeof chrome
-               && 'undefined' != typeof chrome.storage
-                  ? chrome.storage.local
-                  : localstorage();
-
-/**
- * Colors.
- */
-
-exports.colors = [
-  'lightseagreen',
-  'forestgreen',
-  'goldenrod',
-  'dodgerblue',
-  'darkorchid',
-  'crimson'
-];
-
-/**
- * Currently only WebKit-based Web Inspectors, Firefox >= v31,
- * and the Firebug extension (any Firefox version) are known
- * to support "%c" CSS customizations.
- *
- * TODO: add a `localStorage` variable to explicitly enable/disable colors
- */
-
-function useColors() {
-  // NB: In an Electron preload script, document will be defined but not fully
-  // initialized. Since we know we're in Chrome, we'll just detect this case
-  // explicitly
-  if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
-    return true;
-  }
-
-  // is webkit? http://stackoverflow.com/a/16459606/376773
-  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
-  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
-    // is firebug? http://stackoverflow.com/a/398120/376773
-    (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
-    // is firefox >= v31?
-    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
-    (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
-    // double check webkit in userAgent just in case we are in a worker
-    (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
-}
-
-/**
- * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
- */
-
-exports.formatters.j = function(v) {
-  try {
-    return JSON.stringify(v);
-  } catch (err) {
-    return '[UnexpectedJSONParseError]: ' + err.message;
-  }
-};
-
-
-/**
- * Colorize log arguments if enabled.
- *
- * @api public
- */
-
-function formatArgs(args) {
-  var useColors = this.useColors;
-
-  args[0] = (useColors ? '%c' : '')
-    + this.namespace
-    + (useColors ? ' %c' : ' ')
-    + args[0]
-    + (useColors ? '%c ' : ' ')
-    + '+' + exports.humanize(this.diff);
-
-  if (!useColors) return;
-
-  var c = 'color: ' + this.color;
-  args.splice(1, 0, c, 'color: inherit')
-
-  // the final "%c" is somewhat tricky, because there could be other
-  // arguments passed either before or after the %c, so we need to
-  // figure out the correct index to insert the CSS into
-  var index = 0;
-  var lastC = 0;
-  args[0].replace(/%[a-zA-Z%]/g, function(match) {
-    if ('%%' === match) return;
-    index++;
-    if ('%c' === match) {
-      // we only are interested in the *last* %c
-      // (the user may have provided their own)
-      lastC = index;
-    }
-  });
-
-  args.splice(lastC, 0, c);
-}
-
-/**
- * Invokes `console.log()` when available.
- * No-op when `console.log` is not a "function".
- *
- * @api public
- */
-
-function log() {
-  // this hackery is required for IE8/9, where
-  // the `console.log` function doesn't have 'apply'
-  return 'object' === typeof console
-    && console.log
-    && Function.prototype.apply.call(console.log, console, arguments);
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
-  try {
-    if (null == namespaces) {
-      exports.storage.removeItem('debug');
-    } else {
-      exports.storage.debug = namespaces;
-    }
-  } catch(e) {}
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
-  var r;
-  try {
-    r = exports.storage.debug;
-  } catch(e) {}
-
-  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
-  if (!r && typeof process !== 'undefined' && 'env' in process) {
-    r = process.env.DEBUG;
-  }
-
-  return r;
-}
-
-/**
- * Enable namespaces listed in `localStorage.debug` initially.
- */
-
-exports.enable(load());
-
-/**
- * Localstorage attempts to return the localstorage.
- *
- * This is necessary because safari throws
- * when a user disables cookies/localstorage
- * and you attempt to access it.
- *
- * @return {LocalStorage}
- * @api private
- */
-
-function localstorage() {
-  try {
-    return window.localStorage;
-  } catch (e) {}
-}
diff --git a/d2d_app/node_modules/express/node_modules/debug/src/debug.js b/d2d_app/node_modules/express/node_modules/debug/src/debug.js
deleted file mode 100644 (file)
index 6a5e3fc..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-
-/**
- * This is the common logic for both the Node.js and web browser
- * implementations of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
-exports.coerce = coerce;
-exports.disable = disable;
-exports.enable = enable;
-exports.enabled = enabled;
-exports.humanize = require('ms');
-
-/**
- * The currently active debug mode names, and names to skip.
- */
-
-exports.names = [];
-exports.skips = [];
-
-/**
- * Map of special "%n" handling functions, for the debug "format" argument.
- *
- * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
- */
-
-exports.formatters = {};
-
-/**
- * Previous log timestamp.
- */
-
-var prevTime;
-
-/**
- * Select a color.
- * @param {String} namespace
- * @return {Number}
- * @api private
- */
-
-function selectColor(namespace) {
-  var hash = 0, i;
-
-  for (i in namespace) {
-    hash  = ((hash << 5) - hash) + namespace.charCodeAt(i);
-    hash |= 0; // Convert to 32bit integer
-  }
-
-  return exports.colors[Math.abs(hash) % exports.colors.length];
-}
-
-/**
- * Create a debugger with the given `namespace`.
- *
- * @param {String} namespace
- * @return {Function}
- * @api public
- */
-
-function createDebug(namespace) {
-
-  function debug() {
-    // disabled?
-    if (!debug.enabled) return;
-
-    var self = debug;
-
-    // set `diff` timestamp
-    var curr = +new Date();
-    var ms = curr - (prevTime || curr);
-    self.diff = ms;
-    self.prev = prevTime;
-    self.curr = curr;
-    prevTime = curr;
-
-    // turn the `arguments` into a proper Array
-    var args = new Array(arguments.length);
-    for (var i = 0; i < args.length; i++) {
-      args[i] = arguments[i];
-    }
-
-    args[0] = exports.coerce(args[0]);
-
-    if ('string' !== typeof args[0]) {
-      // anything else let's inspect with %O
-      args.unshift('%O');
-    }
-
-    // apply any `formatters` transformations
-    var index = 0;
-    args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
-      // if we encounter an escaped % then don't increase the array index
-      if (match === '%%') return match;
-      index++;
-      var formatter = exports.formatters[format];
-      if ('function' === typeof formatter) {
-        var val = args[index];
-        match = formatter.call(self, val);
-
-        // now we need to remove `args[index]` since it's inlined in the `format`
-        args.splice(index, 1);
-        index--;
-      }
-      return match;
-    });
-
-    // apply env-specific formatting (colors, etc.)
-    exports.formatArgs.call(self, args);
-
-    var logFn = debug.log || exports.log || console.log.bind(console);
-    logFn.apply(self, args);
-  }
-
-  debug.namespace = namespace;
-  debug.enabled = exports.enabled(namespace);
-  debug.useColors = exports.useColors();
-  debug.color = selectColor(namespace);
-
-  // env-specific initialization logic for debug instances
-  if ('function' === typeof exports.init) {
-    exports.init(debug);
-  }
-
-  return debug;
-}
-
-/**
- * Enables a debug mode by namespaces. This can include modes
- * separated by a colon and wildcards.
- *
- * @param {String} namespaces
- * @api public
- */
-
-function enable(namespaces) {
-  exports.save(namespaces);
-
-  exports.names = [];
-  exports.skips = [];
-
-  var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
-  var len = split.length;
-
-  for (var i = 0; i < len; i++) {
-    if (!split[i]) continue; // ignore empty strings
-    namespaces = split[i].replace(/\*/g, '.*?');
-    if (namespaces[0] === '-') {
-      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
-    } else {
-      exports.names.push(new RegExp('^' + namespaces + '$'));
-    }
-  }
-}
-
-/**
- * Disable debug output.
- *
- * @api public
- */
-
-function disable() {
-  exports.enable('');
-}
-
-/**
- * Returns true if the given mode name is enabled, false otherwise.
- *
- * @param {String} name
- * @return {Boolean}
- * @api public
- */
-
-function enabled(name) {
-  var i, len;
-  for (i = 0, len = exports.skips.length; i < len; i++) {
-    if (exports.skips[i].test(name)) {
-      return false;
-    }
-  }
-  for (i = 0, len = exports.names.length; i < len; i++) {
-    if (exports.names[i].test(name)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-/**
- * Coerce `val`.
- *
- * @param {Mixed} val
- * @return {Mixed}
- * @api private
- */
-
-function coerce(val) {
-  if (val instanceof Error) return val.stack || val.message;
-  return val;
-}
diff --git a/d2d_app/node_modules/express/node_modules/debug/src/index.js b/d2d_app/node_modules/express/node_modules/debug/src/index.js
deleted file mode 100644 (file)
index e12cf4d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Detect Electron renderer process, which is node, but we should
- * treat as a browser.
- */
-
-if (typeof process !== 'undefined' && process.type === 'renderer') {
-  module.exports = require('./browser.js');
-} else {
-  module.exports = require('./node.js');
-}
diff --git a/d2d_app/node_modules/express/node_modules/debug/src/inspector-log.js b/d2d_app/node_modules/express/node_modules/debug/src/inspector-log.js
deleted file mode 100644 (file)
index 60ea6c0..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-module.exports = inspectorLog;
-
-// black hole
-const nullStream = new (require('stream').Writable)();
-nullStream._write = () => {};
-
-/**
- * Outputs a `console.log()` to the Node.js Inspector console *only*.
- */
-function inspectorLog() {
-  const stdout = console._stdout;
-  console._stdout = nullStream;
-  console.log.apply(console, arguments);
-  console._stdout = stdout;
-}
diff --git a/d2d_app/node_modules/express/node_modules/debug/src/node.js b/d2d_app/node_modules/express/node_modules/debug/src/node.js
deleted file mode 100644 (file)
index b15109c..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var tty = require('tty');
-var util = require('util');
-
-/**
- * This is the Node.js implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.init = init;
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-
-/**
- * Colors.
- */
-
-exports.colors = [6, 2, 3, 4, 5, 1];
-
-/**
- * Build up the default `inspectOpts` object from the environment variables.
- *
- *   $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
- */
-
-exports.inspectOpts = Object.keys(process.env).filter(function (key) {
-  return /^debug_/i.test(key);
-}).reduce(function (obj, key) {
-  // camel-case
-  var prop = key
-    .substring(6)
-    .toLowerCase()
-    .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() });
-
-  // coerce string value into JS value
-  var val = process.env[key];
-  if (/^(yes|on|true|enabled)$/i.test(val)) val = true;
-  else if (/^(no|off|false|disabled)$/i.test(val)) val = false;
-  else if (val === 'null') val = null;
-  else val = Number(val);
-
-  obj[prop] = val;
-  return obj;
-}, {});
-
-/**
- * The file descriptor to write the `debug()` calls to.
- * Set the `DEBUG_FD` env variable to override with another value. i.e.:
- *
- *   $ DEBUG_FD=3 node script.js 3>debug.log
- */
-
-var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
-
-if (1 !== fd && 2 !== fd) {
-  util.deprecate(function(){}, 'except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)')()
-}
-
-var stream = 1 === fd ? process.stdout :
-             2 === fd ? process.stderr :
-             createWritableStdioStream(fd);
-
-/**
- * Is stdout a TTY? Colored output is enabled when `true`.
- */
-
-function useColors() {
-  return 'colors' in exports.inspectOpts
-    ? Boolean(exports.inspectOpts.colors)
-    : tty.isatty(fd);
-}
-
-/**
- * Map %o to `util.inspect()`, all on a single line.
- */
-
-exports.formatters.o = function(v) {
-  this.inspectOpts.colors = this.useColors;
-  return util.inspect(v, this.inspectOpts)
-    .split('\n').map(function(str) {
-      return str.trim()
-    }).join(' ');
-};
-
-/**
- * Map %o to `util.inspect()`, allowing multiple lines if needed.
- */
-
-exports.formatters.O = function(v) {
-  this.inspectOpts.colors = this.useColors;
-  return util.inspect(v, this.inspectOpts);
-};
-
-/**
- * Adds ANSI color escape codes if enabled.
- *
- * @api public
- */
-
-function formatArgs(args) {
-  var name = this.namespace;
-  var useColors = this.useColors;
-
-  if (useColors) {
-    var c = this.color;
-    var prefix = '  \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m';
-
-    args[0] = prefix + args[0].split('\n').join('\n' + prefix);
-    args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
-  } else {
-    args[0] = new Date().toUTCString()
-      + ' ' + name + ' ' + args[0];
-  }
-}
-
-/**
- * Invokes `util.format()` with the specified arguments and writes to `stream`.
- */
-
-function log() {
-  return stream.write(util.format.apply(util, arguments) + '\n');
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
-  if (null == namespaces) {
-    // If you set a process.env field to null or undefined, it gets cast to the
-    // string 'null' or 'undefined'. Just delete instead.
-    delete process.env.DEBUG;
-  } else {
-    process.env.DEBUG = namespaces;
-  }
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
-  return process.env.DEBUG;
-}
-
-/**
- * Copied from `node/src/node.js`.
- *
- * XXX: It's lame that node doesn't expose this API out-of-the-box. It also
- * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
- */
-
-function createWritableStdioStream (fd) {
-  var stream;
-  var tty_wrap = process.binding('tty_wrap');
-
-  // Note stream._type is used for test-module-load-list.js
-
-  switch (tty_wrap.guessHandleType(fd)) {
-    case 'TTY':
-      stream = new tty.WriteStream(fd);
-      stream._type = 'tty';
-
-      // Hack to have stream not keep the event loop alive.
-      // See https://github.com/joyent/node/issues/1726
-      if (stream._handle && stream._handle.unref) {
-        stream._handle.unref();
-      }
-      break;
-
-    case 'FILE':
-      var fs = require('fs');
-      stream = new fs.SyncWriteStream(fd, { autoClose: false });
-      stream._type = 'fs';
-      break;
-
-    case 'PIPE':
-    case 'TCP':
-      var net = require('net');
-      stream = new net.Socket({
-        fd: fd,
-        readable: false,
-        writable: true
-      });
-
-      // FIXME Should probably have an option in net.Socket to create a
-      // stream from an existing fd which is writable only. But for now
-      // we'll just add this hack and set the `readable` member to false.
-      // Test: ./node test/fixtures/echo.js < /etc/passwd
-      stream.readable = false;
-      stream.read = null;
-      stream._type = 'pipe';
-
-      // FIXME Hack to have stream not keep the event loop alive.
-      // See https://github.com/joyent/node/issues/1726
-      if (stream._handle && stream._handle.unref) {
-        stream._handle.unref();
-      }
-      break;
-
-    default:
-      // Probably an error on in uv_guess_handle()
-      throw new Error('Implement me. Unknown stream file type!');
-  }
-
-  // For supporting legacy API we put the FD here.
-  stream.fd = fd;
-
-  stream._isStdio = true;
-
-  return stream;
-}
-
-/**
- * Init logic for `debug` instances.
- *
- * Create a new `inspectOpts` object in case `useColors` is set
- * differently for a particular `debug` instance.
- */
-
-function init (debug) {
-  debug.inspectOpts = {};
-
-  var keys = Object.keys(exports.inspectOpts);
-  for (var i = 0; i < keys.length; i++) {
-    debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
-  }
-}
-
-/**
- * Enable namespaces listed in `process.env.DEBUG` initially.
- */
-
-exports.enable(load());
diff --git a/d2d_app/node_modules/express/node_modules/depd/lib/compat/callsite-tostring.js b/d2d_app/node_modules/express/node_modules/depd/lib/compat/callsite-tostring.js
deleted file mode 100644 (file)
index 73186dc..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*!
- * depd
- * Copyright(c) 2014 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-'use strict'
-
-/**
- * Module exports.
- */
-
-module.exports = callSiteToString
-
-/**
- * Format a CallSite file location to a string.
- */
-
-function callSiteFileLocation (callSite) {
-  var fileName
-  var fileLocation = ''
-
-  if (callSite.isNative()) {
-    fileLocation = 'native'
-  } else if (callSite.isEval()) {
-    fileName = callSite.getScriptNameOrSourceURL()
-    if (!fileName) {
-      fileLocation = callSite.getEvalOrigin()
-    }
-  } else {
-    fileName = callSite.getFileName()
-  }
-
-  if (fileName) {
-    fileLocation += fileName
-
-    var lineNumber = callSite.getLineNumber()
-    if (lineNumber != null) {
-      fileLocation += ':' + lineNumber
-
-      var columnNumber = callSite.getColumnNumber()
-      if (columnNumber) {
-        fileLocation += ':' + columnNumber
-      }
-    }
-  }
-
-  return fileLocation || 'unknown source'
-}
-
-/**
- * Format a CallSite to a string.
- */
-
-function callSiteToString (callSite) {
-  var addSuffix = true
-  var fileLocation = callSiteFileLocation(callSite)
-  var functionName = callSite.getFunctionName()
-  var isConstructor = callSite.isConstructor()
-  var isMethodCall = !(callSite.isToplevel() || isConstructor)
-  var line = ''
-
-  if (isMethodCall) {
-    var methodName = callSite.getMethodName()
-    var typeName = getConstructorName(callSite)
-
-    if (functionName) {
-      if (typeName && functionName.indexOf(typeName) !== 0) {
-        line += typeName + '.'
-      }
-
-      line += functionName
-
-      if (methodName && functionName.lastIndexOf('.' + methodName) !== functionName.length - methodName.length - 1) {
-        line += ' [as ' + methodName + ']'
-      }
-    } else {
-      line += typeName + '.' + (methodName || '<anonymous>')
-    }
-  } else if (isConstructor) {
-    line += 'new ' + (functionName || '<anonymous>')
-  } else if (functionName) {
-    line += functionName
-  } else {
-    addSuffix = false
-    line += fileLocation
-  }
-
-  if (addSuffix) {
-    line += ' (' + fileLocation + ')'
-  }
-
-  return line
-}
-
-/**
- * Get constructor name of reviver.
- */
-
-function getConstructorName (obj) {
-  var receiver = obj.receiver
-  return (receiver.constructor && receiver.constructor.name) || null
-}
diff --git a/d2d_app/node_modules/express/node_modules/depd/lib/compat/event-listener-count.js b/d2d_app/node_modules/express/node_modules/depd/lib/compat/event-listener-count.js
deleted file mode 100644 (file)
index 3a8925d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/*!
- * depd
- * Copyright(c) 2015 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-'use strict'
-
-/**
- * Module exports.
- * @public
- */
-
-module.exports = eventListenerCount
-
-/**
- * Get the count of listeners on an event emitter of a specific type.
- */
-
-function eventListenerCount (emitter, type) {
-  return emitter.listeners(type).length
-}
diff --git a/d2d_app/node_modules/express/node_modules/depd/lib/compat/index.js b/d2d_app/node_modules/express/node_modules/depd/lib/compat/index.js
deleted file mode 100644 (file)
index 955b333..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*!
- * depd
- * Copyright(c) 2014-2015 Douglas Christopher Wilson
- * MIT Licensed
- */
-
-'use strict'
-
-/**
- * Module dependencies.
- * @private
- */
-
-var EventEmitter = require('events').EventEmitter
-
-/**
- * Module exports.
- * @public
- */
-
-lazyProperty(module.exports, 'callSiteToString', function callSiteToString () {
-  var limit = Error.stackTraceLimit
-  var obj = {}
-  var prep = Error.prepareStackTrace
-
-  function prepareObjectStackTrace (obj, stack) {
-    return stack
-  }
-
-  Error.prepareStackTrace = prepareObjectStackTrace
-  Error.stackTraceLimit = 2
-
-  // capture the stack
-  Error.captureStackTrace(obj)
-
-  // slice the stack
-  var stack = obj.stack.slice()
-
-  Error.prepareStackTrace = prep
-  Error.stackTraceLimit = limit
-
-  return stack[0].toString ? toString : require('./callsite-tostring')
-})
-
-lazyProperty(module.exports, 'eventListenerCount', function eventListenerCount () {
-  return EventEmitter.listenerCount || require('./event-listener-count')
-})
-
-/**
- * Define a lazy property.
- */
-
-function lazyProperty (obj, prop, getter) {
-  function get () {
-    var val = getter()
-
-    Object.defineProperty(obj, prop, {
-      configurable: true,
-      enumerable: true,
-      value: val
-    })
-
-    return val
-  }
-
-  Object.defineProperty(obj, prop, {
-    configurable: true,
-    enumerable: true,
-    get: get
-  })
-}
-
-/**
- * Call toString() on the obj
- */
-
-function toString (obj) {
-  return obj.toString()
-}
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.coveralls.yml b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.coveralls.yml
deleted file mode 100644 (file)
index 20a7068..0000000
+++ /dev/null
@@ -1 +0,0 @@
-repo_token: SIAeZjKYlHK74rbcFvNHMUzjRiMpflxve
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.eslintrc b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.eslintrc
deleted file mode 100644 (file)
index 8a37ae2..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "env": {
-    "browser": true,
-    "node": true
-  },
-  "rules": {
-    "no-console": 0,
-    "no-empty": [1, { "allowEmptyCatch": true }]
-  },
-  "extends": "eslint:recommended"
-}
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.npmignore b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.npmignore
deleted file mode 100644 (file)
index 5f60eec..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-support
-test
-examples
-example
-*.sock
-dist
-yarn.lock
-coverage
-bower.json
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.travis.yml b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/.travis.yml
deleted file mode 100644 (file)
index 6c6090c..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-
-language: node_js
-node_js:
-  - "6"
-  - "5"
-  - "4"
-
-install:
-  - make node_modules
-
-script:
-  - make lint
-  - make test
-  - make coveralls
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/CHANGELOG.md b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/CHANGELOG.md
deleted file mode 100644 (file)
index eadaa18..0000000
+++ /dev/null
@@ -1,362 +0,0 @@
-
-2.6.9 / 2017-09-22
-==================
-
-  * remove ReDoS regexp in %o formatter (#504)
-
-2.6.8 / 2017-05-18
-==================
-
-  * Fix: Check for undefined on browser globals (#462, @marbemac)
-
-2.6.7 / 2017-05-16
-==================
-
-  * Fix: Update ms to 2.0.0 to fix regular expression denial of service vulnerability (#458, @hubdotcom)
-  * Fix: Inline extend function in node implementation (#452, @dougwilson)
-  * Docs: Fix typo (#455, @msasad)
-
-2.6.5 / 2017-04-27
-==================
-  
-  * Fix: null reference check on window.documentElement.style.WebkitAppearance (#447, @thebigredgeek)
-  * Misc: clean up browser reference checks (#447, @thebigredgeek)
-  * Misc: add npm-debug.log to .gitignore (@thebigredgeek)
-
-
-2.6.4 / 2017-04-20
-==================
-
-  * Fix: bug that would occure if process.env.DEBUG is a non-string value. (#444, @LucianBuzzo)
-  * Chore: ignore bower.json in npm installations. (#437, @joaovieira)
-  * Misc: update "ms" to v0.7.3 (@tootallnate)
-
-2.6.3 / 2017-03-13
-==================
-
-  * Fix: Electron reference to `process.env.DEBUG` (#431, @paulcbetts)
-  * Docs: Changelog fix (@thebigredgeek)
-
-2.6.2 / 2017-03-10
-==================
-
-  * Fix: DEBUG_MAX_ARRAY_LENGTH (#420, @slavaGanzin)
-  * Docs: Add backers and sponsors from Open Collective (#422, @piamancini)
-  * Docs: Add Slackin invite badge (@tootallnate)
-
-2.6.1 / 2017-02-10
-==================
-
-  * Fix: Module's `export default` syntax fix for IE8 `Expected identifier` error
-  * Fix: Whitelist DEBUG_FD for values 1 and 2 only (#415, @pi0)
-  * Fix: IE8 "Expected identifier" error (#414, @vgoma)
-  * Fix: Namespaces would not disable once enabled (#409, @musikov)
-
-2.6.0 / 2016-12-28
-==================
-
-  * Fix: added better null pointer checks for browser useColors (@thebigredgeek)
-  * Improvement: removed explicit `window.debug` export (#404, @tootallnate)
-  * Improvement: deprecated `DEBUG_FD` environment variable (#405, @tootallnate)
-
-2.5.2 / 2016-12-25
-==================
-
-  * Fix: reference error on window within webworkers (#393, @KlausTrainer)
-  * Docs: fixed README typo (#391, @lurch)
-  * Docs: added notice about v3 api discussion (@thebigredgeek)
-
-2.5.1 / 2016-12-20
-==================
-
-  * Fix: babel-core compatibility
-
-2.5.0 / 2016-12-20
-==================
-
-  * Fix: wrong reference in bower file (@thebigredgeek)
-  * Fix: webworker compatibility (@thebigredgeek)
-  * Fix: output formatting issue (#388, @kribblo)
-  * Fix: babel-loader compatibility (#383, @escwald)
-  * Misc: removed built asset from repo and publications (@thebigredgeek)
-  * Misc: moved source files to /src (#378, @yamikuronue)
-  * Test: added karma integration and replaced babel with browserify for browser tests (#378, @yamikuronue)
-  * Test: coveralls integration (#378, @yamikuronue)
-  * Docs: simplified language in the opening paragraph (#373, @yamikuronue)
-
-2.4.5 / 2016-12-17
-==================
-
-  * Fix: `navigator` undefined in Rhino (#376, @jochenberger)
-  * Fix: custom log function (#379, @hsiliev)
-  * Improvement: bit of cleanup + linting fixes (@thebigredgeek)
-  * Improvement: rm non-maintainted `dist/` dir (#375, @freewil)
-  * Docs: simplified language in the opening paragraph. (#373, @yamikuronue)
-
-2.4.4 / 2016-12-14
-==================
-
-  * Fix: work around debug being loaded in preload scripts for electron (#368, @paulcbetts)
-
-2.4.3 / 2016-12-14
-==================
-
-  * Fix: navigation.userAgent error for react native (#364, @escwald)
-
-2.4.2 / 2016-12-14
-==================
-
-  * Fix: browser colors (#367, @tootallnate)
-  * Misc: travis ci integration (@thebigredgeek)
-  * Misc: added linting and testing boilerplate with sanity check (@thebigredgeek)
-
-2.4.1 / 2016-12-13
-==================
-
-  * Fix: typo that broke the package (#356)
-
-2.4.0 / 2016-12-13
-==================
-
-  * Fix: bower.json references unbuilt src entry point (#342, @justmatt)
-  * Fix: revert "handle regex special characters" (@tootallnate)
-  * Feature: configurable util.inspect()`options for NodeJS (#327, @tootallnate)
-  * Feature: %O`(big O) pretty-prints objects (#322, @tootallnate)
-  * Improvement: allow colors in workers (#335, @botverse)
-  * Improvement: use same color for same namespace. (#338, @lchenay)
-
-2.3.3 / 2016-11-09
-==================
-
-  * Fix: Catch `JSON.stringify()` errors (#195, Jovan Alleyne)
-  * Fix: Returning `localStorage` saved values (#331, Levi Thomason)
-  * Improvement: Don't create an empty object when no `process` (Nathan Rajlich)
-
-2.3.2 / 2016-11-09
-==================
-
-  * Fix: be super-safe in index.js as well (@TooTallNate)
-  * Fix: should check whether process exists (Tom Newby)
-
-2.3.1 / 2016-11-09
-==================
-
-  * Fix: Added electron compatibility (#324, @paulcbetts)
-  * Improvement: Added performance optimizations (@tootallnate)
-  * Readme: Corrected PowerShell environment variable example (#252, @gimre)
-  * Misc: Removed yarn lock file from source control (#321, @fengmk2)
-
-2.3.0 / 2016-11-07
-==================
-
-  * Fix: Consistent placement of ms diff at end of output (#215, @gorangajic)
-  * Fix: Escaping of regex special characters in namespace strings (#250, @zacronos)
-  * Fix: Fixed bug causing crash on react-native (#282, @vkarpov15)
-  * Feature: Enabled ES6+ compatible import via default export (#212 @bucaran)
-  * Feature: Added %O formatter to reflect Chrome's console.log capability (#279, @oncletom)
-  * Package: Update "ms" to 0.7.2 (#315, @DevSide)
-  * Package: removed superfluous version property from bower.json (#207 @kkirsche)
-  * Readme: fix USE_COLORS to DEBUG_COLORS
-  * Readme: Doc fixes for format string sugar (#269, @mlucool)
-  * Readme: Updated docs for DEBUG_FD and DEBUG_COLORS environment variables (#232, @mattlyons0)
-  * Readme: doc fixes for PowerShell (#271 #243, @exoticknight @unreadable)
-  * Readme: better docs for browser support (#224, @matthewmueller)
-  * Tooling: Added yarn integration for development (#317, @thebigredgeek)
-  * Misc: Renamed History.md to CHANGELOG.md (@thebigredgeek)
-  * Misc: Added license file (#226 #274, @CantemoInternal @sdaitzman)
-  * Misc: Updated contributors (@thebigredgeek)
-
-2.2.0 / 2015-05-09
-==================
-
-  * package: update "ms" to v0.7.1 (#202, @dougwilson)
-  * README: add logging to file example (#193, @DanielOchoa)
-  * README: fixed a typo (#191, @amir-s)
-  * browser: expose `storage` (#190, @stephenmathieson)
-  * Makefile: add a `distclean` target (#189, @stephenmathieson)
-
-2.1.3 / 2015-03-13
-==================
-
-  * Updated stdout/stderr example (#186)
-  * Updated example/stdout.js to match debug current behaviour
-  * Renamed example/stderr.js to stdout.js
-  * Update Readme.md (#184)
-  * replace high intensity foreground color for bold (#182, #183)
-
-2.1.2 / 2015-03-01
-==================
-
-  * dist: recompile
-  * update "ms" to v0.7.0
-  * package: update "browserify" to v9.0.3
-  * component: fix "ms.js" repo location
-  * changed bower package name
-  * updated documentation about using debug in a browser
-  * fix: security error on safari (#167, #168, @yields)
-
-2.1.1 / 2014-12-29
-==================
-
-  * browser: use `typeof` to check for `console` existence
-  * browser: check for `console.log` truthiness (fix IE 8/9)
-  * browser: add support for Chrome apps
-  * Readme: added Windows usage remarks
-  * Add `bower.json` to properly support bower install
-
-2.1.0 / 2014-10-15
-==================
-
-  * node: implement `DEBUG_FD` env variable support
-  * package: update "browserify" to v6.1.0
-  * package: add "license" field to package.json (#135, @panuhorsmalahti)
-
-2.0.0 / 2014-09-01
-==================
-
-  * package: update "browserify" to v5.11.0
-  * node: use stderr rather than stdout for logging (#29, @stephenmathieson)
-
-1.0.4 / 2014-07-15
-==================
-
-  * dist: recompile
-  * example: remove `console.info()` log usage
-  * example: add "Content-Type" UTF-8 header to browser example
-  * browser: place %c marker after the space character
-  * browser: reset the "content" color via `color: inherit`
-  * browser: add colors support for Firefox >= v31
-  * debug: prefer an instance `log()` function over the global one (#119)
-  * Readme: update documentation about styled console logs for FF v31 (#116, @wryk)
-
-1.0.3 / 2014-07-09
-==================
-
-  * Add support for multiple wildcards in namespaces (#122, @seegno)
-  * browser: fix lint
-
-1.0.2 / 2014-06-10
-==================
-
-  * browser: update color palette (#113, @gscottolson)
-  * common: make console logging function configurable (#108, @timoxley)
-  * node: fix %o colors on old node <= 0.8.x
-  * Makefile: find node path using shell/which (#109, @timoxley)
-
-1.0.1 / 2014-06-06
-==================
-
-  * browser: use `removeItem()` to clear localStorage
-  * browser, node: don't set DEBUG if namespaces is undefined (#107, @leedm777)
-  * package: add "contributors" section
-  * node: fix comment typo
-  * README: list authors
-
-1.0.0 / 2014-06-04
-==================
-
-  * make ms diff be global, not be scope
-  * debug: ignore empty strings in enable()
-  * node: make DEBUG_COLORS able to disable coloring
-  * *: export the `colors` array
-  * npmignore: don't publish the `dist` dir
-  * Makefile: refactor to use browserify
-  * package: add "browserify" as a dev dependency
-  * Readme: add Web Inspector Colors section
-  * node: reset terminal color for the debug content
-  * node: map "%o" to `util.inspect()`
-  * browser: map "%j" to `JSON.stringify()`
-  * debug: add custom "formatters"
-  * debug: use "ms" module for humanizing the diff
-  * Readme: add "bash" syntax highlighting
-  * browser: add Firebug color support
-  * browser: add colors for WebKit browsers
-  * node: apply log to `console`
-  * rewrite: abstract common logic for Node & browsers
-  * add .jshintrc file
-
-0.8.1 / 2014-04-14
-==================
-
-  * package: re-add the "component" section
-
-0.8.0 / 2014-03-30
-==================
-
-  * add `enable()` method for nodejs. Closes #27
-  * change from stderr to stdout
-  * remove unnecessary index.js file
-
-0.7.4 / 2013-11-13
-==================
-
-  * remove "browserify" key from package.json (fixes something in browserify)
-
-0.7.3 / 2013-10-30
-==================
-
-  * fix: catch localStorage security error when cookies are blocked (Chrome)
-  * add debug(err) support. Closes #46
-  * add .browser prop to package.json. Closes #42
-
-0.7.2 / 2013-02-06
-==================
-
-  * fix package.json
-  * fix: Mobile Safari (private mode) is broken with debug
-  * fix: Use unicode to send escape character to shell instead of octal to work with strict mode javascript
-
-0.7.1 / 2013-02-05
-==================
-
-  * add repository URL to package.json
-  * add DEBUG_COLORED to force colored output
-  * add browserify support
-  * fix component. Closes #24
-
-0.7.0 / 2012-05-04
-==================
-
-  * Added .component to package.json
-  * Added debug.component.js build
-
-0.6.0 / 2012-03-16
-==================
-
-  * Added support for "-" prefix in DEBUG [Vinay Pulim]
-  * Added `.enabled` flag to the node version [TooTallNate]
-
-0.5.0 / 2012-02-02
-==================
-
-  * Added: humanize diffs. Closes #8
-  * Added `debug.disable()` to the CS variant
-  * Removed padding. Closes #10
-  * Fixed: persist client-side variant again. Closes #9
-
-0.4.0 / 2012-02-01
-==================
-
-  * Added browser variant support for older browsers [TooTallNate]
-  * Added `debug.enable('project:*')` to browser variant [TooTallNate]
-  * Added padding to diff (moved it to the right)
-
-0.3.0 / 2012-01-26
-==================
-
-  * Added millisecond diff when isatty, otherwise UTC string
-
-0.2.0 / 2012-01-22
-==================
-
-  * Added wildcard support
-
-0.1.0 / 2011-12-02
-==================
-
-  * Added: remove colors unless stderr isatty [TooTallNate]
-
-0.0.1 / 2010-01-03
-==================
-
-  * Initial release
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/LICENSE b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/LICENSE
deleted file mode 100644 (file)
index 658c933..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-(The MIT License)
-
-Copyright (c) 2014 TJ Holowaychuk <tj@vision-media.ca>
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
-and associated documentation files (the 'Software'), to deal in the Software without restriction, 
-including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, 
-and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial 
-portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT 
-LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/Makefile b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/Makefile
deleted file mode 100644 (file)
index 584da8b..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# get Makefile directory name: http://stackoverflow.com/a/5982798/376773
-THIS_MAKEFILE_PATH:=$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
-THIS_DIR:=$(shell cd $(dir $(THIS_MAKEFILE_PATH));pwd)
-
-# BIN directory
-BIN := $(THIS_DIR)/node_modules/.bin
-
-# Path
-PATH := node_modules/.bin:$(PATH)
-SHELL := /bin/bash
-
-# applications
-NODE ?= $(shell which node)
-YARN ?= $(shell which yarn)
-PKG ?= $(if $(YARN),$(YARN),$(NODE) $(shell which npm))
-BROWSERIFY ?= $(NODE) $(BIN)/browserify
-
-.FORCE:
-
-install: node_modules
-
-node_modules: package.json
-       @NODE_ENV= $(PKG) install
-       @touch node_modules
-
-lint: .FORCE
-       eslint browser.js debug.js index.js node.js
-
-test-node: .FORCE
-       istanbul cover node_modules/mocha/bin/_mocha -- test/**.js
-
-test-browser: .FORCE
-       mkdir -p dist
-
-       @$(BROWSERIFY) \
-               --standalone debug \
-               . > dist/debug.js
-
-       karma start --single-run
-       rimraf dist
-
-test: .FORCE
-       concurrently \
-               "make test-node" \
-               "make test-browser"
-
-coveralls:
-       cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
-
-.PHONY: all install clean distclean
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/README.md b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/README.md
deleted file mode 100644 (file)
index f67be6b..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-# debug
-[![Build Status](https://travis-ci.org/visionmedia/debug.svg?branch=master)](https://travis-ci.org/visionmedia/debug)  [![Coverage Status](https://coveralls.io/repos/github/visionmedia/debug/badge.svg?branch=master)](https://coveralls.io/github/visionmedia/debug?branch=master)  [![Slack](https://visionmedia-community-slackin.now.sh/badge.svg)](https://visionmedia-community-slackin.now.sh/) [![OpenCollective](https://opencollective.com/debug/backers/badge.svg)](#backers) 
-[![OpenCollective](https://opencollective.com/debug/sponsors/badge.svg)](#sponsors)
-
-
-
-A tiny node.js debugging utility modelled after node core's debugging technique.
-
-**Discussion around the V3 API is under way [here](https://github.com/visionmedia/debug/issues/370)**
-
-## Installation
-
-```bash
-$ npm install debug
-```
-
-## Usage
-
-`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
-
-Example _app.js_:
-
-```js
-var debug = require('debug')('http')
-  , http = require('http')
-  , name = 'My App';
-
-// fake app
-
-debug('booting %s', name);
-
-http.createServer(function(req, res){
-  debug(req.method + ' ' + req.url);
-  res.end('hello\n');
-}).listen(3000, function(){
-  debug('listening');
-});
-
-// fake worker of some kind
-
-require('./worker');
-```
-
-Example _worker.js_:
-
-```js
-var debug = require('debug')('worker');
-
-setInterval(function(){
-  debug('doing some work');
-}, 1000);
-```
-
- The __DEBUG__ environment variable is then used to enable these based on space or comma-delimited names. Here are some examples:
-
-  ![debug http and worker](http://f.cl.ly/items/18471z1H402O24072r1J/Screenshot.png)
-
-  ![debug worker](http://f.cl.ly/items/1X413v1a3M0d3C2c1E0i/Screenshot.png)
-
-#### Windows note
-
- On Windows the environment variable is set using the `set` command.
-
- ```cmd
- set DEBUG=*,-not_this
- ```
-
- Note that PowerShell uses different syntax to set environment variables.
-
- ```cmd
- $env:DEBUG = "*,-not_this"
-  ```
-
-Then, run the program to be debugged as usual.
-
-## Millisecond diff
-
-  When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
-
-  ![](http://f.cl.ly/items/2i3h1d3t121M2Z1A3Q0N/Screenshot.png)
-
-  When stdout is not a TTY, `Date#toUTCString()` is used, making it more useful for logging the debug information as shown below:
-
-  ![](http://f.cl.ly/items/112H3i0e0o0P0a2Q2r11/Screenshot.png)
-
-## Conventions
-
-  If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser".
-
-## Wildcards
-
-  The `*` character may be used as a wildcard. Suppose for example your library has debuggers named "connect:bodyParser", "connect:compress", "connect:session", instead of listing all three with `DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do `DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
-
-  You can also exclude specific debuggers by prefixing them with a "-" character.  For example, `DEBUG=*,-connect:*` would include all debuggers except those starting with "connect:".
-
-## Environment Variables
-
-  When running through Node.js, you can set a few environment variables that will
-  change the behavior of the debug logging:
-
-| Name      | Purpose                                         |
-|-----------|-------------------------------------------------|
-| `DEBUG`   | Enables/disables specific debugging namespaces. |
-| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
-| `DEBUG_DEPTH` | Object inspection depth. |
-| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
-
-
-  __Note:__ The environment variables beginning with `DEBUG_` end up being
-  converted into an Options object that gets used with `%o`/`%O` formatters.
-  See the Node.js documentation for
-  [`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
-  for the complete list.
-
-## Formatters
-
-
-  Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting. Below are the officially supported formatters:
-
-| Formatter | Representation |
-|-----------|----------------|
-| `%O`      | Pretty-print an Object on multiple lines. |
-| `%o`      | Pretty-print an Object all on a single line. |
-| `%s`      | String. |
-| `%d`      | Number (both integer and float). |
-| `%j`      | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
-| `%%`      | Single percent sign ('%'). This does not consume an argument. |
-
-### Custom formatters
-
-  You can add custom formatters by extending the `debug.formatters` object. For example, if you wanted to add support for rendering a Buffer as hex with `%h`, you could do something like:
-
-```js
-const createDebug = require('debug')
-createDebug.formatters.h = (v) => {
-  return v.toString('hex')
-}
-
-// …elsewhere
-const debug = createDebug('foo')
-debug('this is hex: %h', new Buffer('hello world'))
-//   foo this is hex: 68656c6c6f20776f726c6421 +0ms
-```
-
-## Browser support
-  You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
-  or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
-  if you don't want to build it yourself.
-
-  Debug's enable state is currently persisted by `localStorage`.
-  Consider the situation shown below where you have `worker:a` and `worker:b`,
-  and wish to debug both. You can enable this using `localStorage.debug`:
-
-```js
-localStorage.debug = 'worker:*'
-```
-
-And then refresh the page.
-
-```js
-a = debug('worker:a');
-b = debug('worker:b');
-
-setInterval(function(){
-  a('doing some work');
-}, 1000);
-
-setInterval(function(){
-  b('doing some work');
-}, 1200);
-```
-
-#### Web Inspector Colors
-
-  Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
-  option. These are WebKit web inspectors, Firefox ([since version
-  31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
-  and the Firebug plugin for Firefox (any version).
-
-  Colored output looks something like:
-
-  ![](https://cloud.githubusercontent.com/assets/71256/3139768/b98c5fd8-e8ef-11e3-862a-f7253b6f47c6.png)
-
-
-## Output streams
-
-  By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
-
-Example _stdout.js_:
-
-```js
-var debug = require('debug');
-var error = debug('app:error');
-
-// by default stderr is used
-error('goes to stderr!');
-
-var log = debug('app:log');
-// set this namespace to log via console.log
-log.log = console.log.bind(console); // don't forget to bind to console!
-log('goes to stdout');
-error('still goes to stderr!');
-
-// set all output to go via console.info
-// overrides all per-namespace log settings
-debug.log = console.info.bind(console);
-error('now goes to stdout via console.info');
-log('still goes to stdout, but via console.info now');
-```
-
-
-## Authors
-
- - TJ Holowaychuk
- - Nathan Rajlich
- - Andrew Rhyne
-## Backers
-
-Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
-
-<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
-<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
-
-
-## Sponsors
-
-Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
-
-<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
-<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
-
-## License
-
-(The MIT License)
-
-Copyright (c) 2014-2016 TJ Holowaychuk &lt;tj@vision-media.ca&gt;
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-'Software'), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/component.json b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/component.json
deleted file mode 100644 (file)
index 9de2641..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "debug",
-  "repo": "visionmedia/debug",
-  "description": "small debugging utility",
-  "version": "2.6.9",
-  "keywords": [
-    "debug",
-    "log",
-    "debugger"
-  ],
-  "main": "src/browser.js",
-  "scripts": [
-    "src/browser.js",
-    "src/debug.js"
-  ],
-  "dependencies": {
-    "rauchg/ms.js": "0.7.1"
-  }
-}
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/karma.conf.js b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/karma.conf.js
deleted file mode 100644 (file)
index 103a82d..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-// Karma configuration
-// Generated on Fri Dec 16 2016 13:09:51 GMT+0000 (UTC)
-
-module.exports = function(config) {
-  config.set({
-
-    // base path that will be used to resolve all patterns (eg. files, exclude)
-    basePath: '',
-
-
-    // frameworks to use
-    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
-    frameworks: ['mocha', 'chai', 'sinon'],
-
-
-    // list of files / patterns to load in the browser
-    files: [
-      'dist/debug.js',
-      'test/*spec.js'
-    ],
-
-
-    // list of files to exclude
-    exclude: [
-      'src/node.js'
-    ],
-
-
-    // preprocess matching files before serving them to the browser
-    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
-    preprocessors: {
-    },
-
-    // test results reporter to use
-    // possible values: 'dots', 'progress'
-    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
-    reporters: ['progress'],
-
-
-    // web server port
-    port: 9876,
-
-
-    // enable / disable colors in the output (reporters and logs)
-    colors: true,
-
-
-    // level of logging
-    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
-    logLevel: config.LOG_INFO,
-
-
-    // enable / disable watching file and executing tests whenever any file changes
-    autoWatch: true,
-
-
-    // start these browsers
-    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
-    browsers: ['PhantomJS'],
-
-
-    // Continuous Integration mode
-    // if true, Karma captures browsers, runs the tests and exits
-    singleRun: false,
-
-    // Concurrency level
-    // how many browser should be started simultaneous
-    concurrency: Infinity
-  })
-}
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/node.js b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/node.js
deleted file mode 100644 (file)
index 7fc36fe..0000000
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = require('./src/node');
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/package.json b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/package.json
deleted file mode 100644 (file)
index 1f7e10a..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-{
-  "_from": "debug@2.6.9",
-  "_id": "debug@2.6.9",
-  "_inBundle": false,
-  "_integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-  "_location": "/finalhandler/debug",
-  "_phantomChildren": {},
-  "_requested": {
-    "type": "version",
-    "registry": true,
-    "raw": "debug@2.6.9",
-    "name": "debug",
-    "escapedName": "debug",
-    "rawSpec": "2.6.9",
-    "saveSpec": null,
-    "fetchSpec": "2.6.9"
-  },
-  "_requiredBy": [
-    "/finalhandler"
-  ],
-  "_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-  "_shasum": "5d128515df134ff327e90a4c93f4e077a536341f",
-  "_spec": "debug@2.6.9",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/finalhandler",
-  "author": {
-    "name": "TJ Holowaychuk",
-    "email": "tj@vision-media.ca"
-  },
-  "browser": "./src/browser.js",
-  "bugs": {
-    "url": "https://github.com/visionmedia/debug/issues"
-  },
-  "bundleDependencies": false,
-  "component": {
-    "scripts": {
-      "debug/index.js": "browser.js",
-      "debug/debug.js": "debug.js"
-    }
-  },
-  "contributors": [
-    {
-      "name": "Nathan Rajlich",
-      "email": "nathan@tootallnate.net",
-      "url": "http://n8.io"
-    },
-    {
-      "name": "Andrew Rhyne",
-      "email": "rhyneandrew@gmail.com"
-    }
-  ],
-  "dependencies": {
-    "ms": "2.0.0"
-  },
-  "deprecated": false,
-  "description": "small debugging utility",
-  "devDependencies": {
-    "browserify": "9.0.3",
-    "chai": "^3.5.0",
-    "concurrently": "^3.1.0",
-    "coveralls": "^2.11.15",
-    "eslint": "^3.12.1",
-    "istanbul": "^0.4.5",
-    "karma": "^1.3.0",
-    "karma-chai": "^0.1.0",
-    "karma-mocha": "^1.3.0",
-    "karma-phantomjs-launcher": "^1.0.2",
-    "karma-sinon": "^1.0.5",
-    "mocha": "^3.2.0",
-    "mocha-lcov-reporter": "^1.2.0",
-    "rimraf": "^2.5.4",
-    "sinon": "^1.17.6",
-    "sinon-chai": "^2.8.0"
-  },
-  "homepage": "https://github.com/visionmedia/debug#readme",
-  "keywords": [
-    "debug",
-    "log",
-    "debugger"
-  ],
-  "license": "MIT",
-  "main": "./src/index.js",
-  "name": "debug",
-  "repository": {
-    "type": "git",
-    "url": "git://github.com/visionmedia/debug.git"
-  },
-  "version": "2.6.9"
-}
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/browser.js b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/browser.js
deleted file mode 100644 (file)
index 7106924..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * This is the web browser implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-exports.storage = 'undefined' != typeof chrome
-               && 'undefined' != typeof chrome.storage
-                  ? chrome.storage.local
-                  : localstorage();
-
-/**
- * Colors.
- */
-
-exports.colors = [
-  'lightseagreen',
-  'forestgreen',
-  'goldenrod',
-  'dodgerblue',
-  'darkorchid',
-  'crimson'
-];
-
-/**
- * Currently only WebKit-based Web Inspectors, Firefox >= v31,
- * and the Firebug extension (any Firefox version) are known
- * to support "%c" CSS customizations.
- *
- * TODO: add a `localStorage` variable to explicitly enable/disable colors
- */
-
-function useColors() {
-  // NB: In an Electron preload script, document will be defined but not fully
-  // initialized. Since we know we're in Chrome, we'll just detect this case
-  // explicitly
-  if (typeof window !== 'undefined' && window.process && window.process.type === 'renderer') {
-    return true;
-  }
-
-  // is webkit? http://stackoverflow.com/a/16459606/376773
-  // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
-  return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
-    // is firebug? http://stackoverflow.com/a/398120/376773
-    (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
-    // is firefox >= v31?
-    // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
-    (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) ||
-    // double check webkit in userAgent just in case we are in a worker
-    (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
-}
-
-/**
- * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
- */
-
-exports.formatters.j = function(v) {
-  try {
-    return JSON.stringify(v);
-  } catch (err) {
-    return '[UnexpectedJSONParseError]: ' + err.message;
-  }
-};
-
-
-/**
- * Colorize log arguments if enabled.
- *
- * @api public
- */
-
-function formatArgs(args) {
-  var useColors = this.useColors;
-
-  args[0] = (useColors ? '%c' : '')
-    + this.namespace
-    + (useColors ? ' %c' : ' ')
-    + args[0]
-    + (useColors ? '%c ' : ' ')
-    + '+' + exports.humanize(this.diff);
-
-  if (!useColors) return;
-
-  var c = 'color: ' + this.color;
-  args.splice(1, 0, c, 'color: inherit')
-
-  // the final "%c" is somewhat tricky, because there could be other
-  // arguments passed either before or after the %c, so we need to
-  // figure out the correct index to insert the CSS into
-  var index = 0;
-  var lastC = 0;
-  args[0].replace(/%[a-zA-Z%]/g, function(match) {
-    if ('%%' === match) return;
-    index++;
-    if ('%c' === match) {
-      // we only are interested in the *last* %c
-      // (the user may have provided their own)
-      lastC = index;
-    }
-  });
-
-  args.splice(lastC, 0, c);
-}
-
-/**
- * Invokes `console.log()` when available.
- * No-op when `console.log` is not a "function".
- *
- * @api public
- */
-
-function log() {
-  // this hackery is required for IE8/9, where
-  // the `console.log` function doesn't have 'apply'
-  return 'object' === typeof console
-    && console.log
-    && Function.prototype.apply.call(console.log, console, arguments);
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
-  try {
-    if (null == namespaces) {
-      exports.storage.removeItem('debug');
-    } else {
-      exports.storage.debug = namespaces;
-    }
-  } catch(e) {}
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
-  var r;
-  try {
-    r = exports.storage.debug;
-  } catch(e) {}
-
-  // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
-  if (!r && typeof process !== 'undefined' && 'env' in process) {
-    r = process.env.DEBUG;
-  }
-
-  return r;
-}
-
-/**
- * Enable namespaces listed in `localStorage.debug` initially.
- */
-
-exports.enable(load());
-
-/**
- * Localstorage attempts to return the localstorage.
- *
- * This is necessary because safari throws
- * when a user disables cookies/localstorage
- * and you attempt to access it.
- *
- * @return {LocalStorage}
- * @api private
- */
-
-function localstorage() {
-  try {
-    return window.localStorage;
-  } catch (e) {}
-}
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/debug.js b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/debug.js
deleted file mode 100644 (file)
index 6a5e3fc..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-
-/**
- * This is the common logic for both the Node.js and web browser
- * implementations of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = createDebug.debug = createDebug['default'] = createDebug;
-exports.coerce = coerce;
-exports.disable = disable;
-exports.enable = enable;
-exports.enabled = enabled;
-exports.humanize = require('ms');
-
-/**
- * The currently active debug mode names, and names to skip.
- */
-
-exports.names = [];
-exports.skips = [];
-
-/**
- * Map of special "%n" handling functions, for the debug "format" argument.
- *
- * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
- */
-
-exports.formatters = {};
-
-/**
- * Previous log timestamp.
- */
-
-var prevTime;
-
-/**
- * Select a color.
- * @param {String} namespace
- * @return {Number}
- * @api private
- */
-
-function selectColor(namespace) {
-  var hash = 0, i;
-
-  for (i in namespace) {
-    hash  = ((hash << 5) - hash) + namespace.charCodeAt(i);
-    hash |= 0; // Convert to 32bit integer
-  }
-
-  return exports.colors[Math.abs(hash) % exports.colors.length];
-}
-
-/**
- * Create a debugger with the given `namespace`.
- *
- * @param {String} namespace
- * @return {Function}
- * @api public
- */
-
-function createDebug(namespace) {
-
-  function debug() {
-    // disabled?
-    if (!debug.enabled) return;
-
-    var self = debug;
-
-    // set `diff` timestamp
-    var curr = +new Date();
-    var ms = curr - (prevTime || curr);
-    self.diff = ms;
-    self.prev = prevTime;
-    self.curr = curr;
-    prevTime = curr;
-
-    // turn the `arguments` into a proper Array
-    var args = new Array(arguments.length);
-    for (var i = 0; i < args.length; i++) {
-      args[i] = arguments[i];
-    }
-
-    args[0] = exports.coerce(args[0]);
-
-    if ('string' !== typeof args[0]) {
-      // anything else let's inspect with %O
-      args.unshift('%O');
-    }
-
-    // apply any `formatters` transformations
-    var index = 0;
-    args[0] = args[0].replace(/%([a-zA-Z%])/g, function(match, format) {
-      // if we encounter an escaped % then don't increase the array index
-      if (match === '%%') return match;
-      index++;
-      var formatter = exports.formatters[format];
-      if ('function' === typeof formatter) {
-        var val = args[index];
-        match = formatter.call(self, val);
-
-        // now we need to remove `args[index]` since it's inlined in the `format`
-        args.splice(index, 1);
-        index--;
-      }
-      return match;
-    });
-
-    // apply env-specific formatting (colors, etc.)
-    exports.formatArgs.call(self, args);
-
-    var logFn = debug.log || exports.log || console.log.bind(console);
-    logFn.apply(self, args);
-  }
-
-  debug.namespace = namespace;
-  debug.enabled = exports.enabled(namespace);
-  debug.useColors = exports.useColors();
-  debug.color = selectColor(namespace);
-
-  // env-specific initialization logic for debug instances
-  if ('function' === typeof exports.init) {
-    exports.init(debug);
-  }
-
-  return debug;
-}
-
-/**
- * Enables a debug mode by namespaces. This can include modes
- * separated by a colon and wildcards.
- *
- * @param {String} namespaces
- * @api public
- */
-
-function enable(namespaces) {
-  exports.save(namespaces);
-
-  exports.names = [];
-  exports.skips = [];
-
-  var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
-  var len = split.length;
-
-  for (var i = 0; i < len; i++) {
-    if (!split[i]) continue; // ignore empty strings
-    namespaces = split[i].replace(/\*/g, '.*?');
-    if (namespaces[0] === '-') {
-      exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
-    } else {
-      exports.names.push(new RegExp('^' + namespaces + '$'));
-    }
-  }
-}
-
-/**
- * Disable debug output.
- *
- * @api public
- */
-
-function disable() {
-  exports.enable('');
-}
-
-/**
- * Returns true if the given mode name is enabled, false otherwise.
- *
- * @param {String} name
- * @return {Boolean}
- * @api public
- */
-
-function enabled(name) {
-  var i, len;
-  for (i = 0, len = exports.skips.length; i < len; i++) {
-    if (exports.skips[i].test(name)) {
-      return false;
-    }
-  }
-  for (i = 0, len = exports.names.length; i < len; i++) {
-    if (exports.names[i].test(name)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-/**
- * Coerce `val`.
- *
- * @param {Mixed} val
- * @return {Mixed}
- * @api private
- */
-
-function coerce(val) {
-  if (val instanceof Error) return val.stack || val.message;
-  return val;
-}
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/index.js b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/index.js
deleted file mode 100644 (file)
index e12cf4d..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/**
- * Detect Electron renderer process, which is node, but we should
- * treat as a browser.
- */
-
-if (typeof process !== 'undefined' && process.type === 'renderer') {
-  module.exports = require('./browser.js');
-} else {
-  module.exports = require('./node.js');
-}
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/inspector-log.js b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/inspector-log.js
deleted file mode 100644 (file)
index 60ea6c0..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-module.exports = inspectorLog;
-
-// black hole
-const nullStream = new (require('stream').Writable)();
-nullStream._write = () => {};
-
-/**
- * Outputs a `console.log()` to the Node.js Inspector console *only*.
- */
-function inspectorLog() {
-  const stdout = console._stdout;
-  console._stdout = nullStream;
-  console.log.apply(console, arguments);
-  console._stdout = stdout;
-}
diff --git a/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/node.js b/d2d_app/node_modules/express/node_modules/finalhandler/node_modules/debug/src/node.js
deleted file mode 100644 (file)
index b15109c..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/**
- * Module dependencies.
- */
-
-var tty = require('tty');
-var util = require('util');
-
-/**
- * This is the Node.js implementation of `debug()`.
- *
- * Expose `debug()` as the module.
- */
-
-exports = module.exports = require('./debug');
-exports.init = init;
-exports.log = log;
-exports.formatArgs = formatArgs;
-exports.save = save;
-exports.load = load;
-exports.useColors = useColors;
-
-/**
- * Colors.
- */
-
-exports.colors = [6, 2, 3, 4, 5, 1];
-
-/**
- * Build up the default `inspectOpts` object from the environment variables.
- *
- *   $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
- */
-
-exports.inspectOpts = Object.keys(process.env).filter(function (key) {
-  return /^debug_/i.test(key);
-}).reduce(function (obj, key) {
-  // camel-case
-  var prop = key
-    .substring(6)
-    .toLowerCase()
-    .replace(/_([a-z])/g, function (_, k) { return k.toUpperCase() });
-
-  // coerce string value into JS value
-  var val = process.env[key];
-  if (/^(yes|on|true|enabled)$/i.test(val)) val = true;
-  else if (/^(no|off|false|disabled)$/i.test(val)) val = false;
-  else if (val === 'null') val = null;
-  else val = Number(val);
-
-  obj[prop] = val;
-  return obj;
-}, {});
-
-/**
- * The file descriptor to write the `debug()` calls to.
- * Set the `DEBUG_FD` env variable to override with another value. i.e.:
- *
- *   $ DEBUG_FD=3 node script.js 3>debug.log
- */
-
-var fd = parseInt(process.env.DEBUG_FD, 10) || 2;
-
-if (1 !== fd && 2 !== fd) {
-  util.deprecate(function(){}, 'except for stderr(2) and stdout(1), any other usage of DEBUG_FD is deprecated. Override debug.log if you want to use a different log function (https://git.io/debug_fd)')()
-}
-
-var stream = 1 === fd ? process.stdout :
-             2 === fd ? process.stderr :
-             createWritableStdioStream(fd);
-
-/**
- * Is stdout a TTY? Colored output is enabled when `true`.
- */
-
-function useColors() {
-  return 'colors' in exports.inspectOpts
-    ? Boolean(exports.inspectOpts.colors)
-    : tty.isatty(fd);
-}
-
-/**
- * Map %o to `util.inspect()`, all on a single line.
- */
-
-exports.formatters.o = function(v) {
-  this.inspectOpts.colors = this.useColors;
-  return util.inspect(v, this.inspectOpts)
-    .split('\n').map(function(str) {
-      return str.trim()
-    }).join(' ');
-};
-
-/**
- * Map %o to `util.inspect()`, allowing multiple lines if needed.
- */
-
-exports.formatters.O = function(v) {
-  this.inspectOpts.colors = this.useColors;
-  return util.inspect(v, this.inspectOpts);
-};
-
-/**
- * Adds ANSI color escape codes if enabled.
- *
- * @api public
- */
-
-function formatArgs(args) {
-  var name = this.namespace;
-  var useColors = this.useColors;
-
-  if (useColors) {
-    var c = this.color;
-    var prefix = '  \u001b[3' + c + ';1m' + name + ' ' + '\u001b[0m';
-
-    args[0] = prefix + args[0].split('\n').join('\n' + prefix);
-    args.push('\u001b[3' + c + 'm+' + exports.humanize(this.diff) + '\u001b[0m');
-  } else {
-    args[0] = new Date().toUTCString()
-      + ' ' + name + ' ' + args[0];
-  }
-}
-
-/**
- * Invokes `util.format()` with the specified arguments and writes to `stream`.
- */
-
-function log() {
-  return stream.write(util.format.apply(util, arguments) + '\n');
-}
-
-/**
- * Save `namespaces`.
- *
- * @param {String} namespaces
- * @api private
- */
-
-function save(namespaces) {
-  if (null == namespaces) {
-    // If you set a process.env field to null or undefined, it gets cast to the
-    // string 'null' or 'undefined'. Just delete instead.
-    delete process.env.DEBUG;
-  } else {
-    process.env.DEBUG = namespaces;
-  }
-}
-
-/**
- * Load `namespaces`.
- *
- * @return {String} returns the previously persisted debug modes
- * @api private
- */
-
-function load() {
-  return process.env.DEBUG;
-}
-
-/**
- * Copied from `node/src/node.js`.
- *
- * XXX: It's lame that node doesn't expose this API out-of-the-box. It also
- * relies on the undocumented `tty_wrap.guessHandleType()` which is also lame.
- */
-
-function createWritableStdioStream (fd) {
-  var stream;
-  var tty_wrap = process.binding('tty_wrap');
-
-  // Note stream._type is used for test-module-load-list.js
-
-  switch (tty_wrap.guessHandleType(fd)) {
-    case 'TTY':
-      stream = new tty.WriteStream(fd);
-      stream._type = 'tty';
-
-      // Hack to have stream not keep the event loop alive.
-      // See https://github.com/joyent/node/issues/1726
-      if (stream._handle && stream._handle.unref) {
-        stream._handle.unref();
-      }
-      break;
-
-    case 'FILE':
-      var fs = require('fs');
-      stream = new fs.SyncWriteStream(fd, { autoClose: false });
-      stream._type = 'fs';
-      break;
-
-    case 'PIPE':
-    case 'TCP':
-      var net = require('net');
-      stream = new net.Socket({
-        fd: fd,
-        readable: false,
-        writable: true
-      });
-
-      // FIXME Should probably have an option in net.Socket to create a
-      // stream from an existing fd which is writable only. But for now
-      // we'll just add this hack and set the `readable` member to false.
-      // Test: ./node test/fixtures/echo.js < /etc/passwd
-      stream.readable = false;
-      stream.read = null;
-      stream._type = 'pipe';
-
-      // FIXME Hack to have stream not keep the event loop alive.
-      // See https://github.com/joyent/node/issues/1726
-      if (stream._handle && stream._handle.unref) {
-        stream._handle.unref();
-      }
-      break;
-
-    default:
-      // Probably an error on in uv_guess_handle()
-      throw new Error('Implement me. Unknown stream file type!');
-  }
-
-  // For supporting legacy API we put the FD here.
-  stream.fd = fd;
-
-  stream._isStdio = true;
-
-  return stream;
-}
-
-/**
- * Init logic for `debug` instances.
- *
- * Create a new `inspectOpts` object in case `useColors` is set
- * differently for a particular `debug` instance.
- */
-
-function init (debug) {
-  debug.inspectOpts = {};
-
-  var keys = Object.keys(exports.inspectOpts);
-  for (var i = 0; i < keys.length; i++) {
-    debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
-  }
-}
-
-/**
- * Enable namespaces listed in `process.env.DEBUG` initially.
- */
-
-exports.enable(load());
diff --git a/d2d_app/node_modules/express/node_modules/ms/index.js b/d2d_app/node_modules/express/node_modules/ms/index.js
deleted file mode 100644 (file)
index 6a522b1..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/**
- * Helpers.
- */
-
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-var y = d * 365.25;
-
-/**
- * Parse or format the given `val`.
- *
- * Options:
- *
- *  - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} [options]
- * @throws {Error} throw an error if val is not a non-empty string or a number
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function(val, options) {
-  options = options || {};
-  var type = typeof val;
-  if (type === 'string' && val.length > 0) {
-    return parse(val);
-  } else if (type === 'number' && isNaN(val) === false) {
-    return options.long ? fmtLong(val) : fmtShort(val);
-  }
-  throw new Error(
-    'val is not a non-empty string or a valid number. val=' +
-      JSON.stringify(val)
-  );
-};
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
-  str = String(str);
-  if (str.length > 100) {
-    return;
-  }
-  var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(
-    str
-  );
-  if (!match) {
-    return;
-  }
-  var n = parseFloat(match[1]);
-  var type = (match[2] || 'ms').toLowerCase();
-  switch (type) {
-    case 'years':
-    case 'year':
-    case 'yrs':
-    case 'yr':
-    case 'y':
-      return n * y;
-    case 'days':
-    case 'day':
-    case 'd':
-      return n * d;
-    case 'hours':
-    case 'hour':
-    case 'hrs':
-    case 'hr':
-    case 'h':
-      return n * h;
-    case 'minutes':
-    case 'minute':
-    case 'mins':
-    case 'min':
-    case 'm':
-      return n * m;
-    case 'seconds':
-    case 'second':
-    case 'secs':
-    case 'sec':
-    case 's':
-      return n * s;
-    case 'milliseconds':
-    case 'millisecond':
-    case 'msecs':
-    case 'msec':
-    case 'ms':
-      return n;
-    default:
-      return undefined;
-  }
-}
-
-/**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function fmtShort(ms) {
-  if (ms >= d) {
-    return Math.round(ms / d) + 'd';
-  }
-  if (ms >= h) {
-    return Math.round(ms / h) + 'h';
-  }
-  if (ms >= m) {
-    return Math.round(ms / m) + 'm';
-  }
-  if (ms >= s) {
-    return Math.round(ms / s) + 's';
-  }
-  return ms + 'ms';
-}
-
-/**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function fmtLong(ms) {
-  return plural(ms, d, 'day') ||
-    plural(ms, h, 'hour') ||
-    plural(ms, m, 'minute') ||
-    plural(ms, s, 'second') ||
-    ms + ' ms';
-}
-
-/**
- * Pluralization helper.
- */
-
-function plural(ms, n, name) {
-  if (ms < n) {
-    return;
-  }
-  if (ms < n * 1.5) {
-    return Math.floor(ms / n) + ' ' + name;
-  }
-  return Math.ceil(ms / n) + ' ' + name + 's';
-}
diff --git a/d2d_app/node_modules/express/node_modules/ms/package.json b/d2d_app/node_modules/express/node_modules/ms/package.json
deleted file mode 100644 (file)
index 1acc877..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-{
-  "_from": "ms@2.0.0",
-  "_id": "ms@2.0.0",
-  "_inBundle": false,
-  "_integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-  "_location": "/ms",
-  "_phantomChildren": {},
-  "_requested": {
-    "type": "version",
-    "registry": true,
-    "raw": "ms@2.0.0",
-    "name": "ms",
-    "escapedName": "ms",
-    "rawSpec": "2.0.0",
-    "saveSpec": null,
-    "fetchSpec": "2.0.0"
-  },
-  "_requiredBy": [
-    "/body-parser/debug",
-    "/cachemanager/debug",
-    "/electron-download/debug",
-    "/eslint/debug",
-    "/expand-brackets/debug",
-    "/express/debug",
-    "/extract-zip/debug",
-    "/finalhandler/debug",
-    "/grunt-eslint/debug",
-    "/inmemfilecache/debug",
-    "/mocha/debug",
-    "/nugget/debug",
-    "/snapdragon/debug",
-    "/sumchecker/debug"
-  ],
-  "_resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-  "_shasum": "5608aeadfc00be6c2901df5f9861788de0d597c8",
-  "_spec": "ms@2.0.0",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/body-parser/node_modules/debug",
-  "bugs": {
-    "url": "https://github.com/zeit/ms/issues"
-  },
-  "bundleDependencies": false,
-  "deprecated": false,
-  "description": "Tiny milisecond conversion utility",
-  "devDependencies": {
-    "eslint": "3.19.0",
-    "expect.js": "0.3.1",
-    "husky": "0.13.3",
-    "lint-staged": "3.4.1",
-    "mocha": "3.4.1"
-  },
-  "eslintConfig": {
-    "extends": "eslint:recommended",
-    "env": {
-      "node": true,
-      "es6": true
-    }
-  },
-  "files": [
-    "index.js"
-  ],
-  "homepage": "https://github.com/zeit/ms#readme",
-  "license": "MIT",
-  "lint-staged": {
-    "*.js": [
-      "npm run lint",
-      "prettier --single-quote --write",
-      "git add"
-    ]
-  },
-  "main": "./index",
-  "name": "ms",
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/zeit/ms.git"
-  },
-  "scripts": {
-    "lint": "eslint lib/* bin/*",
-    "precommit": "lint-staged",
-    "test": "mocha tests.js"
-  },
-  "version": "2.0.0"
-}
diff --git a/d2d_app/node_modules/express/node_modules/ms/readme.md b/d2d_app/node_modules/express/node_modules/ms/readme.md
deleted file mode 100644 (file)
index 84a9974..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-# ms
-
-[![Build Status](https://travis-ci.org/zeit/ms.svg?branch=master)](https://travis-ci.org/zeit/ms)
-[![Slack Channel](http://zeit-slackin.now.sh/badge.svg)](https://zeit.chat/)
-
-Use this package to easily convert various time formats to milliseconds.
-
-## Examples
-
-```js
-ms('2 days')  // 172800000
-ms('1d')      // 86400000
-ms('10h')     // 36000000
-ms('2.5 hrs') // 9000000
-ms('2h')      // 7200000
-ms('1m')      // 60000
-ms('5s')      // 5000
-ms('1y')      // 31557600000
-ms('100')     // 100
-```
-
-### Convert from milliseconds
-
-```js
-ms(60000)             // "1m"
-ms(2 * 60000)         // "2m"
-ms(ms('10 hours'))    // "10h"
-```
-
-### Time format written-out
-
-```js
-ms(60000, { long: true })             // "1 minute"
-ms(2 * 60000, { long: true })         // "2 minutes"
-ms(ms('10 hours'), { long: true })    // "10 hours"
-```
-
-## Features
-
-- Works both in [node](https://nodejs.org) and in the browser.
-- If a number is supplied to `ms`, a string with a unit is returned.
-- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`).
-- If you pass a string with a number and a valid unit, the number of equivalent ms is returned.
-
-## Caught a bug?
-
-1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
-2. Link the package to the global module directory: `npm link`
-3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, node will now use your clone of ms!
-
-As always, you can run the tests using: `npm test`
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/debug/package.json b/d2d_app/node_modules/express/node_modules/send/node_modules/debug/package.json
deleted file mode 100644 (file)
index 1f3f48e..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-{
-  "_from": "debug@2.6.9",
-  "_id": "debug@2.6.9",
-  "_inBundle": false,
-  "_integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-  "_location": "/send/debug",
-  "_phantomChildren": {},
-  "_requested": {
-    "type": "version",
-    "registry": true,
-    "raw": "debug@2.6.9",
-    "name": "debug",
-    "escapedName": "debug",
-    "rawSpec": "2.6.9",
-    "saveSpec": null,
-    "fetchSpec": "2.6.9"
-  },
-  "_requiredBy": [
-    "/send"
-  ],
-  "_resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-  "_shasum": "5d128515df134ff327e90a4c93f4e077a536341f",
-  "_spec": "debug@2.6.9",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/send",
-  "author": {
-    "name": "TJ Holowaychuk",
-    "email": "tj@vision-media.ca"
-  },
-  "browser": "./src/browser.js",
-  "bugs": {
-    "url": "https://github.com/visionmedia/debug/issues"
-  },
-  "bundleDependencies": false,
-  "component": {
-    "scripts": {
-      "debug/index.js": "browser.js",
-      "debug/debug.js": "debug.js"
-    }
-  },
-  "contributors": [
-    {
-      "name": "Nathan Rajlich",
-      "email": "nathan@tootallnate.net",
-      "url": "http://n8.io"
-    },
-    {
-      "name": "Andrew Rhyne",
-      "email": "rhyneandrew@gmail.com"
-    }
-  ],
-  "dependencies": {
-    "ms": "2.0.0"
-  },
-  "deprecated": false,
-  "description": "small debugging utility",
-  "devDependencies": {
-    "browserify": "9.0.3",
-    "chai": "^3.5.0",
-    "concurrently": "^3.1.0",
-    "coveralls": "^2.11.15",
-    "eslint": "^3.12.1",
-    "istanbul": "^0.4.5",
-    "karma": "^1.3.0",
-    "karma-chai": "^0.1.0",
-    "karma-mocha": "^1.3.0",
-    "karma-phantomjs-launcher": "^1.0.2",
-    "karma-sinon": "^1.0.5",
-    "mocha": "^3.2.0",
-    "mocha-lcov-reporter": "^1.2.0",
-    "rimraf": "^2.5.4",
-    "sinon": "^1.17.6",
-    "sinon-chai": "^2.8.0"
-  },
-  "homepage": "https://github.com/visionmedia/debug#readme",
-  "keywords": [
-    "debug",
-    "log",
-    "debugger"
-  ],
-  "license": "MIT",
-  "main": "./src/index.js",
-  "name": "debug",
-  "repository": {
-    "type": "git",
-    "url": "git://github.com/visionmedia/debug.git"
-  },
-  "version": "2.6.9"
-}
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/mime/.npmignore b/d2d_app/node_modules/express/node_modules/send/node_modules/mime/.npmignore
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/mime/CHANGELOG.md b/d2d_app/node_modules/express/node_modules/send/node_modules/mime/CHANGELOG.md
deleted file mode 100644 (file)
index f127535..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-# Changelog
-
-## v1.6.0 (24/11/2017)
-*No changelog for this release.*
-
----
-
-## v2.0.4 (24/11/2017)
-- [**closed**] Switch to mime-score module for resolving extension contention issues. [#182](https://github.com/broofa/node-mime/issues/182)
-- [**closed**] Update mime-db to 1.31.0 in v1.x branch [#181](https://github.com/broofa/node-mime/issues/181)
-
----
-
-## v1.5.0 (22/11/2017)
-- [**closed**] need ES5 version ready in npm package [#179](https://github.com/broofa/node-mime/issues/179)
-- [**closed**] mime-db no trace of iWork - pages / numbers / etc. [#178](https://github.com/broofa/node-mime/issues/178)
-- [**closed**] How it works in brownser ? [#176](https://github.com/broofa/node-mime/issues/176)
-- [**closed**] Missing `./Mime` [#175](https://github.com/broofa/node-mime/issues/175)
-- [**closed**] Vulnerable Regular Expression [#167](https://github.com/broofa/node-mime/issues/167)
-
----
-
-## v2.0.3 (25/09/2017)
-*No changelog for this release.*
-
----
-
-## v1.4.1 (25/09/2017)
-- [**closed**] Issue when bundling with webpack [#172](https://github.com/broofa/node-mime/issues/172)
-
----
-
-## v2.0.2 (15/09/2017)
-- [**V2**] fs.readFileSync is not a function [#165](https://github.com/broofa/node-mime/issues/165)
-- [**closed**] The extension for video/quicktime should map to .mov, not .qt [#164](https://github.com/broofa/node-mime/issues/164)
-- [**V2**] [v2 Feedback request] Mime class API [#163](https://github.com/broofa/node-mime/issues/163)
-- [**V2**] [v2 Feedback request] Resolving conflicts over extensions [#162](https://github.com/broofa/node-mime/issues/162)
-- [**V2**] Allow callers to load module with official, full, or no defined types.  [#161](https://github.com/broofa/node-mime/issues/161)
-- [**V2**] Use "facets" to resolve extension conflicts [#160](https://github.com/broofa/node-mime/issues/160)
-- [**V2**] Remove fs and path dependencies [#152](https://github.com/broofa/node-mime/issues/152)
-- [**V2**] Default content-type should not be application/octet-stream [#139](https://github.com/broofa/node-mime/issues/139)
-- [**V2**] reset mime-types [#124](https://github.com/broofa/node-mime/issues/124)
-- [**V2**] Extensionless paths should return null or false [#113](https://github.com/broofa/node-mime/issues/113)
-
----
-
-## v2.0.1 (14/09/2017)
-- [**closed**] Changelog for v2.0 does not mention breaking changes [#171](https://github.com/broofa/node-mime/issues/171)
-- [**closed**] MIME breaking with 'class' declaration as it is without 'use strict mode' [#170](https://github.com/broofa/node-mime/issues/170)
-
----
-
-## v2.0.0 (12/09/2017)
-- [**closed**] woff and woff2 [#168](https://github.com/broofa/node-mime/issues/168)
-
----
-
-## v1.4.0 (28/08/2017)
-- [**closed**] support for ac3 voc files [#159](https://github.com/broofa/node-mime/issues/159)
-- [**closed**] Help understanding change from application/xml to text/xml [#158](https://github.com/broofa/node-mime/issues/158)
-- [**closed**] no longer able to override mimetype [#157](https://github.com/broofa/node-mime/issues/157)
-- [**closed**] application/vnd.adobe.photoshop [#147](https://github.com/broofa/node-mime/issues/147)
-- [**closed**] Directories should appear as something other than application/octet-stream [#135](https://github.com/broofa/node-mime/issues/135)
-- [**closed**] requested features [#131](https://github.com/broofa/node-mime/issues/131)
-- [**closed**] Make types.json loading optional? [#129](https://github.com/broofa/node-mime/issues/129)
-- [**closed**] Cannot find module './types.json' [#120](https://github.com/broofa/node-mime/issues/120)
-- [**V2**] .wav files show up as "audio/x-wav" instead of "audio/x-wave" [#118](https://github.com/broofa/node-mime/issues/118)
-- [**closed**] Don't be a pain in the ass for node community [#108](https://github.com/broofa/node-mime/issues/108)
-- [**closed**] don't make default_type global [#78](https://github.com/broofa/node-mime/issues/78)
-- [**closed**] mime.extension() fails if the content-type is parameterized [#74](https://github.com/broofa/node-mime/issues/74)
-
----
-
-## v1.3.6 (11/05/2017)
-- [**closed**] .md should be text/markdown as of March 2016 [#154](https://github.com/broofa/node-mime/issues/154)
-- [**closed**] Error while installing mime [#153](https://github.com/broofa/node-mime/issues/153)
-- [**closed**] application/manifest+json [#149](https://github.com/broofa/node-mime/issues/149)
-- [**closed**] Dynamic adaptive streaming over HTTP (DASH) file extension typo [#141](https://github.com/broofa/node-mime/issues/141)
-- [**closed**] charsets image/png undefined [#140](https://github.com/broofa/node-mime/issues/140)
-- [**closed**] Mime-db dependency out of date [#130](https://github.com/broofa/node-mime/issues/130)
-- [**closed**] how to support plist? [#126](https://github.com/broofa/node-mime/issues/126)
-- [**closed**] how does .types file format look like? [#123](https://github.com/broofa/node-mime/issues/123)
-- [**closed**] Feature: support for expanding MIME patterns [#121](https://github.com/broofa/node-mime/issues/121)
-- [**closed**] DEBUG_MIME doesn't work [#117](https://github.com/broofa/node-mime/issues/117)
-
----
-
-## v1.3.4 (06/02/2015)
-*No changelog for this release.*
-
----
-
-## v1.3.3 (06/02/2015)
-*No changelog for this release.*
-
----
-
-## v1.3.1 (05/02/2015)
-- [**closed**] Consider adding support for Handlebars .hbs file ending [#111](https://github.com/broofa/node-mime/issues/111)
-- [**closed**] Consider adding support for hjson. [#110](https://github.com/broofa/node-mime/issues/110)
-- [**closed**] Add mime type for Opus audio files [#94](https://github.com/broofa/node-mime/issues/94)
-- [**closed**] Consider making the `Requesting New Types` information more visible [#77](https://github.com/broofa/node-mime/issues/77)
-
----
-
-## v1.3.0 (05/02/2015)
-- [**closed**] Add common name? [#114](https://github.com/broofa/node-mime/issues/114)
-- [**closed**] application/x-yaml [#104](https://github.com/broofa/node-mime/issues/104)
-- [**closed**] Add mime type for WOFF file format 2.0 [#102](https://github.com/broofa/node-mime/issues/102)
-- [**closed**] application/x-msi for .msi [#99](https://github.com/broofa/node-mime/issues/99)
-- [**closed**] Add mimetype for gettext translation files [#98](https://github.com/broofa/node-mime/issues/98)
-- [**closed**] collaborators [#88](https://github.com/broofa/node-mime/issues/88)
-- [**closed**] getting errot in installation of mime module...any1 can help? [#87](https://github.com/broofa/node-mime/issues/87)
-- [**closed**] should application/json's charset be utf8? [#86](https://github.com/broofa/node-mime/issues/86)
-- [**closed**] Add "license" and "licenses" to package.json [#81](https://github.com/broofa/node-mime/issues/81)
-- [**closed**] lookup with extension-less file on Windows returns wrong type [#68](https://github.com/broofa/node-mime/issues/68)
-
----
-
-## v1.2.11 (15/08/2013)
-- [**closed**] Update mime.types [#65](https://github.com/broofa/node-mime/issues/65)
-- [**closed**] Publish a new version [#63](https://github.com/broofa/node-mime/issues/63)
-- [**closed**] README should state upfront that "application/octet-stream" is default for unknown extension [#55](https://github.com/broofa/node-mime/issues/55)
-- [**closed**] Suggested improvement to the charset API [#52](https://github.com/broofa/node-mime/issues/52)
-
----
-
-## v1.2.10 (25/07/2013)
-- [**closed**] Mime type for woff files should be application/font-woff and not application/x-font-woff [#62](https://github.com/broofa/node-mime/issues/62)
-- [**closed**] node.types in conflict with mime.types [#51](https://github.com/broofa/node-mime/issues/51)
-
----
-
-## v1.2.9 (17/01/2013)
-- [**closed**] Please update "mime" NPM [#49](https://github.com/broofa/node-mime/issues/49)
-- [**closed**] Please add semicolon [#46](https://github.com/broofa/node-mime/issues/46)
-- [**closed**] parse full mime types [#43](https://github.com/broofa/node-mime/issues/43)
-
----
-
-## v1.2.8 (10/01/2013)
-- [**closed**] /js directory mime is application/javascript. Is it correct? [#47](https://github.com/broofa/node-mime/issues/47)
-- [**closed**] Add mime types for lua code. [#45](https://github.com/broofa/node-mime/issues/45)
-
----
-
-## v1.2.7 (19/10/2012)
-- [**closed**] cannot install 1.2.7 via npm [#41](https://github.com/broofa/node-mime/issues/41)
-- [**closed**] Transfer ownership to @broofa [#36](https://github.com/broofa/node-mime/issues/36)
-- [**closed**] it's wrong to set charset to UTF-8 for text [#30](https://github.com/broofa/node-mime/issues/30)
-- [**closed**] Allow multiple instances of MIME types container [#27](https://github.com/broofa/node-mime/issues/27)
-
----
-
-## v1.2.5 (16/02/2012)
-- [**closed**] When looking up a types, check hasOwnProperty [#23](https://github.com/broofa/node-mime/issues/23)
-- [**closed**] Bump version to 1.2.2 [#18](https://github.com/broofa/node-mime/issues/18)
-- [**closed**] No license [#16](https://github.com/broofa/node-mime/issues/16)
-- [**closed**] Some types missing that are used by html5/css3 [#13](https://github.com/broofa/node-mime/issues/13)
-- [**closed**] npm install fails for 1.2.1 [#12](https://github.com/broofa/node-mime/issues/12)
-- [**closed**] image/pjpeg + image/x-png [#10](https://github.com/broofa/node-mime/issues/10)
-- [**closed**] symlink [#8](https://github.com/broofa/node-mime/issues/8)
-- [**closed**] gzip [#2](https://github.com/broofa/node-mime/issues/2)
-- [**closed**] ALL CAPS filenames return incorrect mime type [#1](https://github.com/broofa/node-mime/issues/1)
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/mime/README.md b/d2d_app/node_modules/express/node_modules/send/node_modules/mime/README.md
deleted file mode 100644 (file)
index 506fbe5..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-# mime
-
-Comprehensive MIME type mapping API based on mime-db module.
-
-## Install
-
-Install with [npm](http://github.com/isaacs/npm):
-
-    npm install mime
-
-## Contributing / Testing
-
-    npm run test
-
-## Command Line
-
-    mime [path_string]
-
-E.g.
-
-    > mime scripts/jquery.js
-    application/javascript
-
-## API - Queries
-
-### mime.lookup(path)
-Get the mime type associated with a file, if no mime type is found `application/octet-stream` is returned. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.').  E.g.
-
-```js
-var mime = require('mime');
-
-mime.lookup('/path/to/file.txt');         // => 'text/plain'
-mime.lookup('file.txt');                  // => 'text/plain'
-mime.lookup('.TXT');                      // => 'text/plain'
-mime.lookup('htm');                       // => 'text/html'
-```
-
-### mime.default_type
-Sets the mime type returned when `mime.lookup` fails to find the extension searched for. (Default is `application/octet-stream`.)
-
-### mime.extension(type)
-Get the default extension for `type`
-
-```js
-mime.extension('text/html');                 // => 'html'
-mime.extension('application/octet-stream');  // => 'bin'
-```
-
-### mime.charsets.lookup()
-
-Map mime-type to charset
-
-```js
-mime.charsets.lookup('text/plain');        // => 'UTF-8'
-```
-
-(The logic for charset lookups is pretty rudimentary.  Feel free to suggest improvements.)
-
-## API - Defining Custom Types
-
-Custom type mappings can be added on a per-project basis via the following APIs.
-
-### mime.define()
-
-Add custom mime/extension mappings
-
-```js
-mime.define({
-    'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],
-    'application/x-my-type': ['x-mt', 'x-mtt'],
-    // etc ...
-});
-
-mime.lookup('x-sft');                 // => 'text/x-some-format'
-```
-
-The first entry in the extensions array is returned by `mime.extension()`. E.g.
-
-```js
-mime.extension('text/x-some-format'); // => 'x-sf'
-```
-
-### mime.load(filepath)
-
-Load mappings from an Apache ".types" format file
-
-```js
-mime.load('./my_project.types');
-```
-The .types file format is simple -  See the `types` dir for examples.
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/mime/cli.js b/d2d_app/node_modules/express/node_modules/send/node_modules/mime/cli.js
deleted file mode 100644 (file)
index 20b1ffe..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/env node
-
-var mime = require('./mime.js');
-var file = process.argv[2];
-var type = mime.lookup(file);
-
-process.stdout.write(type + '\n');
-
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/mime/mime.js b/d2d_app/node_modules/express/node_modules/send/node_modules/mime/mime.js
deleted file mode 100644 (file)
index d7efbde..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-var path = require('path');
-var fs = require('fs');
-
-function Mime() {
-  // Map of extension -> mime type
-  this.types = Object.create(null);
-
-  // Map of mime type -> extension
-  this.extensions = Object.create(null);
-}
-
-/**
- * Define mimetype -> extension mappings.  Each key is a mime-type that maps
- * to an array of extensions associated with the type.  The first extension is
- * used as the default extension for the type.
- *
- * e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
- *
- * @param map (Object) type definitions
- */
-Mime.prototype.define = function (map) {
-  for (var type in map) {
-    var exts = map[type];
-    for (var i = 0; i < exts.length; i++) {
-      if (process.env.DEBUG_MIME && this.types[exts[i]]) {
-        console.warn((this._loading || "define()").replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
-          this.types[exts[i]] + ' to ' + type);
-      }
-
-      this.types[exts[i]] = type;
-    }
-
-    // Default extension is the first one we encounter
-    if (!this.extensions[type]) {
-      this.extensions[type] = exts[0];
-    }
-  }
-};
-
-/**
- * Load an Apache2-style ".types" file
- *
- * This may be called multiple times (it's expected).  Where files declare
- * overlapping types/extensions, the last file wins.
- *
- * @param file (String) path of file to load.
- */
-Mime.prototype.load = function(file) {
-  this._loading = file;
-  // Read file and split into lines
-  var map = {},
-      content = fs.readFileSync(file, 'ascii'),
-      lines = content.split(/[\r\n]+/);
-
-  lines.forEach(function(line) {
-    // Clean up whitespace/comments, and split into fields
-    var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/);
-    map[fields.shift()] = fields;
-  });
-
-  this.define(map);
-
-  this._loading = null;
-};
-
-/**
- * Lookup a mime type based on extension
- */
-Mime.prototype.lookup = function(path, fallback) {
-  var ext = path.replace(/^.*[\.\/\\]/, '').toLowerCase();
-
-  return this.types[ext] || fallback || this.default_type;
-};
-
-/**
- * Return file extension associated with a mime type
- */
-Mime.prototype.extension = function(mimeType) {
-  var type = mimeType.match(/^\s*([^;\s]*)(?:;|\s|$)/)[1].toLowerCase();
-  return this.extensions[type];
-};
-
-// Default instance
-var mime = new Mime();
-
-// Define built-in types
-mime.define(require('./types.json'));
-
-// Default type
-mime.default_type = mime.lookup('bin');
-
-//
-// Additional API specific to the default instance
-//
-
-mime.Mime = Mime;
-
-/**
- * Lookup a charset based on mime type.
- */
-mime.charsets = {
-  lookup: function(mimeType, fallback) {
-    // Assume text types are utf8
-    return (/^text\/|^application\/(javascript|json)/).test(mimeType) ? 'UTF-8' : fallback;
-  }
-};
-
-module.exports = mime;
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/mime/package.json b/d2d_app/node_modules/express/node_modules/send/node_modules/mime/package.json
deleted file mode 100644 (file)
index 91aa50e..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-{
-  "_from": "mime@1.6.0",
-  "_id": "mime@1.6.0",
-  "_inBundle": false,
-  "_integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
-  "_location": "/send/mime",
-  "_phantomChildren": {},
-  "_requested": {
-    "type": "version",
-    "registry": true,
-    "raw": "mime@1.6.0",
-    "name": "mime",
-    "escapedName": "mime",
-    "rawSpec": "1.6.0",
-    "saveSpec": null,
-    "fetchSpec": "1.6.0"
-  },
-  "_requiredBy": [
-    "/send"
-  ],
-  "_resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
-  "_shasum": "32cd9e5c64553bd58d19a568af452acff04981b1",
-  "_spec": "mime@1.6.0",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/send",
-  "author": {
-    "name": "Robert Kieffer",
-    "email": "robert@broofa.com",
-    "url": "http://github.com/broofa"
-  },
-  "bin": {
-    "mime": "cli.js"
-  },
-  "bugs": {
-    "url": "https://github.com/broofa/node-mime/issues"
-  },
-  "bundleDependencies": false,
-  "contributors": [
-    {
-      "name": "Benjamin Thomas",
-      "email": "benjamin@benjaminthomas.org",
-      "url": "http://github.com/bentomas"
-    }
-  ],
-  "dependencies": {},
-  "deprecated": false,
-  "description": "A comprehensive library for mime-type mapping",
-  "devDependencies": {
-    "github-release-notes": "0.13.1",
-    "mime-db": "1.31.0",
-    "mime-score": "1.1.0"
-  },
-  "engines": {
-    "node": ">=4"
-  },
-  "homepage": "https://github.com/broofa/node-mime#readme",
-  "keywords": [
-    "util",
-    "mime"
-  ],
-  "license": "MIT",
-  "main": "mime.js",
-  "name": "mime",
-  "repository": {
-    "url": "git+https://github.com/broofa/node-mime.git",
-    "type": "git"
-  },
-  "scripts": {
-    "changelog": "gren changelog --tags=all --generate --override",
-    "prepare": "node src/build.js",
-    "test": "node src/test.js"
-  },
-  "version": "1.6.0"
-}
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/mime/src/build.js b/d2d_app/node_modules/express/node_modules/send/node_modules/mime/src/build.js
deleted file mode 100644 (file)
index 4928e48..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env node
-
-'use strict';
-
-const fs = require('fs');
-const path = require('path');
-const mimeScore = require('mime-score');
-
-let db = require('mime-db');
-let chalk = require('chalk');
-
-const STANDARD_FACET_SCORE = 900;
-
-const byExtension = {};
-
-// Clear out any conflict extensions in mime-db
-for (let type in db) {
-  let entry = db[type];
-  entry.type = type;
-
-  if (!entry.extensions) continue;
-
-  entry.extensions.forEach(ext => {
-    if (ext in byExtension) {
-      const e0 = entry;
-      const e1 = byExtension[ext];
-      e0.pri = mimeScore(e0.type, e0.source);
-      e1.pri = mimeScore(e1.type, e1.source);
-
-      let drop = e0.pri < e1.pri ? e0 : e1;
-      let keep = e0.pri >= e1.pri ? e0 : e1;
-      drop.extensions = drop.extensions.filter(e => e !== ext);
-
-      console.log(`${ext}: Keeping ${chalk.green(keep.type)} (${keep.pri}), dropping ${chalk.red(drop.type)} (${drop.pri})`);
-    }
-    byExtension[ext] = entry;
-  });
-}
-
-function writeTypesFile(types, path) {
-  fs.writeFileSync(path, JSON.stringify(types));
-}
-
-// Segregate into standard and non-standard types based on facet per
-// https://tools.ietf.org/html/rfc6838#section-3.1
-const types = {};
-
-Object.keys(db).sort().forEach(k => {
-  const entry = db[k];
-  types[entry.type] = entry.extensions;
-});
-
-writeTypesFile(types, path.join(__dirname, '..', 'types.json'));
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/mime/src/test.js b/d2d_app/node_modules/express/node_modules/send/node_modules/mime/src/test.js
deleted file mode 100644 (file)
index 42958a2..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Usage: node test.js
- */
-
-var mime = require('../mime');
-var assert = require('assert');
-var path = require('path');
-
-//
-// Test mime lookups
-//
-
-assert.equal('text/plain', mime.lookup('text.txt'));     // normal file
-assert.equal('text/plain', mime.lookup('TEXT.TXT'));     // uppercase
-assert.equal('text/plain', mime.lookup('dir/text.txt')); // dir + file
-assert.equal('text/plain', mime.lookup('.text.txt'));    // hidden file
-assert.equal('text/plain', mime.lookup('.txt'));         // nameless
-assert.equal('text/plain', mime.lookup('txt'));          // extension-only
-assert.equal('text/plain', mime.lookup('/txt'));         // extension-less ()
-assert.equal('text/plain', mime.lookup('\\txt'));        // Windows, extension-less
-assert.equal('application/octet-stream', mime.lookup('text.nope')); // unrecognized
-assert.equal('fallback', mime.lookup('text.fallback', 'fallback')); // alternate default
-
-//
-// Test extensions
-//
-
-assert.equal('txt', mime.extension(mime.types.text));
-assert.equal('html', mime.extension(mime.types.htm));
-assert.equal('bin', mime.extension('application/octet-stream'));
-assert.equal('bin', mime.extension('application/octet-stream '));
-assert.equal('html', mime.extension(' text/html; charset=UTF-8'));
-assert.equal('html', mime.extension('text/html; charset=UTF-8 '));
-assert.equal('html', mime.extension('text/html; charset=UTF-8'));
-assert.equal('html', mime.extension('text/html ; charset=UTF-8'));
-assert.equal('html', mime.extension('text/html;charset=UTF-8'));
-assert.equal('html', mime.extension('text/Html;charset=UTF-8'));
-assert.equal(undefined, mime.extension('unrecognized'));
-
-//
-// Test node.types lookups
-//
-
-assert.equal('font/woff', mime.lookup('file.woff'));
-assert.equal('application/octet-stream', mime.lookup('file.buffer'));
-// TODO: Uncomment once #157 is resolved
-// assert.equal('audio/mp4', mime.lookup('file.m4a'));
-assert.equal('font/otf', mime.lookup('file.otf'));
-
-//
-// Test charsets
-//
-
-assert.equal('UTF-8', mime.charsets.lookup('text/plain'));
-assert.equal('UTF-8', mime.charsets.lookup(mime.types.js));
-assert.equal('UTF-8', mime.charsets.lookup(mime.types.json));
-assert.equal(undefined, mime.charsets.lookup(mime.types.bin));
-assert.equal('fallback', mime.charsets.lookup('application/octet-stream', 'fallback'));
-
-console.log('\nAll tests passed');
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/mime/types.json b/d2d_app/node_modules/express/node_modules/send/node_modules/mime/types.json
deleted file mode 100644 (file)
index bec78ab..0000000
+++ /dev/null
@@ -1 +0,0 @@
-{"application/andrew-inset":["ez"],"application/applixware":["aw"],"application/atom+xml":["atom"],"application/atomcat+xml":["atomcat"],"application/atomsvc+xml":["atomsvc"],"application/bdoc":["bdoc"],"application/ccxml+xml":["ccxml"],"application/cdmi-capability":["cdmia"],"application/cdmi-container":["cdmic"],"application/cdmi-domain":["cdmid"],"application/cdmi-object":["cdmio"],"application/cdmi-queue":["cdmiq"],"application/cu-seeme":["cu"],"application/dash+xml":["mpd"],"application/davmount+xml":["davmount"],"application/docbook+xml":["dbk"],"application/dssc+der":["dssc"],"application/dssc+xml":["xdssc"],"application/ecmascript":["ecma"],"application/emma+xml":["emma"],"application/epub+zip":["epub"],"application/exi":["exi"],"application/font-tdpfr":["pfr"],"application/font-woff":[],"application/font-woff2":[],"application/geo+json":["geojson"],"application/gml+xml":["gml"],"application/gpx+xml":["gpx"],"application/gxf":["gxf"],"application/gzip":["gz"],"application/hyperstudio":["stk"],"application/inkml+xml":["ink","inkml"],"application/ipfix":["ipfix"],"application/java-archive":["jar","war","ear"],"application/java-serialized-object":["ser"],"application/java-vm":["class"],"application/javascript":["js","mjs"],"application/json":["json","map"],"application/json5":["json5"],"application/jsonml+json":["jsonml"],"application/ld+json":["jsonld"],"application/lost+xml":["lostxml"],"application/mac-binhex40":["hqx"],"application/mac-compactpro":["cpt"],"application/mads+xml":["mads"],"application/manifest+json":["webmanifest"],"application/marc":["mrc"],"application/marcxml+xml":["mrcx"],"application/mathematica":["ma","nb","mb"],"application/mathml+xml":["mathml"],"application/mbox":["mbox"],"application/mediaservercontrol+xml":["mscml"],"application/metalink+xml":["metalink"],"application/metalink4+xml":["meta4"],"application/mets+xml":["mets"],"application/mods+xml":["mods"],"application/mp21":["m21","mp21"],"application/mp4":["mp4s","m4p"],"application/msword":["doc","dot"],"application/mxf":["mxf"],"application/octet-stream":["bin","dms","lrf","mar","so","dist","distz","pkg","bpk","dump","elc","deploy","exe","dll","deb","dmg","iso","img","msi","msp","msm","buffer"],"application/oda":["oda"],"application/oebps-package+xml":["opf"],"application/ogg":["ogx"],"application/omdoc+xml":["omdoc"],"application/onenote":["onetoc","onetoc2","onetmp","onepkg"],"application/oxps":["oxps"],"application/patch-ops-error+xml":["xer"],"application/pdf":["pdf"],"application/pgp-encrypted":["pgp"],"application/pgp-signature":["asc","sig"],"application/pics-rules":["prf"],"application/pkcs10":["p10"],"application/pkcs7-mime":["p7m","p7c"],"application/pkcs7-signature":["p7s"],"application/pkcs8":["p8"],"application/pkix-attr-cert":["ac"],"application/pkix-cert":["cer"],"application/pkix-crl":["crl"],"application/pkix-pkipath":["pkipath"],"application/pkixcmp":["pki"],"application/pls+xml":["pls"],"application/postscript":["ai","eps","ps"],"application/prs.cww":["cww"],"application/pskc+xml":["pskcxml"],"application/raml+yaml":["raml"],"application/rdf+xml":["rdf"],"application/reginfo+xml":["rif"],"application/relax-ng-compact-syntax":["rnc"],"application/resource-lists+xml":["rl"],"application/resource-lists-diff+xml":["rld"],"application/rls-services+xml":["rs"],"application/rpki-ghostbusters":["gbr"],"application/rpki-manifest":["mft"],"application/rpki-roa":["roa"],"application/rsd+xml":["rsd"],"application/rss+xml":["rss"],"application/rtf":["rtf"],"application/sbml+xml":["sbml"],"application/scvp-cv-request":["scq"],"application/scvp-cv-response":["scs"],"application/scvp-vp-request":["spq"],"application/scvp-vp-response":["spp"],"application/sdp":["sdp"],"application/set-payment-initiation":["setpay"],"application/set-registration-initiation":["setreg"],"application/shf+xml":["shf"],"application/smil+xml":["smi","smil"],"application/sparql-query":["rq"],"application/sparql-results+xml":["srx"],"application/srgs":["gram"],"application/srgs+xml":["grxml"],"application/sru+xml":["sru"],"application/ssdl+xml":["ssdl"],"application/ssml+xml":["ssml"],"application/tei+xml":["tei","teicorpus"],"application/thraud+xml":["tfi"],"application/timestamped-data":["tsd"],"application/vnd.3gpp.pic-bw-large":["plb"],"application/vnd.3gpp.pic-bw-small":["psb"],"application/vnd.3gpp.pic-bw-var":["pvb"],"application/vnd.3gpp2.tcap":["tcap"],"application/vnd.3m.post-it-notes":["pwn"],"application/vnd.accpac.simply.aso":["aso"],"application/vnd.accpac.simply.imp":["imp"],"application/vnd.acucobol":["acu"],"application/vnd.acucorp":["atc","acutc"],"application/vnd.adobe.air-application-installer-package+zip":["air"],"application/vnd.adobe.formscentral.fcdt":["fcdt"],"application/vnd.adobe.fxp":["fxp","fxpl"],"application/vnd.adobe.xdp+xml":["xdp"],"application/vnd.adobe.xfdf":["xfdf"],"application/vnd.ahead.space":["ahead"],"application/vnd.airzip.filesecure.azf":["azf"],"application/vnd.airzip.filesecure.azs":["azs"],"application/vnd.amazon.ebook":["azw"],"application/vnd.americandynamics.acc":["acc"],"application/vnd.amiga.ami":["ami"],"application/vnd.android.package-archive":["apk"],"application/vnd.anser-web-certificate-issue-initiation":["cii"],"application/vnd.anser-web-funds-transfer-initiation":["fti"],"application/vnd.antix.game-component":["atx"],"application/vnd.apple.installer+xml":["mpkg"],"application/vnd.apple.mpegurl":["m3u8"],"application/vnd.apple.pkpass":["pkpass"],"application/vnd.aristanetworks.swi":["swi"],"application/vnd.astraea-software.iota":["iota"],"application/vnd.audiograph":["aep"],"application/vnd.blueice.multipass":["mpm"],"application/vnd.bmi":["bmi"],"application/vnd.businessobjects":["rep"],"application/vnd.chemdraw+xml":["cdxml"],"application/vnd.chipnuts.karaoke-mmd":["mmd"],"application/vnd.cinderella":["cdy"],"application/vnd.claymore":["cla"],"application/vnd.cloanto.rp9":["rp9"],"application/vnd.clonk.c4group":["c4g","c4d","c4f","c4p","c4u"],"application/vnd.cluetrust.cartomobile-config":["c11amc"],"application/vnd.cluetrust.cartomobile-config-pkg":["c11amz"],"application/vnd.commonspace":["csp"],"application/vnd.contact.cmsg":["cdbcmsg"],"application/vnd.cosmocaller":["cmc"],"application/vnd.crick.clicker":["clkx"],"application/vnd.crick.clicker.keyboard":["clkk"],"application/vnd.crick.clicker.palette":["clkp"],"application/vnd.crick.clicker.template":["clkt"],"application/vnd.crick.clicker.wordbank":["clkw"],"application/vnd.criticaltools.wbs+xml":["wbs"],"application/vnd.ctc-posml":["pml"],"application/vnd.cups-ppd":["ppd"],"application/vnd.curl.car":["car"],"application/vnd.curl.pcurl":["pcurl"],"application/vnd.dart":["dart"],"application/vnd.data-vision.rdz":["rdz"],"application/vnd.dece.data":["uvf","uvvf","uvd","uvvd"],"application/vnd.dece.ttml+xml":["uvt","uvvt"],"application/vnd.dece.unspecified":["uvx","uvvx"],"application/vnd.dece.zip":["uvz","uvvz"],"application/vnd.denovo.fcselayout-link":["fe_launch"],"application/vnd.dna":["dna"],"application/vnd.dolby.mlp":["mlp"],"application/vnd.dpgraph":["dpg"],"application/vnd.dreamfactory":["dfac"],"application/vnd.ds-keypoint":["kpxx"],"application/vnd.dvb.ait":["ait"],"application/vnd.dvb.service":["svc"],"application/vnd.dynageo":["geo"],"application/vnd.ecowin.chart":["mag"],"application/vnd.enliven":["nml"],"application/vnd.epson.esf":["esf"],"application/vnd.epson.msf":["msf"],"application/vnd.epson.quickanime":["qam"],"application/vnd.epson.salt":["slt"],"application/vnd.epson.ssf":["ssf"],"application/vnd.eszigno3+xml":["es3","et3"],"application/vnd.ezpix-album":["ez2"],"application/vnd.ezpix-package":["ez3"],"application/vnd.fdf":["fdf"],"application/vnd.fdsn.mseed":["mseed"],"application/vnd.fdsn.seed":["seed","dataless"],"application/vnd.flographit":["gph"],"application/vnd.fluxtime.clip":["ftc"],"application/vnd.framemaker":["fm","frame","maker","book"],"application/vnd.frogans.fnc":["fnc"],"application/vnd.frogans.ltf":["ltf"],"application/vnd.fsc.weblaunch":["fsc"],"application/vnd.fujitsu.oasys":["oas"],"application/vnd.fujitsu.oasys2":["oa2"],"application/vnd.fujitsu.oasys3":["oa3"],"application/vnd.fujitsu.oasysgp":["fg5"],"application/vnd.fujitsu.oasysprs":["bh2"],"application/vnd.fujixerox.ddd":["ddd"],"application/vnd.fujixerox.docuworks":["xdw"],"application/vnd.fujixerox.docuworks.binder":["xbd"],"application/vnd.fuzzysheet":["fzs"],"application/vnd.genomatix.tuxedo":["txd"],"application/vnd.geogebra.file":["ggb"],"application/vnd.geogebra.tool":["ggt"],"application/vnd.geometry-explorer":["gex","gre"],"application/vnd.geonext":["gxt"],"application/vnd.geoplan":["g2w"],"application/vnd.geospace":["g3w"],"application/vnd.gmx":["gmx"],"application/vnd.google-apps.document":["gdoc"],"application/vnd.google-apps.presentation":["gslides"],"application/vnd.google-apps.spreadsheet":["gsheet"],"application/vnd.google-earth.kml+xml":["kml"],"application/vnd.google-earth.kmz":["kmz"],"application/vnd.grafeq":["gqf","gqs"],"application/vnd.groove-account":["gac"],"application/vnd.groove-help":["ghf"],"application/vnd.groove-identity-message":["gim"],"application/vnd.groove-injector":["grv"],"application/vnd.groove-tool-message":["gtm"],"application/vnd.groove-tool-template":["tpl"],"application/vnd.groove-vcard":["vcg"],"application/vnd.hal+xml":["hal"],"application/vnd.handheld-entertainment+xml":["zmm"],"application/vnd.hbci":["hbci"],"application/vnd.hhe.lesson-player":["les"],"application/vnd.hp-hpgl":["hpgl"],"application/vnd.hp-hpid":["hpid"],"application/vnd.hp-hps":["hps"],"application/vnd.hp-jlyt":["jlt"],"application/vnd.hp-pcl":["pcl"],"application/vnd.hp-pclxl":["pclxl"],"application/vnd.hydrostatix.sof-data":["sfd-hdstx"],"application/vnd.ibm.minipay":["mpy"],"application/vnd.ibm.modcap":["afp","listafp","list3820"],"application/vnd.ibm.rights-management":["irm"],"application/vnd.ibm.secure-container":["sc"],"application/vnd.iccprofile":["icc","icm"],"application/vnd.igloader":["igl"],"application/vnd.immervision-ivp":["ivp"],"application/vnd.immervision-ivu":["ivu"],"application/vnd.insors.igm":["igm"],"application/vnd.intercon.formnet":["xpw","xpx"],"application/vnd.intergeo":["i2g"],"application/vnd.intu.qbo":["qbo"],"application/vnd.intu.qfx":["qfx"],"application/vnd.ipunplugged.rcprofile":["rcprofile"],"application/vnd.irepository.package+xml":["irp"],"application/vnd.is-xpr":["xpr"],"application/vnd.isac.fcs":["fcs"],"application/vnd.jam":["jam"],"application/vnd.jcp.javame.midlet-rms":["rms"],"application/vnd.jisp":["jisp"],"application/vnd.joost.joda-archive":["joda"],"application/vnd.kahootz":["ktz","ktr"],"application/vnd.kde.karbon":["karbon"],"application/vnd.kde.kchart":["chrt"],"application/vnd.kde.kformula":["kfo"],"application/vnd.kde.kivio":["flw"],"application/vnd.kde.kontour":["kon"],"application/vnd.kde.kpresenter":["kpr","kpt"],"application/vnd.kde.kspread":["ksp"],"application/vnd.kde.kword":["kwd","kwt"],"application/vnd.kenameaapp":["htke"],"application/vnd.kidspiration":["kia"],"application/vnd.kinar":["kne","knp"],"application/vnd.koan":["skp","skd","skt","skm"],"application/vnd.kodak-descriptor":["sse"],"application/vnd.las.las+xml":["lasxml"],"application/vnd.llamagraphics.life-balance.desktop":["lbd"],"application/vnd.llamagraphics.life-balance.exchange+xml":["lbe"],"application/vnd.lotus-1-2-3":["123"],"application/vnd.lotus-approach":["apr"],"application/vnd.lotus-freelance":["pre"],"application/vnd.lotus-notes":["nsf"],"application/vnd.lotus-organizer":["org"],"application/vnd.lotus-screencam":["scm"],"application/vnd.lotus-wordpro":["lwp"],"application/vnd.macports.portpkg":["portpkg"],"application/vnd.mcd":["mcd"],"application/vnd.medcalcdata":["mc1"],"application/vnd.mediastation.cdkey":["cdkey"],"application/vnd.mfer":["mwf"],"application/vnd.mfmp":["mfm"],"application/vnd.micrografx.flo":["flo"],"application/vnd.micrografx.igx":["igx"],"application/vnd.mif":["mif"],"application/vnd.mobius.daf":["daf"],"application/vnd.mobius.dis":["dis"],"application/vnd.mobius.mbk":["mbk"],"application/vnd.mobius.mqy":["mqy"],"application/vnd.mobius.msl":["msl"],"application/vnd.mobius.plc":["plc"],"application/vnd.mobius.txf":["txf"],"application/vnd.mophun.application":["mpn"],"application/vnd.mophun.certificate":["mpc"],"application/vnd.mozilla.xul+xml":["xul"],"application/vnd.ms-artgalry":["cil"],"application/vnd.ms-cab-compressed":["cab"],"application/vnd.ms-excel":["xls","xlm","xla","xlc","xlt","xlw"],"application/vnd.ms-excel.addin.macroenabled.12":["xlam"],"application/vnd.ms-excel.sheet.binary.macroenabled.12":["xlsb"],"application/vnd.ms-excel.sheet.macroenabled.12":["xlsm"],"application/vnd.ms-excel.template.macroenabled.12":["xltm"],"application/vnd.ms-fontobject":["eot"],"application/vnd.ms-htmlhelp":["chm"],"application/vnd.ms-ims":["ims"],"application/vnd.ms-lrm":["lrm"],"application/vnd.ms-officetheme":["thmx"],"application/vnd.ms-outlook":["msg"],"application/vnd.ms-pki.seccat":["cat"],"application/vnd.ms-pki.stl":["stl"],"application/vnd.ms-powerpoint":["ppt","pps","pot"],"application/vnd.ms-powerpoint.addin.macroenabled.12":["ppam"],"application/vnd.ms-powerpoint.presentation.macroenabled.12":["pptm"],"application/vnd.ms-powerpoint.slide.macroenabled.12":["sldm"],"application/vnd.ms-powerpoint.slideshow.macroenabled.12":["ppsm"],"application/vnd.ms-powerpoint.template.macroenabled.12":["potm"],"application/vnd.ms-project":["mpp","mpt"],"application/vnd.ms-word.document.macroenabled.12":["docm"],"application/vnd.ms-word.template.macroenabled.12":["dotm"],"application/vnd.ms-works":["wps","wks","wcm","wdb"],"application/vnd.ms-wpl":["wpl"],"application/vnd.ms-xpsdocument":["xps"],"application/vnd.mseq":["mseq"],"application/vnd.musician":["mus"],"application/vnd.muvee.style":["msty"],"application/vnd.mynfc":["taglet"],"application/vnd.neurolanguage.nlu":["nlu"],"application/vnd.nitf":["ntf","nitf"],"application/vnd.noblenet-directory":["nnd"],"application/vnd.noblenet-sealer":["nns"],"application/vnd.noblenet-web":["nnw"],"application/vnd.nokia.n-gage.data":["ngdat"],"application/vnd.nokia.n-gage.symbian.install":["n-gage"],"application/vnd.nokia.radio-preset":["rpst"],"application/vnd.nokia.radio-presets":["rpss"],"application/vnd.novadigm.edm":["edm"],"application/vnd.novadigm.edx":["edx"],"application/vnd.novadigm.ext":["ext"],"application/vnd.oasis.opendocument.chart":["odc"],"application/vnd.oasis.opendocument.chart-template":["otc"],"application/vnd.oasis.opendocument.database":["odb"],"application/vnd.oasis.opendocument.formula":["odf"],"application/vnd.oasis.opendocument.formula-template":["odft"],"application/vnd.oasis.opendocument.graphics":["odg"],"application/vnd.oasis.opendocument.graphics-template":["otg"],"application/vnd.oasis.opendocument.image":["odi"],"application/vnd.oasis.opendocument.image-template":["oti"],"application/vnd.oasis.opendocument.presentation":["odp"],"application/vnd.oasis.opendocument.presentation-template":["otp"],"application/vnd.oasis.opendocument.spreadsheet":["ods"],"application/vnd.oasis.opendocument.spreadsheet-template":["ots"],"application/vnd.oasis.opendocument.text":["odt"],"application/vnd.oasis.opendocument.text-master":["odm"],"application/vnd.oasis.opendocument.text-template":["ott"],"application/vnd.oasis.opendocument.text-web":["oth"],"application/vnd.olpc-sugar":["xo"],"application/vnd.oma.dd2+xml":["dd2"],"application/vnd.openofficeorg.extension":["oxt"],"application/vnd.openxmlformats-officedocument.presentationml.presentation":["pptx"],"application/vnd.openxmlformats-officedocument.presentationml.slide":["sldx"],"application/vnd.openxmlformats-officedocument.presentationml.slideshow":["ppsx"],"application/vnd.openxmlformats-officedocument.presentationml.template":["potx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":["xlsx"],"application/vnd.openxmlformats-officedocument.spreadsheetml.template":["xltx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.document":["docx"],"application/vnd.openxmlformats-officedocument.wordprocessingml.template":["dotx"],"application/vnd.osgeo.mapguide.package":["mgp"],"application/vnd.osgi.dp":["dp"],"application/vnd.osgi.subsystem":["esa"],"application/vnd.palm":["pdb","pqa","oprc"],"application/vnd.pawaafile":["paw"],"application/vnd.pg.format":["str"],"application/vnd.pg.osasli":["ei6"],"application/vnd.picsel":["efif"],"application/vnd.pmi.widget":["wg"],"application/vnd.pocketlearn":["plf"],"application/vnd.powerbuilder6":["pbd"],"application/vnd.previewsystems.box":["box"],"application/vnd.proteus.magazine":["mgz"],"application/vnd.publishare-delta-tree":["qps"],"application/vnd.pvi.ptid1":["ptid"],"application/vnd.quark.quarkxpress":["qxd","qxt","qwd","qwt","qxl","qxb"],"application/vnd.realvnc.bed":["bed"],"application/vnd.recordare.musicxml":["mxl"],"application/vnd.recordare.musicxml+xml":["musicxml"],"application/vnd.rig.cryptonote":["cryptonote"],"application/vnd.rim.cod":["cod"],"application/vnd.rn-realmedia":["rm"],"application/vnd.rn-realmedia-vbr":["rmvb"],"application/vnd.route66.link66+xml":["link66"],"application/vnd.sailingtracker.track":["st"],"application/vnd.seemail":["see"],"application/vnd.sema":["sema"],"application/vnd.semd":["semd"],"application/vnd.semf":["semf"],"application/vnd.shana.informed.formdata":["ifm"],"application/vnd.shana.informed.formtemplate":["itp"],"application/vnd.shana.informed.interchange":["iif"],"application/vnd.shana.informed.package":["ipk"],"application/vnd.simtech-mindmapper":["twd","twds"],"application/vnd.smaf":["mmf"],"application/vnd.smart.teacher":["teacher"],"application/vnd.solent.sdkm+xml":["sdkm","sdkd"],"application/vnd.spotfire.dxp":["dxp"],"application/vnd.spotfire.sfs":["sfs"],"application/vnd.stardivision.calc":["sdc"],"application/vnd.stardivision.draw":["sda"],"application/vnd.stardivision.impress":["sdd"],"application/vnd.stardivision.math":["smf"],"application/vnd.stardivision.writer":["sdw","vor"],"application/vnd.stardivision.writer-global":["sgl"],"application/vnd.stepmania.package":["smzip"],"application/vnd.stepmania.stepchart":["sm"],"application/vnd.sun.wadl+xml":["wadl"],"application/vnd.sun.xml.calc":["sxc"],"application/vnd.sun.xml.calc.template":["stc"],"application/vnd.sun.xml.draw":["sxd"],"application/vnd.sun.xml.draw.template":["std"],"application/vnd.sun.xml.impress":["sxi"],"application/vnd.sun.xml.impress.template":["sti"],"application/vnd.sun.xml.math":["sxm"],"application/vnd.sun.xml.writer":["sxw"],"application/vnd.sun.xml.writer.global":["sxg"],"application/vnd.sun.xml.writer.template":["stw"],"application/vnd.sus-calendar":["sus","susp"],"application/vnd.svd":["svd"],"application/vnd.symbian.install":["sis","sisx"],"application/vnd.syncml+xml":["xsm"],"application/vnd.syncml.dm+wbxml":["bdm"],"application/vnd.syncml.dm+xml":["xdm"],"application/vnd.tao.intent-module-archive":["tao"],"application/vnd.tcpdump.pcap":["pcap","cap","dmp"],"application/vnd.tmobile-livetv":["tmo"],"application/vnd.trid.tpt":["tpt"],"application/vnd.triscape.mxs":["mxs"],"application/vnd.trueapp":["tra"],"application/vnd.ufdl":["ufd","ufdl"],"application/vnd.uiq.theme":["utz"],"application/vnd.umajin":["umj"],"application/vnd.unity":["unityweb"],"application/vnd.uoml+xml":["uoml"],"application/vnd.vcx":["vcx"],"application/vnd.visio":["vsd","vst","vss","vsw"],"application/vnd.visionary":["vis"],"application/vnd.vsf":["vsf"],"application/vnd.wap.wbxml":["wbxml"],"application/vnd.wap.wmlc":["wmlc"],"application/vnd.wap.wmlscriptc":["wmlsc"],"application/vnd.webturbo":["wtb"],"application/vnd.wolfram.player":["nbp"],"application/vnd.wordperfect":["wpd"],"application/vnd.wqd":["wqd"],"application/vnd.wt.stf":["stf"],"application/vnd.xara":["xar"],"application/vnd.xfdl":["xfdl"],"application/vnd.yamaha.hv-dic":["hvd"],"application/vnd.yamaha.hv-script":["hvs"],"application/vnd.yamaha.hv-voice":["hvp"],"application/vnd.yamaha.openscoreformat":["osf"],"application/vnd.yamaha.openscoreformat.osfpvg+xml":["osfpvg"],"application/vnd.yamaha.smaf-audio":["saf"],"application/vnd.yamaha.smaf-phrase":["spf"],"application/vnd.yellowriver-custom-menu":["cmp"],"application/vnd.zul":["zir","zirz"],"application/vnd.zzazz.deck+xml":["zaz"],"application/voicexml+xml":["vxml"],"application/wasm":["wasm"],"application/widget":["wgt"],"application/winhlp":["hlp"],"application/wsdl+xml":["wsdl"],"application/wspolicy+xml":["wspolicy"],"application/x-7z-compressed":["7z"],"application/x-abiword":["abw"],"application/x-ace-compressed":["ace"],"application/x-apple-diskimage":[],"application/x-arj":["arj"],"application/x-authorware-bin":["aab","x32","u32","vox"],"application/x-authorware-map":["aam"],"application/x-authorware-seg":["aas"],"application/x-bcpio":["bcpio"],"application/x-bdoc":[],"application/x-bittorrent":["torrent"],"application/x-blorb":["blb","blorb"],"application/x-bzip":["bz"],"application/x-bzip2":["bz2","boz"],"application/x-cbr":["cbr","cba","cbt","cbz","cb7"],"application/x-cdlink":["vcd"],"application/x-cfs-compressed":["cfs"],"application/x-chat":["chat"],"application/x-chess-pgn":["pgn"],"application/x-chrome-extension":["crx"],"application/x-cocoa":["cco"],"application/x-conference":["nsc"],"application/x-cpio":["cpio"],"application/x-csh":["csh"],"application/x-debian-package":["udeb"],"application/x-dgc-compressed":["dgc"],"application/x-director":["dir","dcr","dxr","cst","cct","cxt","w3d","fgd","swa"],"application/x-doom":["wad"],"application/x-dtbncx+xml":["ncx"],"application/x-dtbook+xml":["dtb"],"application/x-dtbresource+xml":["res"],"application/x-dvi":["dvi"],"application/x-envoy":["evy"],"application/x-eva":["eva"],"application/x-font-bdf":["bdf"],"application/x-font-ghostscript":["gsf"],"application/x-font-linux-psf":["psf"],"application/x-font-pcf":["pcf"],"application/x-font-snf":["snf"],"application/x-font-type1":["pfa","pfb","pfm","afm"],"application/x-freearc":["arc"],"application/x-futuresplash":["spl"],"application/x-gca-compressed":["gca"],"application/x-glulx":["ulx"],"application/x-gnumeric":["gnumeric"],"application/x-gramps-xml":["gramps"],"application/x-gtar":["gtar"],"application/x-hdf":["hdf"],"application/x-httpd-php":["php"],"application/x-install-instructions":["install"],"application/x-iso9660-image":[],"application/x-java-archive-diff":["jardiff"],"application/x-java-jnlp-file":["jnlp"],"application/x-latex":["latex"],"application/x-lua-bytecode":["luac"],"application/x-lzh-compressed":["lzh","lha"],"application/x-makeself":["run"],"application/x-mie":["mie"],"application/x-mobipocket-ebook":["prc","mobi"],"application/x-ms-application":["application"],"application/x-ms-shortcut":["lnk"],"application/x-ms-wmd":["wmd"],"application/x-ms-wmz":["wmz"],"application/x-ms-xbap":["xbap"],"application/x-msaccess":["mdb"],"application/x-msbinder":["obd"],"application/x-mscardfile":["crd"],"application/x-msclip":["clp"],"application/x-msdos-program":[],"application/x-msdownload":["com","bat"],"application/x-msmediaview":["mvb","m13","m14"],"application/x-msmetafile":["wmf","emf","emz"],"application/x-msmoney":["mny"],"application/x-mspublisher":["pub"],"application/x-msschedule":["scd"],"application/x-msterminal":["trm"],"application/x-mswrite":["wri"],"application/x-netcdf":["nc","cdf"],"application/x-ns-proxy-autoconfig":["pac"],"application/x-nzb":["nzb"],"application/x-perl":["pl","pm"],"application/x-pilot":[],"application/x-pkcs12":["p12","pfx"],"application/x-pkcs7-certificates":["p7b","spc"],"application/x-pkcs7-certreqresp":["p7r"],"application/x-rar-compressed":["rar"],"application/x-redhat-package-manager":["rpm"],"application/x-research-info-systems":["ris"],"application/x-sea":["sea"],"application/x-sh":["sh"],"application/x-shar":["shar"],"application/x-shockwave-flash":["swf"],"application/x-silverlight-app":["xap"],"application/x-sql":["sql"],"application/x-stuffit":["sit"],"application/x-stuffitx":["sitx"],"application/x-subrip":["srt"],"application/x-sv4cpio":["sv4cpio"],"application/x-sv4crc":["sv4crc"],"application/x-t3vm-image":["t3"],"application/x-tads":["gam"],"application/x-tar":["tar"],"application/x-tcl":["tcl","tk"],"application/x-tex":["tex"],"application/x-tex-tfm":["tfm"],"application/x-texinfo":["texinfo","texi"],"application/x-tgif":["obj"],"application/x-ustar":["ustar"],"application/x-virtualbox-hdd":["hdd"],"application/x-virtualbox-ova":["ova"],"application/x-virtualbox-ovf":["ovf"],"application/x-virtualbox-vbox":["vbox"],"application/x-virtualbox-vbox-extpack":["vbox-extpack"],"application/x-virtualbox-vdi":["vdi"],"application/x-virtualbox-vhd":["vhd"],"application/x-virtualbox-vmdk":["vmdk"],"application/x-wais-source":["src"],"application/x-web-app-manifest+json":["webapp"],"application/x-x509-ca-cert":["der","crt","pem"],"application/x-xfig":["fig"],"application/x-xliff+xml":["xlf"],"application/x-xpinstall":["xpi"],"application/x-xz":["xz"],"application/x-zmachine":["z1","z2","z3","z4","z5","z6","z7","z8"],"application/xaml+xml":["xaml"],"application/xcap-diff+xml":["xdf"],"application/xenc+xml":["xenc"],"application/xhtml+xml":["xhtml","xht"],"application/xml":["xml","xsl","xsd","rng"],"application/xml-dtd":["dtd"],"application/xop+xml":["xop"],"application/xproc+xml":["xpl"],"application/xslt+xml":["xslt"],"application/xspf+xml":["xspf"],"application/xv+xml":["mxml","xhvml","xvml","xvm"],"application/yang":["yang"],"application/yin+xml":["yin"],"application/zip":["zip"],"audio/3gpp":[],"audio/adpcm":["adp"],"audio/basic":["au","snd"],"audio/midi":["mid","midi","kar","rmi"],"audio/mp3":[],"audio/mp4":["m4a","mp4a"],"audio/mpeg":["mpga","mp2","mp2a","mp3","m2a","m3a"],"audio/ogg":["oga","ogg","spx"],"audio/s3m":["s3m"],"audio/silk":["sil"],"audio/vnd.dece.audio":["uva","uvva"],"audio/vnd.digital-winds":["eol"],"audio/vnd.dra":["dra"],"audio/vnd.dts":["dts"],"audio/vnd.dts.hd":["dtshd"],"audio/vnd.lucent.voice":["lvp"],"audio/vnd.ms-playready.media.pya":["pya"],"audio/vnd.nuera.ecelp4800":["ecelp4800"],"audio/vnd.nuera.ecelp7470":["ecelp7470"],"audio/vnd.nuera.ecelp9600":["ecelp9600"],"audio/vnd.rip":["rip"],"audio/wav":["wav"],"audio/wave":[],"audio/webm":["weba"],"audio/x-aac":["aac"],"audio/x-aiff":["aif","aiff","aifc"],"audio/x-caf":["caf"],"audio/x-flac":["flac"],"audio/x-m4a":[],"audio/x-matroska":["mka"],"audio/x-mpegurl":["m3u"],"audio/x-ms-wax":["wax"],"audio/x-ms-wma":["wma"],"audio/x-pn-realaudio":["ram","ra"],"audio/x-pn-realaudio-plugin":["rmp"],"audio/x-realaudio":[],"audio/x-wav":[],"audio/xm":["xm"],"chemical/x-cdx":["cdx"],"chemical/x-cif":["cif"],"chemical/x-cmdf":["cmdf"],"chemical/x-cml":["cml"],"chemical/x-csml":["csml"],"chemical/x-xyz":["xyz"],"font/collection":["ttc"],"font/otf":["otf"],"font/ttf":["ttf"],"font/woff":["woff"],"font/woff2":["woff2"],"image/apng":["apng"],"image/bmp":["bmp"],"image/cgm":["cgm"],"image/g3fax":["g3"],"image/gif":["gif"],"image/ief":["ief"],"image/jp2":["jp2","jpg2"],"image/jpeg":["jpeg","jpg","jpe"],"image/jpm":["jpm"],"image/jpx":["jpx","jpf"],"image/ktx":["ktx"],"image/png":["png"],"image/prs.btif":["btif"],"image/sgi":["sgi"],"image/svg+xml":["svg","svgz"],"image/tiff":["tiff","tif"],"image/vnd.adobe.photoshop":["psd"],"image/vnd.dece.graphic":["uvi","uvvi","uvg","uvvg"],"image/vnd.djvu":["djvu","djv"],"image/vnd.dvb.subtitle":[],"image/vnd.dwg":["dwg"],"image/vnd.dxf":["dxf"],"image/vnd.fastbidsheet":["fbs"],"image/vnd.fpx":["fpx"],"image/vnd.fst":["fst"],"image/vnd.fujixerox.edmics-mmr":["mmr"],"image/vnd.fujixerox.edmics-rlc":["rlc"],"image/vnd.ms-modi":["mdi"],"image/vnd.ms-photo":["wdp"],"image/vnd.net-fpx":["npx"],"image/vnd.wap.wbmp":["wbmp"],"image/vnd.xiff":["xif"],"image/webp":["webp"],"image/x-3ds":["3ds"],"image/x-cmu-raster":["ras"],"image/x-cmx":["cmx"],"image/x-freehand":["fh","fhc","fh4","fh5","fh7"],"image/x-icon":["ico"],"image/x-jng":["jng"],"image/x-mrsid-image":["sid"],"image/x-ms-bmp":[],"image/x-pcx":["pcx"],"image/x-pict":["pic","pct"],"image/x-portable-anymap":["pnm"],"image/x-portable-bitmap":["pbm"],"image/x-portable-graymap":["pgm"],"image/x-portable-pixmap":["ppm"],"image/x-rgb":["rgb"],"image/x-tga":["tga"],"image/x-xbitmap":["xbm"],"image/x-xpixmap":["xpm"],"image/x-xwindowdump":["xwd"],"message/rfc822":["eml","mime"],"model/gltf+json":["gltf"],"model/gltf-binary":["glb"],"model/iges":["igs","iges"],"model/mesh":["msh","mesh","silo"],"model/vnd.collada+xml":["dae"],"model/vnd.dwf":["dwf"],"model/vnd.gdl":["gdl"],"model/vnd.gtw":["gtw"],"model/vnd.mts":["mts"],"model/vnd.vtu":["vtu"],"model/vrml":["wrl","vrml"],"model/x3d+binary":["x3db","x3dbz"],"model/x3d+vrml":["x3dv","x3dvz"],"model/x3d+xml":["x3d","x3dz"],"text/cache-manifest":["appcache","manifest"],"text/calendar":["ics","ifb"],"text/coffeescript":["coffee","litcoffee"],"text/css":["css"],"text/csv":["csv"],"text/hjson":["hjson"],"text/html":["html","htm","shtml"],"text/jade":["jade"],"text/jsx":["jsx"],"text/less":["less"],"text/markdown":["markdown","md"],"text/mathml":["mml"],"text/n3":["n3"],"text/plain":["txt","text","conf","def","list","log","in","ini"],"text/prs.lines.tag":["dsc"],"text/richtext":["rtx"],"text/rtf":[],"text/sgml":["sgml","sgm"],"text/slim":["slim","slm"],"text/stylus":["stylus","styl"],"text/tab-separated-values":["tsv"],"text/troff":["t","tr","roff","man","me","ms"],"text/turtle":["ttl"],"text/uri-list":["uri","uris","urls"],"text/vcard":["vcard"],"text/vnd.curl":["curl"],"text/vnd.curl.dcurl":["dcurl"],"text/vnd.curl.mcurl":["mcurl"],"text/vnd.curl.scurl":["scurl"],"text/vnd.dvb.subtitle":["sub"],"text/vnd.fly":["fly"],"text/vnd.fmi.flexstor":["flx"],"text/vnd.graphviz":["gv"],"text/vnd.in3d.3dml":["3dml"],"text/vnd.in3d.spot":["spot"],"text/vnd.sun.j2me.app-descriptor":["jad"],"text/vnd.wap.wml":["wml"],"text/vnd.wap.wmlscript":["wmls"],"text/vtt":["vtt"],"text/x-asm":["s","asm"],"text/x-c":["c","cc","cxx","cpp","h","hh","dic"],"text/x-component":["htc"],"text/x-fortran":["f","for","f77","f90"],"text/x-handlebars-template":["hbs"],"text/x-java-source":["java"],"text/x-lua":["lua"],"text/x-markdown":["mkd"],"text/x-nfo":["nfo"],"text/x-opml":["opml"],"text/x-org":[],"text/x-pascal":["p","pas"],"text/x-processing":["pde"],"text/x-sass":["sass"],"text/x-scss":["scss"],"text/x-setext":["etx"],"text/x-sfv":["sfv"],"text/x-suse-ymp":["ymp"],"text/x-uuencode":["uu"],"text/x-vcalendar":["vcs"],"text/x-vcard":["vcf"],"text/xml":[],"text/yaml":["yaml","yml"],"video/3gpp":["3gp","3gpp"],"video/3gpp2":["3g2"],"video/h261":["h261"],"video/h263":["h263"],"video/h264":["h264"],"video/jpeg":["jpgv"],"video/jpm":["jpgm"],"video/mj2":["mj2","mjp2"],"video/mp2t":["ts"],"video/mp4":["mp4","mp4v","mpg4"],"video/mpeg":["mpeg","mpg","mpe","m1v","m2v"],"video/ogg":["ogv"],"video/quicktime":["qt","mov"],"video/vnd.dece.hd":["uvh","uvvh"],"video/vnd.dece.mobile":["uvm","uvvm"],"video/vnd.dece.pd":["uvp","uvvp"],"video/vnd.dece.sd":["uvs","uvvs"],"video/vnd.dece.video":["uvv","uvvv"],"video/vnd.dvb.file":["dvb"],"video/vnd.fvt":["fvt"],"video/vnd.mpegurl":["mxu","m4u"],"video/vnd.ms-playready.media.pyv":["pyv"],"video/vnd.uvvu.mp4":["uvu","uvvu"],"video/vnd.vivo":["viv"],"video/webm":["webm"],"video/x-f4v":["f4v"],"video/x-fli":["fli"],"video/x-flv":["flv"],"video/x-m4v":["m4v"],"video/x-matroska":["mkv","mk3d","mks"],"video/x-mng":["mng"],"video/x-ms-asf":["asf","asx"],"video/x-ms-vob":["vob"],"video/x-ms-wm":["wm"],"video/x-ms-wmv":["wmv"],"video/x-ms-wmx":["wmx"],"video/x-ms-wvx":["wvx"],"video/x-msvideo":["avi"],"video/x-sgi-movie":["movie"],"video/x-smv":["smv"],"x-conference/x-cooltalk":["ice"]}
\ No newline at end of file
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/ms/index.js b/d2d_app/node_modules/express/node_modules/send/node_modules/ms/index.js
deleted file mode 100644 (file)
index 7229750..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * Helpers.
- */
-
-var s = 1000;
-var m = s * 60;
-var h = m * 60;
-var d = h * 24;
-var w = d * 7;
-var y = d * 365.25;
-
-/**
- * Parse or format the given `val`.
- *
- * Options:
- *
- *  - `long` verbose formatting [false]
- *
- * @param {String|Number} val
- * @param {Object} [options]
- * @throws {Error} throw an error if val is not a non-empty string or a number
- * @return {String|Number}
- * @api public
- */
-
-module.exports = function(val, options) {
-  options = options || {};
-  var type = typeof val;
-  if (type === 'string' && val.length > 0) {
-    return parse(val);
-  } else if (type === 'number' && isNaN(val) === false) {
-    return options.long ? fmtLong(val) : fmtShort(val);
-  }
-  throw new Error(
-    'val is not a non-empty string or a valid number. val=' +
-      JSON.stringify(val)
-  );
-};
-
-/**
- * Parse the given `str` and return milliseconds.
- *
- * @param {String} str
- * @return {Number}
- * @api private
- */
-
-function parse(str) {
-  str = String(str);
-  if (str.length > 100) {
-    return;
-  }
-  var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
-    str
-  );
-  if (!match) {
-    return;
-  }
-  var n = parseFloat(match[1]);
-  var type = (match[2] || 'ms').toLowerCase();
-  switch (type) {
-    case 'years':
-    case 'year':
-    case 'yrs':
-    case 'yr':
-    case 'y':
-      return n * y;
-    case 'weeks':
-    case 'week':
-    case 'w':
-      return n * w;
-    case 'days':
-    case 'day':
-    case 'd':
-      return n * d;
-    case 'hours':
-    case 'hour':
-    case 'hrs':
-    case 'hr':
-    case 'h':
-      return n * h;
-    case 'minutes':
-    case 'minute':
-    case 'mins':
-    case 'min':
-    case 'm':
-      return n * m;
-    case 'seconds':
-    case 'second':
-    case 'secs':
-    case 'sec':
-    case 's':
-      return n * s;
-    case 'milliseconds':
-    case 'millisecond':
-    case 'msecs':
-    case 'msec':
-    case 'ms':
-      return n;
-    default:
-      return undefined;
-  }
-}
-
-/**
- * Short format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function fmtShort(ms) {
-  var msAbs = Math.abs(ms);
-  if (msAbs >= d) {
-    return Math.round(ms / d) + 'd';
-  }
-  if (msAbs >= h) {
-    return Math.round(ms / h) + 'h';
-  }
-  if (msAbs >= m) {
-    return Math.round(ms / m) + 'm';
-  }
-  if (msAbs >= s) {
-    return Math.round(ms / s) + 's';
-  }
-  return ms + 'ms';
-}
-
-/**
- * Long format for `ms`.
- *
- * @param {Number} ms
- * @return {String}
- * @api private
- */
-
-function fmtLong(ms) {
-  var msAbs = Math.abs(ms);
-  if (msAbs >= d) {
-    return plural(ms, msAbs, d, 'day');
-  }
-  if (msAbs >= h) {
-    return plural(ms, msAbs, h, 'hour');
-  }
-  if (msAbs >= m) {
-    return plural(ms, msAbs, m, 'minute');
-  }
-  if (msAbs >= s) {
-    return plural(ms, msAbs, s, 'second');
-  }
-  return ms + ' ms';
-}
-
-/**
- * Pluralization helper.
- */
-
-function plural(ms, msAbs, n, name) {
-  var isPlural = msAbs >= n * 1.5;
-  return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
-}
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/ms/package.json b/d2d_app/node_modules/express/node_modules/send/node_modules/ms/package.json
deleted file mode 100644 (file)
index 431855c..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-{
-  "_from": "ms@2.1.1",
-  "_id": "ms@2.1.1",
-  "_inBundle": false,
-  "_integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
-  "_location": "/send/ms",
-  "_phantomChildren": {},
-  "_requested": {
-    "type": "version",
-    "registry": true,
-    "raw": "ms@2.1.1",
-    "name": "ms",
-    "escapedName": "ms",
-    "rawSpec": "2.1.1",
-    "saveSpec": null,
-    "fetchSpec": "2.1.1"
-  },
-  "_requiredBy": [
-    "/send"
-  ],
-  "_resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
-  "_shasum": "30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a",
-  "_spec": "ms@2.1.1",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/send",
-  "bugs": {
-    "url": "https://github.com/zeit/ms/issues"
-  },
-  "bundleDependencies": false,
-  "deprecated": false,
-  "description": "Tiny millisecond conversion utility",
-  "devDependencies": {
-    "eslint": "4.12.1",
-    "expect.js": "0.3.1",
-    "husky": "0.14.3",
-    "lint-staged": "5.0.0",
-    "mocha": "4.0.1"
-  },
-  "eslintConfig": {
-    "extends": "eslint:recommended",
-    "env": {
-      "node": true,
-      "es6": true
-    }
-  },
-  "files": [
-    "index.js"
-  ],
-  "homepage": "https://github.com/zeit/ms#readme",
-  "license": "MIT",
-  "lint-staged": {
-    "*.js": [
-      "npm run lint",
-      "prettier --single-quote --write",
-      "git add"
-    ]
-  },
-  "main": "./index",
-  "name": "ms",
-  "repository": {
-    "type": "git",
-    "url": "git+https://github.com/zeit/ms.git"
-  },
-  "scripts": {
-    "lint": "eslint lib/* bin/*",
-    "precommit": "lint-staged",
-    "test": "mocha tests.js"
-  },
-  "version": "2.1.1"
-}
diff --git a/d2d_app/node_modules/express/node_modules/send/node_modules/ms/readme.md b/d2d_app/node_modules/express/node_modules/send/node_modules/ms/readme.md
deleted file mode 100644 (file)
index bb76729..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-# ms
-
-[![Build Status](https://travis-ci.org/zeit/ms.svg?branch=master)](https://travis-ci.org/zeit/ms)
-[![Slack Channel](http://zeit-slackin.now.sh/badge.svg)](https://zeit.chat/)
-
-Use this package to easily convert various time formats to milliseconds.
-
-## Examples
-
-```js
-ms('2 days')  // 172800000
-ms('1d')      // 86400000
-ms('10h')     // 36000000
-ms('2.5 hrs') // 9000000
-ms('2h')      // 7200000
-ms('1m')      // 60000
-ms('5s')      // 5000
-ms('1y')      // 31557600000
-ms('100')     // 100
-ms('-3 days') // -259200000
-ms('-1h')     // -3600000
-ms('-200')    // -200
-```
-
-### Convert from Milliseconds
-
-```js
-ms(60000)             // "1m"
-ms(2 * 60000)         // "2m"
-ms(-3 * 60000)        // "-3m"
-ms(ms('10 hours'))    // "10h"
-```
-
-### Time Format Written-Out
-
-```js
-ms(60000, { long: true })             // "1 minute"
-ms(2 * 60000, { long: true })         // "2 minutes"
-ms(-3 * 60000, { long: true })        // "-3 minutes"
-ms(ms('10 hours'), { long: true })    // "10 hours"
-```
-
-## Features
-
-- Works both in [Node.js](https://nodejs.org) and in the browser
-- If a number is supplied to `ms`, a string with a unit is returned
-- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`)
-- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned
-
-## Related Packages
-
-- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time.
-
-## Caught a Bug?
-
-1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
-2. Link the package to the global module directory: `npm link`
-3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms!
-
-As always, you can run the tests using: `npm test`
diff --git a/d2d_app/node_modules/has-flag/index.js b/d2d_app/node_modules/has-flag/index.js
new file mode 100644 (file)
index 0000000..5139728
--- /dev/null
@@ -0,0 +1,8 @@
+'use strict';
+module.exports = (flag, argv) => {
+       argv = argv || process.argv;
+       const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
+       const pos = argv.indexOf(prefix + flag);
+       const terminatorPos = argv.indexOf('--');
+       return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
+};
diff --git a/d2d_app/node_modules/has-flag/license b/d2d_app/node_modules/has-flag/license
new file mode 100644 (file)
index 0000000..e7af2f7
--- /dev/null
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/has-flag/package.json b/d2d_app/node_modules/has-flag/package.json
new file mode 100644 (file)
index 0000000..9c6958d
--- /dev/null
@@ -0,0 +1,76 @@
+{
+  "_from": "has-flag@^3.0.0",
+  "_id": "has-flag@3.0.0",
+  "_inBundle": false,
+  "_integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+  "_location": "/has-flag",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "has-flag@^3.0.0",
+    "name": "has-flag",
+    "escapedName": "has-flag",
+    "rawSpec": "^3.0.0",
+    "saveSpec": null,
+    "fetchSpec": "^3.0.0"
+  },
+  "_requiredBy": [
+    "/supports-color"
+  ],
+  "_resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+  "_shasum": "b5d454dc2199ae225699f3467e5a07f3b955bafd",
+  "_spec": "has-flag@^3.0.0",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/supports-color",
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "sindresorhus@gmail.com",
+    "url": "sindresorhus.com"
+  },
+  "bugs": {
+    "url": "https://github.com/sindresorhus/has-flag/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Check if argv has a specific flag",
+  "devDependencies": {
+    "ava": "*",
+    "xo": "*"
+  },
+  "engines": {
+    "node": ">=4"
+  },
+  "files": [
+    "index.js"
+  ],
+  "homepage": "https://github.com/sindresorhus/has-flag#readme",
+  "keywords": [
+    "has",
+    "check",
+    "detect",
+    "contains",
+    "find",
+    "flag",
+    "cli",
+    "command-line",
+    "argv",
+    "process",
+    "arg",
+    "args",
+    "argument",
+    "arguments",
+    "getopt",
+    "minimist",
+    "optimist"
+  ],
+  "license": "MIT",
+  "name": "has-flag",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/sindresorhus/has-flag.git"
+  },
+  "scripts": {
+    "test": "xo && ava"
+  },
+  "version": "3.0.0"
+}
diff --git a/d2d_app/node_modules/has-flag/readme.md b/d2d_app/node_modules/has-flag/readme.md
new file mode 100644 (file)
index 0000000..677893c
--- /dev/null
@@ -0,0 +1,70 @@
+# has-flag [![Build Status](https://travis-ci.org/sindresorhus/has-flag.svg?branch=master)](https://travis-ci.org/sindresorhus/has-flag)
+
+> Check if [`argv`](https://nodejs.org/docs/latest/api/process.html#process_process_argv) has a specific flag
+
+Correctly stops looking after an `--` argument terminator.
+
+
+## Install
+
+```
+$ npm install has-flag
+```
+
+
+## Usage
+
+```js
+// foo.js
+const hasFlag = require('has-flag');
+
+hasFlag('unicorn');
+//=> true
+
+hasFlag('--unicorn');
+//=> true
+
+hasFlag('f');
+//=> true
+
+hasFlag('-f');
+//=> true
+
+hasFlag('foo=bar');
+//=> true
+
+hasFlag('foo');
+//=> false
+
+hasFlag('rainbow');
+//=> false
+```
+
+```
+$ node foo.js -f --unicorn --foo=bar -- --rainbow
+```
+
+
+## API
+
+### hasFlag(flag, [argv])
+
+Returns a boolean for whether the flag exists.
+
+#### flag
+
+Type: `string`
+
+CLI flag to look for. The `--` prefix is optional.
+
+#### argv
+
+Type: `string[]`<br>
+Default: `process.argv`
+
+CLI arguments.
+
+
+## License
+
+MIT © [Sindre Sorhus](https://sindresorhus.com)
diff --git a/d2d_app/node_modules/jake/Makefile b/d2d_app/node_modules/jake/Makefile
new file mode 100644 (file)
index 0000000..3d0574e
--- /dev/null
@@ -0,0 +1,44 @@
+#
+# Jake JavaScript build tool
+# Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+.PHONY: all build install clean uninstall
+
+PREFIX=/usr/local
+DESTDIR=
+
+all: build
+
+build:
+       @echo 'Jake built.'
+
+install:
+       @mkdir -p $(DESTDIR)$(PREFIX)/bin && \
+    mkdir -p $(DESTDIR)$(PREFIX)/lib/node_modules/jake && \
+    mkdir -p ./node_modules && \
+    npm install utilities minimatch && \
+               cp -R ./* $(DESTDIR)$(PREFIX)/lib/node_modules/jake/ && \
+               ln -snf ../lib/node_modules/jake/bin/cli.js $(DESTDIR)$(PREFIX)/bin/jake && \
+               chmod 755 $(DESTDIR)$(PREFIX)/lib/node_modules/jake/bin/cli.js && \
+               echo 'Jake installed.'
+
+clean:
+       @true
+
+uninstall:
+       @rm -f $(DESTDIR)$(PREFIX)/bin/jake && \
+               rm -fr $(DESTDIR)$(PREFIX)/lib/node_modules/jake/ && \
+               echo 'Jake uninstalled.'
diff --git a/d2d_app/node_modules/jake/README.md b/d2d_app/node_modules/jake/README.md
new file mode 100644 (file)
index 0000000..e938850
--- /dev/null
@@ -0,0 +1,17 @@
+### Jake -- the JavaScript build tool for Node.js
+
+[![Build Status](https://travis-ci.org/jakejs/jake.svg?branch=master)](https://travis-ci.org/jakejs/jake)
+
+Documentation site at [http://jakejs.com](http://jakejs.com/)
+
+### Contributing
+1. [Install node](http://nodejs.org/#download).
+2. Clone this repository `$ git clone git@github.com:jakejs/jake.git`.
+3. Install dependencies `$ npm install`.
+4. Run tests with `$ npm test`.
+5. Start Hacking!
+
+### License
+
+Licensed under the Apache License, Version 2.0
+(<http://www.apache.org/licenses/LICENSE-2.0>)
diff --git a/d2d_app/node_modules/jake/bin/bash_completion.sh b/d2d_app/node_modules/jake/bin/bash_completion.sh
new file mode 100755 (executable)
index 0000000..bb25995
--- /dev/null
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+# http://stackoverflow.com/a/246128
+SOURCE="${BASH_SOURCE[0]}"
+while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
+  DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+  SOURCE="$(readlink "$SOURCE")"
+  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
+done
+JAKE_BIN_DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
+
+# http://stackoverflow.com/a/12495480
+# http://stackoverflow.com/a/28647824
+_auto_jake()
+{
+    local cur
+    local -a COMPGEN=()
+    _get_comp_words_by_ref -n : -c cur
+    
+    # run auto-completions in jake via our auto_complete.js wrapper
+    local -a auto_complete_info=( $(export COMP_LINE="${COMP_LINE}" && ${JAKE_BIN_DIR}/auto_complete.js "$cur" "${3}") )
+    # check reply flag
+    local reply_flag="${auto_complete_info[0]}"
+    if [[ "${reply_flag}" == "no-complete" ]]; then
+        return 1
+    fi
+    local auto_completions=("${auto_complete_info[@]:1}")
+    COMPGEN=( $(compgen -W "${auto_completions[*]}" -- "$cur") )
+    COMPREPLY=( "${COMPGEN[@]}" )
+    
+    __ltrim_colon_completions "$cur"
+    
+    # do we need another space??
+    if [[ "${reply_flag}" == "yes-space" ]]; then
+        COMPREPLY=( "${COMPGEN[@]}" " " )
+    fi
+    
+    return 0
+} 
+
+complete -o default -F _auto_jake jake
diff --git a/d2d_app/node_modules/jake/bin/cli.js b/d2d_app/node_modules/jake/bin/cli.js
new file mode 100755 (executable)
index 0000000..9f68abb
--- /dev/null
@@ -0,0 +1,31 @@
+#!/usr/bin/env node
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+// Try to load a local jake
+try {
+  require(`${ process.cwd() }/node_modules/jake`);
+}
+// If that fails, likely running globally
+catch(e) {
+  require('../lib/jake');
+}
+
+var args = process.argv.slice(2);
+
+jake.run.apply(jake, args);
diff --git a/d2d_app/node_modules/jake/jakefile.js b/d2d_app/node_modules/jake/jakefile.js
new file mode 100644 (file)
index 0000000..b0ae79b
--- /dev/null
@@ -0,0 +1,105 @@
+let fs = require('fs')
+let path = require('path');
+let proc = require('child_process');
+
+const PROJECT_DIR = process.cwd();
+process.env.PROJECT_DIR = PROJECT_DIR;
+
+namespace('doc', function () {
+  task('generate', ['doc:clobber'], function () {
+    var cmd = '../node-jsdoc-toolkit/app/run.js -n -r=100 ' +
+        '-t=../node-jsdoc-toolkit/templates/codeview -d=./doc/ ./lib';
+    jake.logger.log('Generating docs ...');
+    jake.exec([cmd], function () {
+      jake.logger.log('Done.');
+      complete();
+    });
+  }, {async: true});
+
+  task('clobber', function () {
+    var cmd = 'rm -fr ./doc/*';
+    jake.exec([cmd], function () {
+      jake.logger.log('Clobbered old docs.');
+      complete();
+    });
+  }, {async: true});
+
+});
+
+desc('Generate docs for Jake');
+task('doc', ['doc:generate']);
+
+npmPublishTask('jake', function () {
+  this.packageFiles.include([
+    'Makefile',
+    'jakefile.js',
+    'README.md',
+    'package.json',
+    'usage.txt',
+    'lib/**',
+    'bin/**',
+    'test/**'
+    ]);
+  this.packageFiles.exclude([
+    'test/tmp'
+  ]);
+});
+
+jake.Task['publish:package'].directory = PROJECT_DIR;
+
+namespace('test', function () {
+
+  let integrationTest = task('integration', ['publish:package'], async function () {
+    let pkg = JSON.parse(fs.readFileSync(`${PROJECT_DIR}/package.json`).toString());
+    let version = pkg.version;
+
+    proc.execSync('rm -rf ./node_modules');
+    // Install from the actual package, run tests from the packaged binary
+    proc.execSync(`mkdir -p node_modules/.bin && mv ${PROJECT_DIR}/pkg/jake-v` +
+        `${version} node_modules/jake && ln -s ${process.cwd()}` +
+      '/node_modules/jake/bin/cli.js ./node_modules/.bin/jake');
+
+    let testArgs = [];
+    if (process.env.filter) {
+      testArgs.push(process.env.filter);
+    }
+    else {
+      testArgs.push('*.js');
+    }
+    let spawned = proc.spawn(`${PROJECT_DIR}/node_modules/.bin/mocha`, testArgs, {
+      stdio: 'inherit'
+    });
+    return new Promise((resolve, reject) => {
+      spawned.on('exit', () => {
+        if (!(process.env.noclobber || process.env.noClobber)) {
+          proc.execSync('rm -rf tmp_publish && rm -rf package.json' +
+              ' && rm -rf package-lock.json && rm -rf node_modules');
+          // Rather than invoking 'clobber' task
+          jake.rmRf(`${PROJECT_DIR}/pkg`);
+        }
+        resolve();
+      });
+    });
+
+  });
+
+  integrationTest.directory = `${PROJECT_DIR}/test/integration`;
+
+  let unitTest = task('unit', async function () {
+    let testArgs = [];
+    if (process.env.filter) {
+      testArgs.push(process.env.filter);
+    }
+    else {
+      testArgs.push('*.js');
+    }
+    let spawned = proc.spawn(`${PROJECT_DIR}/node_modules/.bin/mocha`, testArgs, {
+      stdio: 'inherit'
+    });
+  });
+
+  unitTest.directory = `${PROJECT_DIR}/test/unit`;
+});
+
+desc('Runs all tests');
+task('test', ['test:unit', 'test:integration']);
diff --git a/d2d_app/node_modules/jake/lib/api.js b/d2d_app/node_modules/jake/lib/api.js
new file mode 100644 (file)
index 0000000..9f09140
--- /dev/null
@@ -0,0 +1,409 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+let { uuid } = require('./utils');
+
+let api = new (function () {
+  /**
+    @name task
+    @static
+    @function
+    @description Creates a Jake Task
+    `
+    @param {String} name The name of the Task
+    @param {Array} [prereqs] Prerequisites to be run before this task
+    @param {Function} [action] The action to perform for this task
+    @param {Object} [opts]
+      @param {Boolean} [opts.asyc=false] Perform this task asynchronously.
+      If you flag a task with this option, you must call the global
+      `complete` method inside the task's action, for execution to proceed
+      to the next task.
+
+    @example
+    desc('This is the default task.');
+    task('default', function (params) {
+      console.log('This is the default task.');
+    });
+
+    desc('This task has prerequisites.');
+    task('hasPrereqs', ['foo', 'bar', 'baz'], function (params) {
+      console.log('Ran some prereqs first.');
+    });
+
+    desc('This is an asynchronous task.');
+    task('asyncTask', function () {
+      setTimeout(complete, 1000);
+    }, {async: true});
+   */
+  this.task = function (name, prereqs, action, opts) {
+    let args = Array.prototype.slice.call(arguments);
+    let createdTask;
+    args.unshift('task');
+    createdTask = jake.createTask.apply(global, args);
+    jake.currentTaskDescription = null;
+    return createdTask;
+  };
+
+  /**
+    @name rule
+    @static
+    @function
+    @description Creates a Jake Suffix Rule
+    `
+    @param {String} pattern The suffix name of the objective
+    @param {String} source The suffix name of the objective
+    @param {Array} [prereqs] Prerequisites to be run before this task
+    @param {Function} [action] The action to perform for this task
+    @param {Object} [opts]
+      @param {Boolean} [opts.asyc=false] Perform this task asynchronously.
+      If you flag a task with this option, you must call the global
+      `complete` method inside the task's action, for execution to proceed
+      to the next task.
+    @example
+    desc('This is a rule, which does not support namespace or pattern.');
+    rule('.o', '.c', {async: true}, function () {
+      let cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This rule has prerequisites.');
+    rule('.o', '.c', ['util.h'], {async: true}, function () {
+      let cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This is a rule with patterns.');
+    rule('%.o', '%.c', {async: true}, function () {
+      let cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This is another rule with patterns.');
+    rule('obj/%.o', 'src/%.c', {async: true}, function () {
+      let cmd = util.format('gcc -o %s %s', this.name, this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This is an example with chain rules.');
+    rule('%.pdf', '%.dvi', {async: true}, function () {
+      let cmd = util.format('dvipdfm %s',this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    rule('%.dvi', '%.tex', {async: true}, function () {
+      let cmd = util.format('latex %s',this.source);
+      jake.exec([cmd], function () {
+        complete();
+      }, {printStdout: true});
+    });
+
+    desc('This rule has a namespace.');
+    task('default', ['debug:obj/main.o]);
+
+    namespace('debug', {async: true}, function() {
+      rule('obj/%.o', 'src/%.c', function () {
+        // ...
+      });
+    }
+   */
+  this.rule = function () {
+    let args = Array.prototype.slice.call(arguments);
+    let arg;
+    let pattern = args.shift();
+    let source = args.shift();
+    let prereqs = [];
+    let action = function () {};
+    let opts = {};
+    let key = pattern.toString(); // May be a RegExp
+
+    while ((arg = args.shift())) {
+      if (typeof arg == 'function') {
+        action = arg;
+      }
+      else if (Array.isArray(arg)) {
+        prereqs = arg;
+      }
+      else {
+        opts = arg;
+      }
+    }
+
+    jake.currentNamespace.rules[key] = new jake.Rule({
+      pattern: pattern,
+      source: source,
+      prereqs: prereqs,
+      action: action,
+      opts: opts,
+      desc: jake.currentTaskDescription,
+      ns: jake.currentNamespace
+    });
+    jake.currentTaskDescription = null;
+  };
+
+  /**
+    @name directory
+    @static
+    @function
+    @description Creates a Jake DirectoryTask. Can be used as a prerequisite
+    for FileTasks, or for simply ensuring a directory exists for use with a
+    Task's action.
+    `
+    @param {String} name The name of the DiretoryTask
+
+    @example
+
+    // Creates the package directory for distribution
+    directory('pkg');
+   */
+  this.directory = function (name) {
+    let args = Array.prototype.slice.call(arguments);
+    let createdTask;
+    args.unshift('directory');
+    createdTask = jake.createTask.apply(global, args);
+    jake.currentTaskDescription = null;
+    return createdTask;
+  };
+
+  /**
+    @name file
+    @static
+    @function
+    @description Creates a Jake FileTask.
+    `
+    @param {String} name The name of the FileTask
+    @param {Array} [prereqs] Prerequisites to be run before this task
+    @param {Function} [action] The action to create this file, if it doesn't
+    exist already.
+    @param {Object} [opts]
+      @param {Array} [opts.asyc=false] Perform this task asynchronously.
+      If you flag a task with this option, you must call the global
+      `complete` method inside the task's action, for execution to proceed
+      to the next task.
+
+   */
+  this.file = function (name, prereqs, action, opts) {
+    let args = Array.prototype.slice.call(arguments);
+    let createdTask;
+    args.unshift('file');
+    createdTask = jake.createTask.apply(global, args);
+    jake.currentTaskDescription = null;
+    return createdTask;
+  };
+
+  /**
+    @name desc
+    @static
+    @function
+    @description Creates a description for a Jake Task (or FileTask,
+    DirectoryTask). When invoked, the description that iscreated will
+    be associated with whatever Task is created next.
+    `
+    @param {String} description The description for the Task
+   */
+  this.desc = function (description) {
+    jake.currentTaskDescription = description;
+  };
+
+  /**
+    @name namespace
+    @static
+    @function
+    @description Creates a namespace which allows logical grouping
+    of tasks, and prevents name-collisions with task-names. Namespaces
+    can be nested inside of other namespaces.
+    `
+    @param {String} name The name of the namespace
+    @param {Function} scope The enclosing scope for the namespaced tasks
+
+    @example
+    namespace('doc', function () {
+      task('generate', ['doc:clobber'], function () {
+        // Generate some docs
+      });
+
+      task('clobber', function () {
+        // Clobber the doc directory first
+      });
+    });
+   */
+  this.namespace = function (name, closure) {
+    let curr = jake.currentNamespace;
+    let ns = curr.childNamespaces[name] || new jake.Namespace(name, curr);
+    let fn = closure || function () {};
+    curr.childNamespaces[name] = ns;
+    jake.currentNamespace = ns;
+    fn();
+    jake.currentNamespace = curr;
+    jake.currentTaskDescription = null;
+    return ns;
+  };
+
+  /**
+    @name complete
+    @static
+    @function
+    @description Completes an asynchronous task, allowing Jake's
+    execution to proceed to the next task. Calling complete globally or without
+    arguments completes the last task on the invocationChain. If you use parallel
+    execution of prereqs this will probably complete a wrong task. You should call this
+    function with this task as the first argument, before the optional return value.
+    Alternatively you can call task.complete()
+    `
+    @example
+    task('generate', ['doc:clobber'], function () {
+      exec('./generate_docs.sh', function (err, stdout, stderr) {
+        if (err || stderr) {
+          fail(err || stderr);
+        }
+        else {
+          console.log(stdout);
+          complete();
+        }
+      });
+    }, {async: true});
+   */
+  this.complete = function (task, val) {
+    //this should detect if the first arg is a task, but I guess it should be more thorough
+    if(task && task. _currentPrereqIndex >=0 ) {
+      task.complete(val);
+    }
+    else {
+      val = task;
+      if(jake._invocationChain.length > 0) {
+        jake._invocationChain[jake._invocationChain.length-1].complete(val);
+      }
+    }
+  };
+
+  /**
+    @name fail
+    @static
+    @function
+    @description Causes Jake execution to abort with an error.
+    Allows passing an optional error code, which will be used to
+    set the exit-code of exiting process.
+    `
+    @param {Error|String} err The error to thow when aborting execution.
+    If this argument is an Error object, it will simply be thrown. If
+    a String, it will be used as the error-message. (If it is a multi-line
+    String, the first line will be used as the Error message, and the
+    remaining lines will be used as the error-stack.)
+
+    @example
+    task('createTests, function () {
+      if (!fs.existsSync('./tests')) {
+        fail('Test directory does not exist.');
+      }
+      else {
+        // Do some testing stuff ...
+      }
+    });
+   */
+  this.fail = function (err, code) {
+    let msg;
+    let errObj;
+    if (code) {
+      jake.errorCode = code;
+    }
+    if (err) {
+      if (typeof err == 'string') {
+        // Use the initial or only line of the error as the error-message
+        // If there was a multi-line error, use the rest as the stack
+        msg = err.split('\n');
+        errObj = new Error(msg.shift());
+        if (msg.length) {
+          errObj.stack = msg.join('\n');
+        }
+        throw errObj;
+      }
+      else if (err instanceof Error) {
+        throw err;
+      }
+      else {
+        throw new Error(err.toString());
+      }
+    }
+    else {
+      throw new Error();
+    }
+  };
+
+  this.packageTask = function (name, version, prereqs, definition) {
+    return new jake.PackageTask(name, version, prereqs, definition);
+  };
+
+  this.publishTask = function (name, prereqs, opts, definition) {
+    return new jake.PublishTask(name, prereqs, opts, definition);
+  };
+
+  // Backward-compat
+  this.npmPublishTask = function (name, prereqs, opts, definition) {
+    return new jake.PublishTask(name, prereqs, opts, definition);
+  };
+
+  this.testTask = function () {
+    let ctor = function () {};
+    let t;
+    ctor.prototype = jake.TestTask.prototype;
+    t = new ctor();
+    jake.TestTask.apply(t, arguments);
+    return t;
+  };
+
+  this.setTaskTimeout = function (t) {
+    this._taskTimeout = t;
+  };
+
+  this.setSeriesAutoPrefix = function (prefix) {
+    this._seriesAutoPrefix = prefix;
+  };
+
+  this.series = function (...args) {
+    let prereqs = args.map((arg) => {
+      let name = (this._seriesAutoPrefix || '') + arg.name;
+      jake.task(name, arg);
+      return name;
+    });
+    let seriesName = uuid();
+    let seriesTask = jake.task(seriesName, prereqs);
+    seriesTask._internal = true;
+    let res = function () {
+      return new Promise((resolve) => {
+        seriesTask.invoke();
+        seriesTask.on('complete', (val) => {
+          resolve(val);
+        });
+      });
+    };
+    Object.defineProperty(res, 'name', {value: uuid(),
+      writable: false});
+    return res;
+  };
+
+})();
+
+module.exports = api;
diff --git a/d2d_app/node_modules/jake/lib/jake.js b/d2d_app/node_modules/jake/lib/jake.js
new file mode 100644 (file)
index 0000000..a463163
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+if (!global.jake) {
+
+  let EventEmitter = require('events').EventEmitter;
+  // And so it begins
+  global.jake = new EventEmitter();
+
+  let fs = require('fs');
+  let chalk = require('chalk');
+  let taskNs = require('./task');
+  let Task = taskNs.Task;
+  let FileTask = taskNs.FileTask;
+  let DirectoryTask = taskNs.DirectoryTask;
+  let Rule = require('./rule').Rule;
+  let Namespace = require('./namespace').Namespace;
+  let RootNamespace = require('./namespace').RootNamespace;
+  let api = require('./api');
+  let utils = require('./utils');
+  let Program = require('./program').Program;
+  let loader = require('./loader')();
+  let pkg = JSON.parse(fs.readFileSync(__dirname + '/../package.json').toString());
+
+  const MAX_RULE_RECURSION_LEVEL = 16;
+
+  // Globalize jake and top-level API methods (e.g., `task`, `desc`)
+  Object.assign(global, api);
+
+  // Copy utils onto base jake
+  jake.logger = utils.logger;
+  jake.exec = utils.exec;
+
+  // File utils should be aliased directly on base jake as well
+  Object.assign(jake, utils.file);
+
+  // Also add top-level API methods to exported object for those who don't want to
+  // use the globals (`file` here will overwrite the 'file' utils namespace)
+  Object.assign(jake, api);
+
+  Object.assign(jake, new (function () {
+
+    this._invocationChain = [];
+    this._taskTimeout = 30000;
+
+    // Public properties
+    // =================
+    this.version = pkg.version;
+    // Used when Jake exits with a specific error-code
+    this.errorCode = null;
+    // Loads Jakefiles/jakelibdirs
+    this.loader = loader;
+    // The root of all ... namespaces
+    this.rootNamespace = new RootNamespace();
+    // Non-namespaced tasks are placed into the default
+    this.defaultNamespace = this.rootNamespace;
+    // Start in the default
+    this.currentNamespace = this.defaultNamespace;
+    // Saves the description created by a 'desc' call that prefaces a
+    // 'task' call that defines a task.
+    this.currentTaskDescription = null;
+    this.program = new Program();
+    this.FileList = require('filelist').FileList;
+    this.PackageTask = require('./package_task').PackageTask;
+    this.PublishTask = require('./publish_task').PublishTask;
+    this.TestTask = require('./test_task').TestTask;
+    this.Task = Task;
+    this.FileTask = FileTask;
+    this.DirectoryTask = DirectoryTask;
+    this.Namespace = Namespace;
+    this.Rule = Rule;
+
+    this.parseAllTasks = function () {
+      let _parseNs = function (ns) {
+        let nsTasks = ns.tasks;
+        let nsNamespaces = ns.childNamespaces;
+        for (let q in nsTasks) {
+          let nsTask = nsTasks[q];
+          jake.Task[nsTask.fullName] = nsTask;
+        }
+        for (let p in nsNamespaces) {
+          let nsNamespace = nsNamespaces[p];
+          _parseNs(nsNamespace);
+        }
+      };
+      _parseNs(jake.defaultNamespace);
+    };
+
+    /**
+     * Displays the list of descriptions avaliable for tasks defined in
+     * a Jakefile
+     */
+    this.showAllTaskDescriptions = function (f) {
+      let p;
+      let maxTaskNameLength = 0;
+      let task;
+      let padding;
+      let name;
+      let descr;
+      let filter = typeof f == 'string' ? f : null;
+
+      for (p in jake.Task) {
+        if (!Object.prototype.hasOwnProperty.call(jake.Task, p)) {
+          continue;
+        }
+        if (filter && p.indexOf(filter) == -1) {
+          continue;
+        }
+        task = jake.Task[p];
+        // Record the length of the longest task name -- used for
+        // pretty alignment of the task descriptions
+        if (task.description) {
+          maxTaskNameLength = p.length > maxTaskNameLength ?
+            p.length : maxTaskNameLength;
+        }
+      }
+      // Print out each entry with descriptions neatly aligned
+      for (p in jake.Task) {
+        if (!Object.prototype.hasOwnProperty.call(jake.Task, p)) {
+          continue;
+        }
+        if (filter && p.indexOf(filter) == -1) {
+          continue;
+        }
+        task = jake.Task[p];
+
+        //name = '\033[32m' + p + '\033[39m ';
+        name = chalk.green(p);
+
+        descr = task.description;
+        if (descr) {
+          descr = chalk.gray('# ' + descr);
+
+          // Create padding-string with calculated length
+          padding = (new Array(maxTaskNameLength - p.length + 2)).join(' ');
+
+          console.log('jake ' + name + padding + descr);
+        }
+      }
+    };
+
+    this.createTask = function () {
+      let args = Array.prototype.slice.call(arguments);
+      let arg;
+      let obj;
+      let task;
+      let type;
+      let name;
+      let action;
+      let opts = {};
+      let prereqs = [];
+
+      type = args.shift();
+
+      // name, [deps], [action]
+      // Name (string) + deps (array) format
+      if (typeof args[0] == 'string') {
+        name = args.shift();
+        if (Array.isArray(args[0])) {
+          prereqs = args.shift();
+        }
+      }
+      // name:deps, [action]
+      // Legacy object-literal syntax, e.g.: {'name': ['depA', 'depB']}
+      else {
+        obj = args.shift();
+        for (let p in obj) {
+          prereqs = prereqs.concat(obj[p]);
+          name = p;
+        }
+      }
+
+      // Optional opts/callback or callback/opts
+      while ((arg = args.shift())) {
+        if (typeof arg == 'function') {
+          action = arg;
+        }
+        else {
+          opts = Object.assign(Object.create(null), arg);
+        }
+      }
+
+      task = jake.currentNamespace.resolveTask(name);
+      if (task && !action) {
+        // Task already exists and no action, just update prereqs, and return it.
+        task.prereqs = task.prereqs.concat(prereqs);
+        return task;
+      }
+
+      switch (type) {
+      case 'directory':
+        action = function () {
+          jake.mkdirP(name);
+        };
+        task = new DirectoryTask(name, prereqs, action, opts);
+        break;
+      case 'file':
+        task = new FileTask(name, prereqs, action, opts);
+        break;
+      default:
+        task = new Task(name, prereqs, action, opts);
+      }
+
+      jake.currentNamespace.addTask(task);
+
+      if (jake.currentTaskDescription) {
+        task.description = jake.currentTaskDescription;
+        jake.currentTaskDescription = null;
+      }
+
+      // FIXME: Should only need to add a new entry for the current
+      // task-definition, not reparse the entire structure
+      jake.parseAllTasks();
+
+      return task;
+    };
+
+    this.attemptRule = function (name, ns, level) {
+      let prereqRule;
+      let prereq;
+      if (level > MAX_RULE_RECURSION_LEVEL) {
+        return null;
+      }
+      // Check Rule
+      prereqRule = ns.matchRule(name);
+      if (prereqRule) {
+        prereq = prereqRule.createTask(name, level);
+      }
+      return prereq || null;
+    };
+
+    this.createPlaceholderFileTask = function (name, namespace) {
+      let parsed = name.split(':');
+      let filePath = parsed.pop(); // Strip any namespace
+      let task;
+
+      task = namespace.resolveTask(name);
+
+      // If there's not already an existing dummy FileTask for it,
+      // create one
+      if (!task) {
+        // Create a dummy FileTask only if file actually exists
+        if (fs.existsSync(filePath)) {
+          task = new jake.FileTask(filePath);
+          task.dummy = true;
+          let ns;
+          if (parsed.length) {
+            ns = namespace.resolveNamespace(parsed.join(':'));
+          }
+          else {
+            ns = namespace;
+          }
+          if (!namespace) {
+            throw new Error('Invalid namespace, cannot add FileTask');
+          }
+          ns.addTask(task);
+          // Put this dummy Task in the global Tasks list so
+          // modTime will be eval'd correctly
+          jake.Task[`${ns.path}:${filePath}`] = task;
+        }
+      }
+
+      return task || null;
+    };
+
+
+    this.run = function () {
+      let args = Array.prototype.slice.call(arguments);
+      let program = this.program;
+      let loader = this.loader;
+      let preempt;
+      let opts;
+
+      program.parseArgs(args);
+      program.init();
+
+      preempt = program.firstPreemptiveOption();
+      if (preempt) {
+        preempt();
+      }
+      else {
+        opts = program.opts;
+        // jakefile flag set but no jakefile yet
+        if (opts.autocomplete && opts.jakefile === true) {
+          process.stdout.write('no-complete');
+          return;
+        }
+        // Load Jakefile and jakelibdir files
+        let jakefileLoaded = loader.loadFile(opts.jakefile);
+        let jakelibdirLoaded = loader.loadDirectory(opts.jakelibdir);
+
+        if(!jakefileLoaded && !jakelibdirLoaded && !opts.autocomplete) {
+          fail('No Jakefile. Specify a valid path with -f/--jakefile, ' +
+              'or place one in the current directory.');
+        }
+
+        program.run();
+      }
+    };
+
+  })());
+}
+
+module.exports = jake;
diff --git a/d2d_app/node_modules/jake/lib/loader.js b/d2d_app/node_modules/jake/lib/loader.js
new file mode 100644 (file)
index 0000000..02ad262
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+let path = require('path');
+let fs = require('fs');
+let existsSync = fs.existsSync;
+let utils = require('./utils');
+
+// Files like jakelib/foobar.jake.js
+const JAKELIB_FILE_PAT = /\.jake$|\.js$/;
+const SUPPORTED_EXTENSIONS = {
+  'js': null,
+  'coffee': function () {
+    try {
+      let cs = require('coffeescript');
+      if (typeof cs.register == 'function') {
+        cs.register();
+      }
+    }
+    catch(e) {
+      throw new Error('You have a CoffeeScript Jakefile, but have not installed CoffeeScript');
+    }
+  },
+  'ls': function () {
+    try {
+      require('livescript');
+    }
+    catch (e) {
+      throw new Error('You have a LiveScript Jakefile, but have not installed LiveScript');
+    }
+  }
+};
+const IMPLICIT_JAKEFILE_NAMES = [
+  'Jakefile',
+  'Gulpfile'
+];
+
+let Loader = function () {
+  // Load a Jakefile, running the code inside -- this may result in
+  // tasks getting defined using the original Jake API, e.g.,
+  // `task('foo' ['bar', 'baz']);`, or can also auto-create tasks
+  // from any functions exported from the file
+  function loadFile(filePath) {
+    let exported = require(filePath);
+    for (let [key, value] of Object.entries(exported)) {
+      let t;
+      if (typeof value == 'function') {
+        t = jake.task(key, value);
+        t.description = '(Exported function)';
+      }
+    }
+  }
+
+  function fileExists(name) {
+    let nameWithExt = null;
+    // Support no file extension as well
+    let exts = Object.keys(SUPPORTED_EXTENSIONS).concat(['']);
+    exts.some((ext) => {
+      let fname = ext ? `${name}.${ext}` : name;
+      if (existsSync(fname)) {
+        nameWithExt = fname;
+        return true;
+      }
+    });
+    return nameWithExt;
+  }
+
+  // Recursive
+  function findImplicitJakefile() {
+    let cwd = process.cwd();
+    let names = IMPLICIT_JAKEFILE_NAMES;
+    let found = null;
+    names.some((name) => {
+      let n;
+      // Prefer all-lowercase
+      n = name.toLowerCase();
+      if ((found = fileExists(n))) {
+        return found;
+      }
+      // Check mixed-case as well
+      n = name;
+      if ((found = fileExists(n))) {
+        return found;
+      }
+    });
+    if (found) {
+      return found;
+    }
+    else {
+      process.chdir("..");
+      // If we've walked all the way up the directory tree,
+      // bail out with no result
+      if (cwd === process.cwd()) {
+        return null;
+      }
+      return findImplicitJakefile();
+    }
+  }
+
+  this.loadFile = function (fileSpecified) {
+    let jakefile;
+    let origCwd = process.cwd();
+
+    if (fileSpecified) {
+      if (existsSync(fileSpecified)) {
+        jakefile = fileSpecified;
+      }
+    }
+    else {
+      jakefile = findImplicitJakefile();
+    }
+
+    if (jakefile) {
+      let ext = jakefile.split('.')[1];
+      let loaderFunc = SUPPORTED_EXTENSIONS[ext];
+      loaderFunc && loaderFunc();
+
+      loadFile(utils.file.absolutize(jakefile));
+      return true;
+    }
+    else {
+      if (!fileSpecified) {
+        // Restore the working directory on failure
+        process.chdir(origCwd);
+      }
+      return false;
+    }
+  };
+
+  this.loadDirectory = function (d) {
+    let dirname = d || 'jakelib';
+    let dirlist;
+    dirname = utils.file.absolutize(dirname);
+    if (existsSync(dirname)) {
+      dirlist = fs.readdirSync(dirname);
+      dirlist.forEach(function (filePath) {
+        if (JAKELIB_FILE_PAT.test(filePath)) {
+          loadFile(path.join(dirname, filePath));
+        }
+      });
+      return true;
+    }
+    return false;
+  };
+
+};
+
+module.exports = function () {
+  return new Loader();
+};
diff --git a/d2d_app/node_modules/jake/lib/namespace.js b/d2d_app/node_modules/jake/lib/namespace.js
new file mode 100644 (file)
index 0000000..a3c2787
--- /dev/null
@@ -0,0 +1,115 @@
+const ROOT_NAMESPACE_NAME = '__rootNamespace__';
+
+class Namespace {
+  constructor(name, parentNamespace) {
+    this.name = name;
+    this.parentNamespace = parentNamespace;
+    this.childNamespaces = {};
+    this.tasks = {};
+    this.rules = {};
+    this.path = this.getPath();
+  }
+
+  get fullName() {
+    return this._getFullName();
+  }
+
+  addTask(task) {
+    this.tasks[task.name] = task;
+    task.namespace = this;
+  }
+
+  resolveTask(name) {
+    if (!name) {
+      return;
+    }
+
+    let taskPath = name.split(':');
+    let taskName = taskPath.pop();
+    let task;
+    let ns;
+
+    // Namespaced, return either relative to current, or from root
+    if (taskPath.length) {
+      taskPath = taskPath.join(':');
+      ns = this.resolveNamespace(taskPath) ||
+        Namespace.ROOT_NAMESPACE.resolveNamespace(taskPath);
+      task = (ns && ns.resolveTask(taskName));
+    }
+    // Bare task, return either local, or top-level
+    else {
+      task = this.tasks[name] || Namespace.ROOT_NAMESPACE.tasks[name];
+    }
+
+    return task || null;
+  }
+
+
+  resolveNamespace(relativeName) {
+    if (!relativeName) {
+      return this;
+    }
+
+    let parts = relativeName.split(':');
+    let ns = this;
+
+    for (let i = 0, ii = parts.length; (ns && i < ii); i++) {
+      ns = ns.childNamespaces[parts[i]];
+    }
+
+    return ns || null;
+  }
+
+  matchRule(relativeName) {
+    let parts = relativeName.split(':');
+    parts.pop();
+    let ns = this.resolveNamespace(parts.join(':'));
+    let rules = ns ? ns.rules : [];
+    let r;
+    let match;
+
+    for (let p in rules) {
+      r = rules[p];
+      if (r.match(relativeName)) {
+        match = r;
+      }
+    }
+
+    return (ns && match) ||
+        (this.parentNamespace &&
+        this.parentNamespace.matchRule(relativeName));
+  }
+
+  getPath() {
+    let parts = [];
+    let next = this.parentNamespace;
+    while (next) {
+      parts.push(next.name);
+      next = next.parentNamespace;
+    }
+    parts.pop(); // Remove '__rootNamespace__'
+    return parts.reverse().join(':');
+  }
+
+  _getFullName() {
+    let path = this.path;
+    path = (path && path.split(':')) || [];
+    path.push(this.name);
+    return path.join(':');
+  }
+
+  isRootNamespace() {
+    return !this.parentNamespace;
+  }
+}
+
+class RootNamespace extends Namespace {
+  constructor() {
+    super(ROOT_NAMESPACE_NAME, null);
+    Namespace.ROOT_NAMESPACE = this;
+  }
+}
+
+module.exports.Namespace = Namespace;
+module.exports.RootNamespace = RootNamespace;
+
diff --git a/d2d_app/node_modules/jake/lib/package_task.js b/d2d_app/node_modules/jake/lib/package_task.js
new file mode 100644 (file)
index 0000000..527aca7
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+let path = require('path');
+let fs = require('fs');
+let exec = require('child_process').exec;
+let FileList = require('filelist').FileList;
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.PackageTask
+  @constructor
+  @description Instantiating a PackageTask creates a number of Jake
+  Tasks that make packaging and distributing your software easy.
+
+  @param {String} name The name of the project
+  @param {String} version The current project version (will be
+  appended to the project-name in the package-archive
+  @param {Function} definition Defines the contents of the package,
+  and format of the package-archive. Will be executed on the instantiated
+  PackageTask (i.e., 'this', will be the PackageTask instance),
+  to set the various instance-propertiess.
+
+  @example
+  let t = new jake.PackageTask('rous', 'v' + version, function () {
+    let files = [
+      'Capfile'
+    , 'Jakefile'
+    , 'README.md'
+    , 'package.json'
+    , 'app/*'
+    , 'bin/*'
+    , 'config/*'
+    , 'lib/*'
+    , 'node_modules/*'
+    ];
+    this.packageFiles.include(files);
+    this.packageFiles.exclude('node_modules/foobar');
+    this.needTarGz = true;
+  });
+
+ */
+let PackageTask = function () {
+  let args = Array.prototype.slice.call(arguments);
+  let name = args.shift();
+  let version = args.shift();
+  let definition = args.pop();
+  let prereqs = args.pop() || []; // Optional
+
+  prereqs = [].concat(prereqs); // Accept string or list
+
+  /**
+    @name jake.PackageTask#name
+    @public
+    @type {String}
+    @description The name of the project
+   */
+  this.name = name;
+  /**
+    @name jake.PackageTask#version
+    @public
+    @type {String}
+    @description The project version-string
+   */
+  this.version = version;
+  /**
+    @name jake.PackageTask#prereqs
+    @public
+    @type {Array}
+    @description Tasks to run before packaging
+   */
+  this.prereqs = prereqs;
+  /**
+    @name jake.PackageTask#packageDir
+    @public
+    @type {String='pkg'}
+    @description The directory-name to use for packaging the software
+   */
+  this.packageDir = 'pkg';
+  /**
+    @name jake.PackageTask#packageFiles
+    @public
+    @type {jake.FileList}
+    @description The list of files and directories to include in the
+    package-archive
+   */
+  this.packageFiles = new FileList();
+  /**
+    @name jake.PackageTask#needTar
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `tar` utility to create
+    a gzip .tgz archive of the package
+   */
+  this.needTar = false;
+  /**
+    @name jake.PackageTask#needTarGz
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `tar` utility to create
+    a gzip .tar.gz archive of the package
+   */
+  this.needTarGz = false;
+  /**
+    @name jake.PackageTask#needTarBz2
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `tar` utility to create
+    a bzip2 .bz2 archive of the package
+   */
+  this.needTarBz2 = false;
+  /**
+    @name jake.PackageTask#needJar
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `jar` utility to create
+    a .jar archive of the package
+   */
+  this.needJar = false;
+  /**
+    @name jake.PackageTask#needZip
+    @public
+    @type {Boolean=false}
+    @description If set to true, uses the `zip` utility to create
+    a .zip archive of the package
+   */
+  this.needZip = false;
+  /**
+    @name jake.PackageTask#manifestFile
+    @public
+    @type {String=null}
+    @description Can be set to point the `jar` utility at a manifest
+    file to use in a .jar archive. If unset, one will be automatically
+    created by the `jar` utility. This path should be relative to the
+    root of the package directory (this.packageDir above, likely 'pkg')
+   */
+  this.manifestFile = null;
+  /**
+    @name jake.PackageTask#tarCommand
+    @public
+    @type {String='tar'}
+    @description The shell-command to use for creating tar archives.
+   */
+  this.tarCommand = 'tar';
+  /**
+    @name jake.PackageTask#jarCommand
+    @public
+    @type {String='jar'}
+    @description The shell-command to use for creating jar archives.
+   */
+  this.jarCommand = 'jar';
+  /**
+    @name jake.PackageTask#zipCommand
+    @public
+    @type {String='zip'}
+    @description The shell-command to use for creating zip archives.
+   */
+  this.zipCommand = 'zip';
+  /**
+    @name jake.PackageTask#archiveNoBaseDir
+    @public
+    @type {Boolean=false}
+    @description Simple option for performing the archive on the
+    contents of the directory instead of the directory itself
+   */
+  this.archiveNoBaseDir = false;
+  /**
+    @name jake.PackageTask#archiveChangeDir
+    @public
+    @type {String=null}
+    @description Equivalent to the '-C' command for the `tar` and `jar`
+    commands. ("Change to this directory before adding files.")
+   */
+  this.archiveChangeDir = null;
+  /**
+    @name jake.PackageTask#archiveContentDir
+    @public
+    @type {String=null}
+    @description Specifies the files and directories to include in the
+    package-archive. If unset, this will default to the main package
+    directory -- i.e., name + version.
+   */
+  this.archiveContentDir = null;
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+  this.define();
+};
+
+PackageTask.prototype = new (function () {
+
+  let _compressOpts = {
+    Tar: {
+      ext: '.tgz',
+      flags: 'czf',
+      cmd: 'tar'
+    },
+    TarGz: {
+      ext: '.tar.gz',
+      flags: 'czf',
+      cmd: 'tar'
+    },
+    TarBz2: {
+      ext: '.tar.bz2',
+      flags: 'cjf',
+      cmd: 'tar'
+    },
+    Jar: {
+      ext: '.jar',
+      flags: 'cf',
+      cmd: 'jar'
+    },
+    Zip: {
+      ext: '.zip',
+      flags: 'qr',
+      cmd: 'zip'
+    }
+  };
+
+  this.define = function () {
+    let self = this;
+    let packageDirPath = this.packageDirPath();
+    let compressTaskArr = [];
+
+    desc('Build the package for distribution');
+    task('package', self.prereqs.concat(['clobberPackage', 'buildPackage']));
+    // Backward-compat alias
+    task('repackage', ['package']);
+
+    task('clobberPackage', function () {
+      jake.rmRf(self.packageDir, {silent: true});
+    });
+
+    desc('Remove the package');
+    task('clobber', ['clobberPackage']);
+
+    let doCommand = function (p) {
+      let filename = path.resolve(self.packageDir + '/' + self.packageName() +
+                                  _compressOpts[p].ext);
+      if (process.platform == 'win32') {
+        // Windows full path may have drive letter, which is going to cause
+        // namespace problems, so strip it.
+        if (filename.length > 2 && filename[1] == ':') {
+          filename = filename.substr(2);
+        }
+      }
+      compressTaskArr.push(filename);
+
+      file(filename, [packageDirPath], function () {
+        let cmd;
+        let opts = _compressOpts[p];
+        // Directory to move to when doing the compression-task
+        // Changes in the case of zip for emulating -C option
+        let chdir = self.packageDir;
+        // Save the current dir so it's possible to pop back up
+        // after compressing
+        let currDir = process.cwd();
+        let archiveChangeDir;
+        let archiveContentDir;
+
+        if (self.archiveNoBaseDir) {
+          archiveChangeDir = self.packageName();
+          archiveContentDir = '.';
+        }
+        else {
+          archiveChangeDir = self.archiveChangeDir;
+          archiveContentDir = self.archiveContentDir;
+        }
+
+        cmd = self[opts.cmd + 'Command'];
+        cmd += ' -' + opts.flags;
+        if (opts.cmd == 'jar' && self.manifestFile) {
+          cmd += 'm';
+        }
+
+        // The name of the archive to create -- use full path
+        // so compression can be performed from a different dir
+        // if needed
+        cmd += ' ' + filename;
+
+        if (opts.cmd == 'jar' && self.manifestFile) {
+          cmd += ' ' + self.manifestFile;
+        }
+
+        // Where to perform the compression -- -C option isn't
+        // supported in zip, so actually do process.chdir for this
+        if (archiveChangeDir) {
+          if (opts.cmd == 'zip') {
+            chdir = path.join(chdir, archiveChangeDir);
+          }
+          else {
+            cmd += ' -C ' + archiveChangeDir;
+          }
+        }
+
+        // Where to get the archive content
+        if (archiveContentDir) {
+          cmd += ' ' + archiveContentDir;
+        }
+        else {
+          cmd += ' ' + self.packageName();
+        }
+
+        // Move into the desired dir (usually packageDir) to compress
+        // Return back up to the current dir after the exec
+        process.chdir(chdir);
+
+        exec(cmd, function (err, stdout, stderr) {
+          if (err) { throw err; }
+
+          // Return back up to the starting directory (see above,
+          // before exec)
+          process.chdir(currDir);
+
+          complete();
+        });
+      }, {async: true});
+    };
+
+    for (let p in _compressOpts) {
+      if (this['need' + p]) {
+        doCommand(p);
+      }
+    }
+
+    task('buildPackage', compressTaskArr, function () {});
+
+    directory(this.packageDir);
+
+    file(packageDirPath, this.packageFiles, function () {
+      jake.mkdirP(packageDirPath);
+      let fileList = [];
+      self.packageFiles.forEach(function (name) {
+        let f = path.join(self.packageDirPath(), name);
+        let fDir = path.dirname(f);
+        jake.mkdirP(fDir, {silent: true});
+
+        // Add both files and directories
+        fileList.push({
+          from: name,
+          to: f
+        });
+      });
+      let _copyFile = function () {
+        let file = fileList.pop();
+        let stat;
+        if (file) {
+          stat = fs.statSync(file.from);
+          // Target is a directory, just create it
+          if (stat.isDirectory()) {
+            jake.mkdirP(file.to, {silent: true});
+            _copyFile();
+          }
+          // Otherwise copy the file
+          else {
+            jake.cpR(file.from, file.to, {silent: true});
+            _copyFile();
+          }
+        }
+        else {
+          complete();
+        }
+      };
+      _copyFile();
+    }, {async: true});
+
+
+  };
+
+  this.packageName = function () {
+    if (this.version) {
+      return this.name + '-' + this.version;
+    }
+    else {
+      return this.name;
+    }
+  };
+
+  this.packageDirPath = function () {
+    return this.packageDir + '/' + this.packageName();
+  };
+
+})();
+
+jake.PackageTask = PackageTask;
+exports.PackageTask = PackageTask;
+
diff --git a/d2d_app/node_modules/jake/lib/parseargs.js b/d2d_app/node_modules/jake/lib/parseargs.js
new file mode 100644 (file)
index 0000000..1bd24c9
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+let parseargs = {};
+let isOpt = function (arg) { return arg.indexOf('-') === 0 };
+let removeOptPrefix = function (opt) { return opt.replace(/^--/, '').replace(/^-/, '') };
+
+/**
+ * @constructor
+ * Parses a list of command-line args into a key/value object of
+ * options and an array of positional commands.
+ * @ param {Array} opts A list of options in the following format:
+ * [{full: 'foo', abbr: 'f'}, {full: 'bar', abbr: 'b'}]]
+ */
+parseargs.Parser = function (opts) {
+  // A key/value object of matching options parsed out of the args
+  this.opts = {};
+  this.taskNames = null;
+  this.envVars = null;
+
+  // Data structures used for parsing
+  this.reg = opts;
+  this.shortOpts = {};
+  this.longOpts = {};
+
+  let self = this;
+  [].forEach.call(opts, function (item) {
+    self.shortOpts[item.abbr] = item;
+    self.longOpts[item.full] = item;
+  });
+};
+
+parseargs.Parser.prototype = new function () {
+
+  let _trueOrNextVal = function (argParts, args) {
+    if (argParts[1]) {
+      return argParts[1];
+    }
+    else {
+      return (!args[0] || isOpt(args[0])) ?
+        true : args.shift();
+    }
+  };
+
+  /**
+   * Parses an array of arguments into options and positional commands
+   * @param {Array} args The command-line args to parse
+   */
+  this.parse = function (args) {
+    let cmds = [];
+    let cmd;
+    let envVars = {};
+    let opts = {};
+    let arg;
+    let argItem;
+    let argParts;
+    let cmdItems;
+    let taskNames = [];
+    let preempt;
+
+    while (args.length) {
+      arg = args.shift();
+
+      if (isOpt(arg)) {
+        arg = removeOptPrefix(arg);
+        argParts = arg.split('=');
+        argItem = this.longOpts[argParts[0]] || this.shortOpts[argParts[0]];
+        if (argItem) {
+          // First-encountered preemptive opt takes precedence -- no further opts
+          // or possibility of ambiguity, so just look for a value, or set to
+          // true and then bail
+          if (argItem.preempts) {
+            opts[argItem.full] = _trueOrNextVal(argParts, args);
+            preempt = true;
+            break;
+          }
+          // If the opt requires a value, see if we can get a value from the
+          // next arg, or infer true from no-arg -- if it's followed by another
+          // opt, throw an error
+          if (argItem.expectValue || argItem.allowValue) {
+            opts[argItem.full] = _trueOrNextVal(argParts, args);
+            if (argItem.expectValue && !opts[argItem.full]) {
+              throw new Error(argItem.full + ' option expects a value.');
+            }
+          }
+          else {
+            opts[argItem.full] = true;
+          }
+        }
+      }
+      else {
+        cmds.unshift(arg);
+      }
+    }
+
+    if (!preempt) {
+      // Parse out any env-vars and task-name
+      while ((cmd = cmds.pop())) {
+        cmdItems = cmd.split('=');
+        if (cmdItems.length > 1) {
+          envVars[cmdItems[0]] = cmdItems[1];
+        }
+        else {
+          taskNames.push(cmd);
+        }
+      }
+
+    }
+
+    return {
+      opts: opts,
+      envVars: envVars,
+      taskNames: taskNames
+    };
+  };
+
+};
+
+module.exports = parseargs;
diff --git a/d2d_app/node_modules/jake/lib/program.js b/d2d_app/node_modules/jake/lib/program.js
new file mode 100644 (file)
index 0000000..121632f
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+let fs = require('fs');
+let parseargs = require('./parseargs');
+let utils = require('./utils');
+let Program;
+let usage = require('fs').readFileSync(`${__dirname}/../usage.txt`).toString();
+let { Task } = require('./task/task');
+
+function die(msg) {
+  console.log(msg);
+  process.stdout.write('', function () {
+    process.stderr.write('', function () {
+      process.exit();
+    });
+  });
+}
+
+let preempts = {
+  version: function () {
+    die(jake.version);
+  },
+  help: function () {
+    die(usage);
+  }
+};
+
+let AVAILABLE_OPTS = [
+  { full: 'jakefile',
+    abbr: 'f',
+    expectValue: true
+  },
+  { full: 'quiet',
+    abbr: 'q',
+    expectValue: false
+  },
+  { full: 'directory',
+    abbr: 'C',
+    expectValue: true
+  },
+  { full: 'always-make',
+    abbr: 'B',
+    expectValue: false
+  },
+  { full: 'tasks',
+    abbr: 'T',
+    expectValue: false,
+    allowValue: true
+  },
+  // Alias t
+  { full: 'tasks',
+    abbr: 't',
+    expectValue: false,
+    allowValue: true
+  },
+  // Alias ls
+  { full: 'tasks',
+    abbr: 'ls',
+    expectValue: false,
+    allowValue: true
+  },
+  { full: 'help',
+    abbr: 'h',
+  },
+  { full: 'version',
+    abbr: 'V',
+  },
+  // Alias lowercase v
+  { full: 'version',
+    abbr: 'v',
+  },
+  { full: 'jakelibdir',
+    abbr: 'J',
+    expectValue: true
+  },
+  { full: 'allow-rejection',
+    abbr: 'ar',
+    expectValue: false
+  }
+];
+
+Program = function () {
+  this.availableOpts = AVAILABLE_OPTS;
+  this.opts = {};
+  this.taskNames = null;
+  this.taskArgs = null;
+  this.envVars = null;
+  this.die = die;
+};
+
+Program.prototype = new (function () {
+
+  this.handleErr = function (err) {
+    if (jake.listeners('error').length !== 0) {
+      jake.emit('error', err);
+      return;
+    }
+
+    if (jake.listeners('error').length) {
+      jake.emit('error', err);
+      return;
+    }
+
+    utils.logger.error('jake aborted.');
+    if (err.stack) {
+      utils.logger.error(err.stack);
+    }
+    else {
+      utils.logger.error(err.message);
+    }
+
+    process.stdout.write('', function () {
+      process.stderr.write('', function () {
+        jake.errorCode = jake.errorCode || 1;
+        process.exit(jake.errorCode);
+      });
+    });
+  };
+
+  this.parseArgs = function (args) {
+    let result = (new parseargs.Parser(this.availableOpts)).parse(args);
+    this.setOpts(result.opts);
+    this.setTaskNames(result.taskNames);
+    this.setEnvVars(result.envVars);
+  };
+
+  this.setOpts = function (options) {
+    let opts = options || {};
+    Object.assign(this.opts, opts);
+  };
+
+  this.internalOpts = function (options) {
+    this.availableOpts = this.availableOpts.concat(options);
+  };
+
+  this.autocompletions = function (cur) {
+    let p; let i; let task;
+    let commonPrefix = '';
+    let matches = [];
+
+    for (p in jake.Task) {
+      task = jake.Task[p];
+      if (
+        'fullName' in task
+          && (
+            // if empty string, program converts to true
+            cur === true ||
+            task.fullName.indexOf(cur) === 0
+          )
+      ) {
+        if (matches.length === 0) {
+          commonPrefix = task.fullName;
+        }
+        else {
+          for (i = commonPrefix.length; i > -1; --i) {
+            commonPrefix = commonPrefix.substr(0, i);
+            if (task.fullName.indexOf(commonPrefix) === 0) {
+              break;
+            }
+          }
+        }
+        matches.push(task.fullName);
+      }
+    }
+
+    if (matches.length > 1 && commonPrefix === cur) {
+      matches.unshift('yes-space');
+    }
+    else {
+      matches.unshift('no-space');
+    }
+
+    process.stdout.write(matches.join(' '));
+  };
+
+  this.setTaskNames = function (names) {
+    if (names && !Array.isArray(names)) {
+      throw new Error('Task names must be an array');
+    }
+    this.taskNames = (names && names.length) ? names : ['default'];
+  };
+
+  this.setEnvVars = function (vars) {
+    this.envVars = vars || null;
+  };
+
+  this.firstPreemptiveOption = function () {
+    let opts = this.opts;
+    for (let p in opts) {
+      if (preempts[p]) {
+        return preempts[p];
+      }
+    }
+    return false;
+  };
+
+  this.init = function (configuration) {
+    let self = this;
+    let config = configuration || {};
+    if (config.options) {
+      this.setOpts(config.options);
+    }
+    if (config.taskNames) {
+      this.setTaskNames(config.taskNames);
+    }
+    if (config.envVars) {
+      this.setEnvVars(config.envVars);
+    }
+    process.addListener('uncaughtException', function (err) {
+      self.handleErr(err);
+    });
+    if (!this.opts['allow-rejection']) {
+      process.addListener('unhandledRejection', (reason, promise) => {
+        utils.logger.error('Unhandled rejection at:', promise, 'reason:', reason);
+        self.handleErr(reason);
+      });
+    }
+    if (this.envVars) {
+      Object.assign(process.env, this.envVars);
+    }
+  };
+
+  this.run = function () {
+    let rootTask;
+    let taskNames;
+    let dirname;
+    let opts = this.opts;
+
+    if (opts.autocomplete) {
+      return this.autocompletions(opts['autocomplete-cur'], opts['autocomplete-prev']);
+    }
+    // Run with `jake -T`, just show descriptions
+    if (opts.tasks) {
+      return jake.showAllTaskDescriptions(opts.tasks);
+    }
+
+    taskNames = this.taskNames;
+    if (!(Array.isArray(taskNames) && taskNames.length)) {
+      throw new Error('Please pass jake.runTasks an array of task-names');
+    }
+
+    // Set working dir
+    dirname = opts.directory;
+    if (dirname) {
+      if (fs.existsSync(dirname) &&
+        fs.statSync(dirname).isDirectory()) {
+        process.chdir(dirname);
+      }
+      else {
+        throw new Error(dirname + ' is not a valid directory path');
+      }
+    }
+
+    rootTask = task(Task.ROOT_TASK_NAME, taskNames, function () {});
+    rootTask._internal = true;
+
+    rootTask.once('complete', function () {
+      jake.emit('complete');
+    });
+    jake.emit('start');
+    rootTask.invoke();
+  };
+
+})();
+
+module.exports.Program = Program;
diff --git a/d2d_app/node_modules/jake/lib/publish_task.js b/d2d_app/node_modules/jake/lib/publish_task.js
new file mode 100644 (file)
index 0000000..f0cacfd
--- /dev/null
@@ -0,0 +1,290 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+let fs = require('fs');
+let path = require('path');
+let exec = require('child_process').execSync;
+let FileList = require('filelist').FileList;
+
+let PublishTask = function () {
+  let args = Array.prototype.slice.call(arguments).filter(function (item) {
+    return typeof item != 'undefined';
+  });
+  let arg;
+  let opts = {};
+  let definition;
+  let prereqs = [];
+  let createDef = function (arg) {
+    return function () {
+      this.packageFiles.include(arg);
+    };
+  };
+
+  this.name = args.shift();
+
+  // Old API, just name + list of files
+  if (args.length == 1 && (Array.isArray(args[0]) || typeof args[0] == 'string')) {
+    definition = createDef(args.pop());
+  }
+  // Current API, name + [prereqs] + [opts] + definition
+  else {
+    while ((arg = args.pop())) {
+      // Definition func
+      if (typeof arg == 'function') {
+        definition = arg;
+      }
+      // Prereqs
+      else if (Array.isArray(arg) || typeof arg == 'string') {
+        prereqs = arg;
+      }
+      // Opts
+      else {
+        opts = arg;
+      }
+    }
+  }
+
+  this.prereqs = prereqs;
+  this.packageFiles = new FileList();
+  this.publishCmd = opts.publishCmd || 'npm publish %filename';
+  this.publishMessage = opts.publishMessage || 'BOOM! Published.';
+  this.gitCmd = opts.gitCmd || 'git';
+  this.versionFiles = opts.versionFiles || ['package.json'];
+  this.scheduleDelay = 5000;
+
+  // Override utility funcs for testing
+  this._ensureRepoClean = function (stdout) {
+    if (stdout.length) {
+      fail(new Error('Git repository is not clean.'));
+    }
+  };
+  this._getCurrentBranch = function (stdout) {
+    return String(stdout).trim();
+  };
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+  this.define();
+};
+
+
+PublishTask.prototype = new (function () {
+
+  let _currentBranch = null;
+
+  let getPackage = function () {
+    let pkg = JSON.parse(fs.readFileSync(path.join(process.cwd(),
+      '/package.json')).toString());
+    return pkg;
+  };
+  let getPackageVersionNumber = function () {
+    return getPackage().version;
+  };
+
+  this.define = function () {
+    let self = this;
+
+    namespace('publish', function () {
+      task('fetchTags', function () {
+        // Make sure local tags are up to date
+        exec(self.gitCmd + ' fetch --tags');
+        console.log('Fetched remote tags.');
+      });
+
+      task('getCurrentBranch', function () {
+        // Figure out what branch to push to
+        let stdout = exec(self.gitCmd + ' symbolic-ref --short HEAD').toString();
+        if (!stdout) {
+          throw new Error('No current Git branch found');
+        }
+        _currentBranch = self._getCurrentBranch(stdout);
+        console.log('On branch ' + _currentBranch);
+      });
+
+      task('ensureClean', function () {
+        // Only bump, push, and tag if the Git repo is clean
+        let stdout = exec(self.gitCmd + ' status --porcelain --untracked-files=no').toString();
+        // Throw if there's output
+        self._ensureRepoClean(stdout);
+      });
+
+      task('updateVersionFiles', function () {
+        let pkg;
+        let version;
+        let arr;
+        let patch;
+
+        // Grab the current version-string
+        pkg = getPackage();
+        version = pkg.version;
+        // Increment the patch-number for the version
+        arr = version.split('.');
+        patch = parseInt(arr.pop(), 10) + 1;
+        arr.push(patch);
+        version = arr.join('.');
+
+        // Update package.json or other files with the new version-info
+        self.versionFiles.forEach(function (file) {
+          let p = path.join(process.cwd(), file);
+          let data = JSON.parse(fs.readFileSync(p).toString());
+          data.version = version;
+          fs.writeFileSync(p, JSON.stringify(data, true, 2) + '\n');
+        });
+        // Return the version string so that listeners for the 'complete' event
+        // for this task can use it (e.g., to update other files before pushing
+        // to Git)
+        return version;
+      });
+
+      task('pushVersion', ['ensureClean', 'updateVersionFiles'], function () {
+        let version = getPackageVersionNumber();
+        let message = 'Version ' + version;
+        let cmds = [
+          self.gitCmd + ' commit -a -m "' + message + '"',
+          self.gitCmd + ' push origin ' + _currentBranch,
+          self.gitCmd + ' tag -a v' + version + ' -m "' + message + '"',
+          self.gitCmd + ' push --tags'
+        ];
+        cmds.forEach((cmd) => {
+          exec(cmd);
+        });
+        version = getPackageVersionNumber();
+        console.log('Bumped version number to v' + version + '.');
+      });
+
+      let defineTask = task('definePackage', function () {
+        let version = getPackageVersionNumber();
+        new jake.PackageTask(self.name, 'v' + version, self.prereqs, function () {
+          // Replace the PackageTask's FileList with the PublishTask's FileList
+          this.packageFiles = self.packageFiles;
+          this.needTarGz = true; // Default to tar.gz
+          // If any of the need<CompressionFormat> or archive opts are set
+          // proxy them to the PackageTask
+          for (let p in this) {
+            if (p.indexOf('need') === 0 || p.indexOf('archive') === 0) {
+              if (typeof self[p] != 'undefined') {
+                this[p] = self[p];
+              }
+            }
+          }
+        });
+      });
+      defineTask._internal = true;
+
+      task('package', function () {
+        let definePack = jake.Task['publish:definePackage'];
+        let pack = jake.Task['package'];
+        let version = getPackageVersionNumber();
+
+        // May have already been run
+        if (definePack.taskStatus == jake.Task.runStatuses.DONE) {
+          definePack.reenable(true);
+        }
+        definePack.invoke();
+        // Set manually, completion happens in next tick, creating deadlock
+        definePack.taskStatus = jake.Task.runStatuses.DONE;
+        pack.invoke();
+        console.log('Created package for ' + self.name + ' v' + version);
+      });
+
+      task('publish', function () {
+        return new Promise((resolve) => {
+          let version = getPackageVersionNumber();
+          let filename;
+          let cmd;
+
+          console.log('Publishing ' + self.name + ' v' + version);
+
+          if (typeof self.createPublishCommand == 'function') {
+            cmd = self.createPublishCommand(version);
+          }
+          else {
+            filename = './pkg/' + self.name + '-v' + version + '.tar.gz';
+            cmd = self.publishCmd.replace(/%filename/gi, filename);
+          }
+
+          if (typeof cmd == 'function') {
+            cmd(function (err) {
+              if (err) {
+                throw err;
+              }
+              console.log(self.publishMessage);
+              resolve();
+            });
+          }
+          else {
+            // Hackity hack -- NPM publish sometimes returns errror like:
+            // Error sending version data\nnpm ERR!
+            // Error: forbidden 0.2.4 is modified, should match modified time
+            setTimeout(function () {
+              let stdout = exec(cmd).toString() || '';
+              stdout = stdout.trim();
+              if (stdout) {
+                console.log(stdout);
+              }
+              console.log(self.publishMessage);
+              resolve();
+            }, self.scheduleDelay);
+          }
+        });
+      });
+
+      task('cleanup', function () {
+        return new Promise((resolve) => {
+          let clobber = jake.Task.clobber;
+          clobber.reenable(true);
+          clobber.on('complete', function () {
+            console.log('Cleaned up package');
+            resolve();
+          });
+          clobber.invoke();
+        });
+      });
+
+    });
+
+    let prefixNs = function (item) {
+      return 'publish:' + item;
+    };
+
+    // Create aliases in the default namespace
+    desc('Create a new version and release.');
+    task('publish', self.prereqs.concat(['version', 'release']
+      .map(prefixNs)));
+
+    desc('Release the existing version.');
+    task('publishExisting', self.prereqs.concat(['release']
+      .map(prefixNs)));
+
+    task('version', ['fetchTags', 'getCurrentBranch', 'pushVersion']
+      .map(prefixNs));
+
+    task('release', ['package', 'publish', 'cleanup']
+      .map(prefixNs));
+
+    // Invoke proactively so there will be a callable 'package' task
+    // which can be used apart from 'publish'
+    jake.Task['publish:definePackage'].invoke();
+  };
+
+})();
+
+jake.PublishTask = PublishTask;
+exports.PublishTask = PublishTask;
+
diff --git a/d2d_app/node_modules/jake/lib/rule.js b/d2d_app/node_modules/jake/lib/rule.js
new file mode 100644 (file)
index 0000000..25f51ae
--- /dev/null
@@ -0,0 +1,311 @@
+let path = require('path');
+let fs = require('fs');
+let Task = require('./task/task').Task;
+
+// Split a task to two parts, name space and task name.
+// For example, given 'foo:bin/a%.c', return an object with
+// - 'ns'     : foo
+// - 'name'   : bin/a%.c
+function splitNs(task) {
+  let parts = task.split(':');
+  let name = parts.pop();
+  let ns = resolveNs(parts);
+  return {
+    'name' : name,
+    'ns'   : ns
+  };
+}
+
+// Return the namespace based on an array of names.
+// For example, given ['foo', 'baz' ], return the namespace
+//
+//   default -> foo -> baz
+//
+// where default is the global root namespace
+// and -> means child namespace.
+function resolveNs(parts) {
+  let  ns = jake.defaultNamespace;
+  for(let i = 0, l = parts.length; ns && i < l; i++) {
+    ns = ns.childNamespaces[parts[i]];
+  }
+  return ns;
+}
+
+// Given a pattern p, say 'foo:bin/a%.c'
+// Return an object with
+// - 'ns'     : foo
+// - 'dir'    : bin
+// - 'prefix' : a
+// - 'suffix' : .c
+function resolve(p) {
+  let task = splitNs(p);
+  let name  = task.name;
+  let ns    = task.ns;
+  let split = path.basename(name).split('%');
+  return {
+    ns: ns,
+    dir: path.dirname(name),
+    prefix: split[0],
+    suffix: split[1]
+  };
+}
+
+// Test whether string a is a suffix of string b
+function stringEndWith(a, b) {
+  let l;
+  return (l = b.lastIndexOf(a)) == -1 ? false : l + a.length == b.length;
+}
+
+// Replace the suffix a of the string s with b.
+// Note that, it is assumed a is a suffix of s.
+function stringReplaceSuffix(s, a, b) {
+  return s.slice(0, s.lastIndexOf(a)) + b;
+}
+
+class Rule {
+  constructor(opts) {
+    this.pattern = opts.pattern;
+    this.source = opts.source;
+    this.prereqs = opts.prereqs;
+    this.action = opts.action;
+    this.opts = opts.opts;
+    this.desc =  opts.desc;
+    this.ns = opts.ns;
+  }
+
+  // Create a file task based on this rule for the specified
+  // task-name
+  // ======
+  // FIXME: Right now this just throws away any passed-in args
+  // for the synthsized task (taskArgs param)
+  // ======
+  createTask(fullName, level) {
+    let self = this;
+    let pattern;
+    let source;
+    let action;
+    let opts;
+    let prereqs;
+    let valid;
+    let src;
+    let tNs;
+    let createdTask;
+    let name = Task.getBaseTaskName(fullName);
+    let nsPath = Task.getBaseNamespacePath(fullName);
+    let ns = this.ns.resolveNamespace(nsPath);
+
+    pattern = this.pattern;
+    source = this.source;
+
+    if (typeof source == 'string') {
+      src = Rule.getSource(name, pattern, source);
+    }
+    else {
+      src = source(name);
+    }
+
+    // TODO: Write a utility function that appends a
+    // taskname to a namespace path
+    src = nsPath.split(':').filter(function (item) {
+      return !!item;
+    }).concat(src).join(':');
+
+    // Generate the prerequisite for the matching task.
+    //    It is the original prerequisites plus the prerequisite
+    //    representing source file, i.e.,
+    //
+    //      rule( '%.o', '%.c', ['some.h'] ...
+    //
+    //    If the objective is main.o, then new task should be
+    //
+    //      file( 'main.o', ['main.c', 'some.h' ] ...
+    prereqs = this.prereqs.slice(); // Get a copy to work with
+    prereqs.unshift(src);
+
+    // Prereq should be:
+    // 1. an existing task
+    // 2. an existing file on disk
+    // 3. a valid rule (i.e., not at too deep a level)
+    valid = prereqs.some(function (p) {
+      let ns = self.ns;
+      return ns.resolveTask(p) ||
+        fs.existsSync(Task.getBaseTaskName(p)) ||
+        jake.attemptRule(p, ns, level + 1);
+    });
+
+    // If any of the prereqs aren't valid, the rule isn't valid
+    if (!valid) {
+      return null;
+    }
+    // Otherwise, hunky-dory, finish creating the task for the rule
+    else {
+      // Create the action for the task
+      action = function () {
+        let task = this;
+        self.action.apply(task);
+      };
+
+      opts = this.opts;
+
+      // Insert the file task into Jake
+      //
+      // Since createTask function stores the task as a child task
+      // of currentNamespace. Here we temporariliy switch the namespace.
+      // FIXME: Should allow optional ns passed in instead of this hack
+      tNs = jake.currentNamespace;
+      jake.currentNamespace = ns;
+      createdTask = jake.createTask('file', name, prereqs, action, opts);
+      createdTask.source = src.split(':').pop();
+      jake.currentNamespace = tNs;
+
+      return createdTask;
+    }
+  }
+
+  match(name) {
+    return Rule.match(this.pattern, name);
+  }
+
+  // Test wether the a prerequisite matchs the pattern.
+  // The arg 'pattern' does not have namespace as prefix.
+  // For example, the following tests are true
+  //
+  //   pattern      |    name
+  //   bin/%.o      |    bin/main.o
+  //   bin/%.o      |    foo:bin/main.o
+  //
+  // The following tests are false (trivally)
+  //
+  //   pattern      |    name
+  //   bin/%.o      |    foobin/main.o
+  //   bin/%.o      |    bin/main.oo
+  static match(pattern, name) {
+    let p;
+    let task;
+    let obj;
+    let filename;
+
+    if (pattern instanceof RegExp) {
+      return pattern.test(name);
+    }
+    else if (pattern.indexOf('%') == -1) {
+      // No Pattern. No Folder. No Namespace.
+      // A Simple Suffix Rule. Just test suffix
+      return stringEndWith(pattern, name);
+    }
+    else {
+      // Resolve the dir, prefix and suffix of pattern
+      p = resolve(pattern);
+
+      // Resolve the namespace and task-name
+      task = splitNs(name);
+      name = task.name;
+
+      // Set the objective as the task-name
+      obj = name;
+
+      // Namespace is already matched.
+
+      // Check dir
+      if (path.dirname(obj) != p.dir) {
+        return false;
+      }
+
+      filename = path.basename(obj);
+
+      // Check file name length
+      if ((p.prefix.length + p.suffix.length + 1) > filename.length) {
+        // Length does not match.
+        return false;
+      }
+
+      // Check prefix
+      if (filename.indexOf(p.prefix) !== 0) {
+        return false;
+      }
+
+      // Check suffix
+      if (!stringEndWith(p.suffix, filename)) {
+        return false;
+      }
+
+      // OK. Find a match.
+      return true;
+    }
+  }
+
+  // Generate the source based on
+  //  - name    name for the synthesized task
+  //  - pattern    pattern for the objective
+  //  - source    pattern for the source
+  //
+  // Return the source with properties
+  //  - dep      the prerequisite of source
+  //             (with the namespace)
+  //
+  //  - file     the file name of source
+  //             (without the namespace)
+  //
+  // For example, given
+  //
+  //  - name   foo:bin/main.o
+  //  - pattern    bin/%.o
+  //  - source    src/%.c
+  //
+  //    return 'foo:src/main.c',
+  //
+  static getSource(name, pattern, source) {
+    let dep;
+    let pat;
+    let match;
+    let file;
+    let src;
+
+    // Regex pattern -- use to look up the extension
+    if (pattern instanceof RegExp) {
+      match = pattern.exec(name);
+      if (match) {
+        if (typeof source == 'function') {
+          src = source(name);
+        }
+        else {
+          src = stringReplaceSuffix(name, match[0], source);
+        }
+      }
+    }
+    // Assume string
+    else {
+      // Simple string suffix replacement
+      if (pattern.indexOf('%') == -1) {
+        if (typeof source == 'function') {
+          src = source(name);
+        }
+        else {
+          src = stringReplaceSuffix(name, pattern, source);
+        }
+      }
+      // Percent-based substitution
+      else {
+        pat = pattern.replace('%', '(.*?)');
+        pat = new RegExp(pat);
+        match = pat.exec(name);
+        if (match) {
+          if (typeof source == 'function') {
+            src = source(name);
+          }
+          else {
+            file = match[1];
+            file = source.replace('%', file);
+            dep = match[0];
+            src = name.replace(dep, file);
+          }
+        }
+      }
+    }
+
+    return src;
+  }
+}
+
+
+exports.Rule = Rule;
diff --git a/d2d_app/node_modules/jake/lib/task/directory_task.js b/d2d_app/node_modules/jake/lib/task/directory_task.js
new file mode 100644 (file)
index 0000000..b17b624
--- /dev/null
@@ -0,0 +1,30 @@
+let fs = require('fs');
+let FileTask = require('./file_task').FileTask;
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.DirectoryTask
+  @constructor
+  @augments EventEmitter
+  @augments jake.Task
+  @augments jake.FileTask
+  @description A Jake DirectoryTask
+
+  @param {String} name The name of the directory to create.
+ */
+class DirectoryTask extends FileTask {
+  constructor(...args) {
+    super(...args);
+    if (fs.existsSync(this.name)) {
+      this.updateModTime();
+    }
+    else {
+      this.modTime = null;
+    }
+  }
+}
+
+exports.DirectoryTask = DirectoryTask;
diff --git a/d2d_app/node_modules/jake/lib/task/file_task.js b/d2d_app/node_modules/jake/lib/task/file_task.js
new file mode 100644 (file)
index 0000000..6fad84b
--- /dev/null
@@ -0,0 +1,124 @@
+let fs = require('fs');
+let Task = require('./task').Task;
+
+function isFileOrDirectory(t) {
+  return (t instanceof FileTask ||
+          t instanceof DirectoryTask);
+}
+
+function isFile(t) {
+  return (t instanceof FileTask && !(t instanceof DirectoryTask));
+}
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.FileTask
+  @class`
+  @extentds Task
+  @description A Jake FileTask
+
+  @param {String} name The name of the Task
+  @param {Array} [prereqs] Prerequisites to be run before this task
+  @param {Function} [action] The action to perform to create this file
+  @param {Object} [opts]
+    @param {Array} [opts.asyc=false] Perform this task asynchronously.
+    If you flag a task with this option, you must call the global
+    `complete` method inside the task's action, for execution to proceed
+    to the next task.
+ */
+class FileTask extends Task {
+  constructor(...args) {
+    super(...args);
+    this.dummy = false;
+    if (fs.existsSync(this.name)) {
+      this.updateModTime();
+    }
+    else {
+      this.modTime = null;
+    }
+  }
+
+  isNeeded() {
+    let prereqs = this.prereqs;
+    let prereqName;
+    let prereqTask;
+
+    // No repeatsies
+    if (this.taskStatus == Task.runStatuses.DONE) {
+      return false;
+    }
+    // The always-make override
+    else if (jake.program.opts['always-make']) {
+      return true;
+    }
+    // Default case
+    else {
+
+      // We need either an existing file, or an action to create one.
+      // First try grabbing the actual mod-time of the file
+      try {
+        this.updateModTime();
+      }
+      // Then fall back to looking for an action
+      catch(e) {
+        if (typeof this.action == 'function') {
+          return true;
+        }
+        else {
+          throw new Error('File-task ' + this.fullName + ' has no ' +
+            'existing file, and no action to create one.');
+        }
+      }
+
+      // Compare mod-time of all the prereqs with its mod-time
+      // If any prereqs are newer, need to run the action to update
+      if (prereqs && prereqs.length) {
+        for (let i = 0, ii = prereqs.length; i < ii; i++) {
+          prereqName = prereqs[i];
+          prereqTask = this.namespace.resolveTask(prereqName) ||
+            jake.createPlaceholderFileTask(prereqName, this.namespace);
+          // Run the action if:
+          // 1. The prereq is a normal task (not file/dir)
+          // 2. The prereq is a file-task with a mod-date more recent than
+          // the one for this file/dir
+          if (prereqTask) {
+            if (!isFileOrDirectory(prereqTask) ||
+                (isFile(prereqTask) && prereqTask.modTime > this.modTime)) {
+              return true;
+            }
+          }
+        }
+      }
+      // File/dir has no prereqs, and exists -- no need to run
+      else {
+        // Effectively done
+        this.taskStatus = Task.runStatuses.DONE;
+        return false;
+      }
+    }
+  }
+
+  updateModTime() {
+    let stats = fs.statSync(this.name);
+    this.modTime = stats.mtime;
+  }
+
+  complete() {
+    if (!this.dummy) {
+      this.updateModTime();
+    }
+    // Hackity hack
+    Task.prototype.complete.apply(this, arguments);
+  }
+
+}
+
+exports.FileTask = FileTask;
+
+// DirectoryTask is a subclass of FileTask, depends on it
+// being defined
+let DirectoryTask = require('./directory_task').DirectoryTask;
+
diff --git a/d2d_app/node_modules/jake/lib/task/index.js b/d2d_app/node_modules/jake/lib/task/index.js
new file mode 100644 (file)
index 0000000..bc93f41
--- /dev/null
@@ -0,0 +1,9 @@
+
+let Task = require('./task').Task;
+let FileTask = require('./file_task').FileTask;
+let DirectoryTask = require('./directory_task').DirectoryTask;
+
+exports.Task = Task;
+exports.FileTask = FileTask;
+exports.DirectoryTask = DirectoryTask;
+
diff --git a/d2d_app/node_modules/jake/lib/task/task.js b/d2d_app/node_modules/jake/lib/task/task.js
new file mode 100644 (file)
index 0000000..9e8886f
--- /dev/null
@@ -0,0 +1,439 @@
+let EventEmitter = require('events').EventEmitter;
+let async = require('async');
+let chalk = require('chalk');
+// 'rule' module is required at the bottom because circular deps
+
+// Used for task value, so better not to use
+// null, since value should be unset/uninitialized
+let UNDEFINED_VALUE;
+
+const ROOT_TASK_NAME = '__rootTask__';
+const POLLING_INTERVAL = 100;
+
+// Parse any positional args attached to the task-name
+function parsePrereqName(name) {
+  let taskArr = name.split('[');
+  let taskName = taskArr[0];
+  let taskArgs = [];
+  if (taskArr[1]) {
+    taskArgs = taskArr[1].replace(/\]$/, '');
+    taskArgs = taskArgs.split(',');
+  }
+  return {
+    name: taskName,
+    args: taskArgs
+  };
+}
+
+/**
+  @name jake.Task
+  @class
+  @extends EventEmitter
+  @description A Jake Task
+
+  @param {String} name The name of the Task
+  @param {Array} [prereqs] Prerequisites to be run before this task
+  @param {Function} [action] The action to perform for this task
+  @param {Object} [opts]
+    @param {Array} [opts.asyc=false] Perform this task asynchronously.
+    If you flag a task with this option, you must call the global
+    `complete` method inside the task's action, for execution to proceed
+    to the next task.
+ */
+class Task extends EventEmitter {
+
+  constructor(name, prereqs, action, options) {
+    // EventEmitter ctor takes no args
+    super();
+
+    if (name.indexOf(':') > -1) {
+      throw new Error('Task name cannot include a colon. It is used internally as namespace delimiter.');
+    }
+    let opts = options || {};
+
+    this._currentPrereqIndex = 0;
+    this._internal = false;
+    this._skipped = false;
+
+    this.name = name;
+    this.prereqs = prereqs;
+    this.action = action;
+    this.async = false;
+    this.taskStatus = Task.runStatuses.UNSTARTED;
+    this.description = null;
+    this.args = [];
+    this.value = UNDEFINED_VALUE;
+    this.concurrency = 1;
+    this.startTime = null;
+    this.endTime = null;
+    this.directory = null;
+    this.namespace = null;
+
+    // Support legacy async-flag -- if not explicitly passed or falsy, will
+    // be set to empty-object
+    if (typeof opts == 'boolean' && opts === true) {
+      this.async = true;
+    }
+    else {
+      if (opts.async) {
+        this.async = true;
+      }
+      if (opts.concurrency) {
+        this.concurrency = opts.concurrency;
+      }
+    }
+
+    //Do a test on self dependencies for this task
+    if(Array.isArray(this.prereqs) && this.prereqs.indexOf(this.name) !== -1) {
+      throw new Error("Cannot use prereq " + this.name + " as a dependency of itself");
+    }
+  }
+
+  get fullName() {
+    return this._getFullName();
+  }
+
+  _initInvocationChain() {
+    // Legacy global invocation chain
+    jake._invocationChain.push(this);
+
+    // New root chain
+    if (!this._invocationChain) {
+      this._invocationChainRoot = true;
+      this._invocationChain = [];
+      if (jake.currentRunningTask) {
+        jake.currentRunningTask._waitForChains = jake.currentRunningTask._waitForChains || [];
+        jake.currentRunningTask._waitForChains.push(this._invocationChain);
+      }
+    }
+  }
+
+  /**
+    @name jake.Task#invoke
+    @function
+    @description Runs prerequisites, then this task. If the task has already
+    been run, will not run the task again.
+   */
+  invoke() {
+    this._initInvocationChain();
+
+    this.args = Array.prototype.slice.call(arguments);
+    this.reenabled = false
+    this.runPrereqs();
+  }
+
+  /**
+    @name jake.Task#execute
+    @function
+    @description Run only this task, without prereqs. If the task has already
+    been run, *will* run the task again.
+   */
+  execute() {
+    this._initInvocationChain();
+
+    this.args = Array.prototype.slice.call(arguments);
+    this.reenable();
+    this.reenabled = true
+    this.run();
+  }
+
+  runPrereqs() {
+    if (this.prereqs && this.prereqs.length) {
+
+      if (this.concurrency > 1) {
+        async.eachLimit(this.prereqs, this.concurrency,
+
+          (name, cb) => {
+            let parsed = parsePrereqName(name);
+
+            let prereq = this.namespace.resolveTask(parsed.name) ||
+          jake.attemptRule(name, this.namespace, 0) ||
+          jake.createPlaceholderFileTask(name, this.namespace);
+
+            if (!prereq) {
+              throw new Error('Unknown task "' + name + '"');
+            }
+
+            //Test for circular invocation
+            if(prereq === this) {
+              setImmediate(function () {
+                cb(new Error("Cannot use prereq " + prereq.name + " as a dependency of itself"));
+              });
+            }
+
+            if (prereq.taskStatus == Task.runStatuses.DONE) {
+            //prereq already done, return
+              setImmediate(cb);
+            }
+            else {
+            //wait for complete before calling cb
+              prereq.once('_done', () => {
+                prereq.removeAllListeners('_done');
+                setImmediate(cb);
+              });
+              // Start the prereq if we are the first to encounter it
+              if (prereq.taskStatus === Task.runStatuses.UNSTARTED) {
+                prereq.taskStatus = Task.runStatuses.STARTED;
+                prereq.invoke.apply(prereq, parsed.args);
+              }
+            }
+          },
+
+          (err) => {
+          //async callback is called after all prereqs have run.
+            if (err) {
+              throw err;
+            }
+            else {
+              setImmediate(this.run.bind(this));
+            }
+          }
+        );
+      }
+      else {
+        setImmediate(this.nextPrereq.bind(this));
+      }
+    }
+    else {
+      setImmediate(this.run.bind(this));
+    }
+  }
+
+  nextPrereq() {
+    let self = this;
+    let index = this._currentPrereqIndex;
+    let name = this.prereqs[index];
+    let prereq;
+    let parsed;
+
+    if (name) {
+
+      parsed = parsePrereqName(name);
+
+      prereq = this.namespace.resolveTask(parsed.name) ||
+          jake.attemptRule(name, this.namespace, 0) ||
+          jake.createPlaceholderFileTask(name, this.namespace);
+
+      if (!prereq) {
+        throw new Error('Unknown task "' + name + '"');
+      }
+
+      // Do when done
+      if (prereq.taskStatus == Task.runStatuses.DONE) {
+        self.handlePrereqDone(prereq);
+      }
+      else {
+        prereq.once('_done', () => {
+          this.handlePrereqDone(prereq);
+          prereq.removeAllListeners('_done');
+        });
+        if (prereq.taskStatus == Task.runStatuses.UNSTARTED) {
+          prereq.taskStatus = Task.runStatuses.STARTED;
+          prereq._invocationChain = this._invocationChain;
+          prereq.invoke.apply(prereq, parsed.args);
+        }
+      }
+    }
+  }
+
+  /**
+    @name jake.Task#reenable
+    @function
+    @description Reenables a task so that it can be run again.
+   */
+  reenable(deep) {
+    let prereqs;
+    let prereq;
+    this._skipped = false;
+    this.taskStatus = Task.runStatuses.UNSTARTED;
+    this.value = UNDEFINED_VALUE;
+    if (deep && this.prereqs) {
+      prereqs = this.prereqs;
+      for (let i = 0, ii = prereqs.length; i < ii; i++) {
+        prereq = jake.Task[prereqs[i]];
+        if (prereq) {
+          prereq.reenable(deep);
+        }
+      }
+    }
+  }
+
+  handlePrereqDone(prereq) {
+    this._currentPrereqIndex++;
+    if (this._currentPrereqIndex < this.prereqs.length) {
+      setImmediate(this.nextPrereq.bind(this));
+    }
+    else {
+      setImmediate(this.run.bind(this));
+    }
+  }
+
+  isNeeded() {
+    let needed = true;
+    if (this.taskStatus == Task.runStatuses.DONE) {
+      needed = false;
+    }
+    return needed;
+  }
+
+  run() {
+    let val, previous;
+    let hasAction = typeof this.action == 'function';
+
+    if (!this.isNeeded()) {
+      this.emit('skip');
+      this.emit('_done');
+    }
+    else {
+      if (this._invocationChain.length) {
+        previous = this._invocationChain[this._invocationChain.length - 1];
+        // If this task is repeating and its previous is equal to this, don't check its status because it was set to UNSTARTED by the reenable() method
+        if (!(this.reenabled && previous == this)) {
+          if (previous.taskStatus != Task.runStatuses.DONE) {
+            let now = (new Date()).getTime();
+            if (now - this.startTime > jake._taskTimeout) {
+              return jake.fail(`Timed out waiting for task: ${previous.name} with status of ${previous.taskStatus}`);
+            }
+            setTimeout(this.run.bind(this), POLLING_INTERVAL);
+            return;
+          }
+        }
+      }
+      if (!(this.reenabled && previous == this)) {
+        this._invocationChain.push(this);
+      }
+
+      if (!(this._internal || jake.program.opts.quiet)) {
+        console.log("Starting '" + chalk.green(this.fullName) + "'...");
+      }
+
+      this.startTime = (new Date()).getTime();
+      this.emit('start');
+
+      jake.currentRunningTask = this;
+
+      if (hasAction) {
+        try {
+          if (this.directory) {
+            process.chdir(this.directory);
+          }
+
+          val = this.action.apply(this, this.args);
+
+          if (typeof val == 'object' && typeof val.then == 'function') {
+            this.async = true;
+
+            val.then(
+              (result) => {
+                setImmediate(() => {
+                  this.complete(result);
+                });
+              },
+              (err) => {
+                setImmediate(() => {
+                  this.errorOut(err);
+                });
+              });
+          }
+        }
+        catch (err) {
+          this.errorOut(err);
+          return; // Bail out, not complete
+        }
+      }
+
+      if (!(hasAction && this.async)) {
+        setImmediate(() => {
+          this.complete(val);
+        });
+      }
+    }
+  }
+
+  errorOut(err) {
+    this.taskStatus = Task.runStatuses.ERROR;
+    this._invocationChain.chainStatus = Task.runStatuses.ERROR;
+    this.emit('error', err);
+  }
+
+  complete(val) {
+
+    if (Array.isArray(this._waitForChains)) {
+      let stillWaiting = this._waitForChains.some((chain) => {
+        return !(chain.chainStatus == Task.runStatuses.DONE ||
+              chain.chainStatus == Task.runStatuses.ERROR);
+      });
+      if (stillWaiting) {
+        let now = (new Date()).getTime();
+        let elapsed = now - this.startTime;
+        if (elapsed > jake._taskTimeout) {
+          return jake.fail(`Timed out waiting for task: ${this.name} with status of ${this.taskStatus}. Elapsed: ${elapsed}`);
+        }
+        setTimeout(() => {
+          this.complete(val);
+        }, POLLING_INTERVAL);
+        return;
+      }
+    }
+
+    jake._invocationChain.splice(jake._invocationChain.indexOf(this), 1);
+
+    if (this._invocationChainRoot) {
+      this._invocationChain.chainStatus = Task.runStatuses.DONE;
+    }
+
+    this._currentPrereqIndex = 0;
+
+    // If 'complete' getting called because task has been
+    // run already, value will not be passed -- leave in place
+    if (!this._skipped) {
+      this.taskStatus = Task.runStatuses.DONE;
+      this.value = val;
+
+      this.emit('complete', this.value);
+      this.emit('_done');
+
+      this.endTime = (new Date()).getTime();
+      let taskTime = this.endTime - this.startTime;
+
+      if (!(this._internal || jake.program.opts.quiet)) {
+        console.log("Finished '" + chalk.green(this.fullName) + "' after " + chalk.magenta(taskTime + ' ms'));
+      }
+
+    }
+  }
+
+  _getFullName() {
+    let ns = this.namespace;
+    let path = (ns && ns.path) || '';
+    path = (path && path.split(':')) || [];
+    if (this.namespace !== jake.defaultNamespace) {
+      path.push(this.namespace.name);
+    }
+    path.push(this.name);
+    return path.join(':');
+  }
+
+  static getBaseNamespacePath(fullName) {
+    return fullName.split(':').slice(0, -1).join(':');
+  }
+
+  static getBaseTaskName(fullName) {
+    return fullName.split(':').pop();
+  }
+}
+
+Task.runStatuses = {
+  UNSTARTED: 'unstarted',
+  DONE: 'done',
+  STARTED: 'started',
+  ERROR: 'error'
+};
+
+Task.ROOT_TASK_NAME = ROOT_TASK_NAME;
+
+exports.Task = Task;
+
+// Required here because circular deps
+require('../rule');
+
diff --git a/d2d_app/node_modules/jake/lib/test_task.js b/d2d_app/node_modules/jake/lib/test_task.js
new file mode 100644 (file)
index 0000000..6482bf1
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+let path = require('path');
+let currDir = process.cwd();
+
+/**
+  @name jake
+  @namespace jake
+*/
+/**
+  @name jake.TestTask
+  @constructor
+  @description Instantiating a TestTask creates a number of Jake
+  Tasks that make running tests for your software easy.
+
+  @param {String} name The name of the project
+  @param {Function} definition Defines the list of files containing the tests,
+  and the name of the namespace/task for running them. Will be executed on the
+  instantiated TestTask (i.e., 'this', will be the TestTask instance), to set
+  the various instance-propertiess.
+
+  @example
+  let t = new jake.TestTask('bij-js', function () {
+    this.testName = 'testSpecial';
+    this.testFiles.include('test/**');
+  });
+
+ */
+let TestTask = function () {
+  let self = this;
+  let args = Array.prototype.slice.call(arguments);
+  let name = args.shift();
+  let definition = args.pop();
+  let prereqs = args.pop() || [];
+
+  /**
+    @name jake.TestTask#testNam
+    @public
+    @type {String}
+    @description The name of the namespace to place the tests in, and
+    the top-level task for running tests. Defaults to "test"
+   */
+  this.testName = 'test';
+
+  /**
+    @name jake.TestTask#testFiles
+    @public
+    @type {jake.FileList}
+    @description The list of files containing tests to load
+   */
+  this.testFiles = new jake.FileList();
+
+  /**
+    @name jake.TestTask#showDescription
+    @public
+    @type {Boolean}
+    @description Show the created task when doing Jake -T
+   */
+  this.showDescription = true;
+
+  /*
+    @name jake.TestTask#totalTests
+    @public
+    @type {Number}
+    @description The total number of tests to run
+  */
+  this.totalTests = 0;
+
+  /*
+    @name jake.TestTask#executedTests
+    @public
+    @type {Number}
+    @description The number of tests successfully run
+  */
+  this.executedTests = 0;
+
+  if (typeof definition == 'function') {
+    definition.call(this);
+  }
+
+  if (this.showDescription) {
+    desc('Run the tests for ' + name);
+  }
+
+  task(this.testName, prereqs, {async: true}, function () {
+    let t = jake.Task[this.fullName + ':run'];
+    t.on('complete', function () {
+      complete();
+    });
+    // Pass args to the namespaced test
+    t.invoke.apply(t, arguments);
+  });
+
+  namespace(self.testName, function () {
+
+    let runTask = task('run', {async: true}, function (pat) {
+      let re;
+      let testFiles;
+
+      // Don't nest; make a top-level namespace. Don't want
+      // re-calling from inside to nest infinitely
+      jake.currentNamespace = jake.defaultNamespace;
+
+      re = new RegExp(pat);
+      // Get test files that match the passed-in pattern
+      testFiles = self.testFiles.toArray()
+        .filter(function (f) {
+          return (re).test(f);
+        }) // Don't load the same file multiple times -- should this be in FileList?
+        .reduce(function (p, c) {
+          if (p.indexOf(c) < 0) {
+            p.push(c);
+          }
+          return p;
+        }, []);
+
+      // Create a namespace for all the testing tasks to live in
+      namespace(self.testName + 'Exec', function () {
+        // Each test will be a prereq for the dummy top-level task
+        let prereqs = [];
+        // Continuation to pass to the async tests, wrapping `continune`
+        let next = function () {
+          complete();
+        };
+        // Create the task for this test-function
+        let createTask = function (name, action) {
+          // If the test-function is defined with a continuation
+          // param, flag the task as async
+          let t;
+          let isAsync = !!action.length;
+
+          // Define the actual namespaced task with the name, the
+          // wrapped action, and the correc async-flag
+          t = task(name, createAction(name, action), {
+            async: isAsync
+          });
+          t.once('complete', function () {
+            self.executedTests++;
+          });
+          t._internal = true;
+          return t;
+        };
+        // Used as the action for the defined task for each test.
+        let createAction = function (n, a) {
+          // A wrapped function that passes in the `next` function
+          // for any tasks that run asynchronously
+          return function () {
+            let cb;
+            if (a.length) {
+              cb = next;
+            }
+            if (!(n == 'before' || n == 'after' ||
+                    /_beforeEach$/.test(n) || /_afterEach$/.test(n))) {
+              jake.logger.log(n);
+            }
+            // 'this' will be the task when action is run
+            return a.call(this, cb);
+          };
+        };
+          // Dummy top-level task for everything to be prereqs for
+        let topLevel;
+
+        // Pull in each test-file, and iterate over any exported
+        // test-functions. Register each test-function as a prereq task
+        testFiles.forEach(function (file) {
+          let exp = require(path.join(currDir, file));
+
+          // Create a namespace for each filename, so test-name collisions
+          // won't be a problem
+          namespace(file, function () {
+            let testPrefix = self.testName + 'Exec:' + file + ':';
+            let testName;
+            // Dummy task for displaying file banner
+            testName = '*** Running ' + file + ' ***';
+            prereqs.push(testPrefix + testName);
+            createTask(testName, function () {});
+
+            // 'before' setup
+            if (typeof exp.before == 'function') {
+              prereqs.push(testPrefix + 'before');
+              // Create the task
+              createTask('before', exp.before);
+            }
+
+            // Walk each exported function, and create a task for each
+            for (let p in exp) {
+              if (p == 'before' || p == 'after' ||
+                  p == 'beforeEach' || p == 'afterEach') {
+                continue;
+              }
+
+              if (typeof exp.beforeEach == 'function') {
+                prereqs.push(testPrefix + p + '_beforeEach');
+                // Create the task
+                createTask(p + '_beforeEach', exp.beforeEach);
+              }
+
+              // Add the namespace:name of this test to the list of prereqs
+              // for the dummy top-level task
+              prereqs.push(testPrefix + p);
+              // Create the task
+              createTask(p, exp[p]);
+
+              if (typeof exp.afterEach == 'function') {
+                prereqs.push(testPrefix + p + '_afterEach');
+                // Create the task
+                createTask(p + '_afterEach', exp.afterEach);
+              }
+            }
+
+            // 'after' teardown
+            if (typeof exp.after == 'function') {
+              prereqs.push(testPrefix + 'after');
+              // Create the task
+              let afterTask = createTask('after', exp.after);
+              afterTask._internal = true;
+            }
+
+          });
+        });
+
+        self.totalTests = prereqs.length;
+        process.on('exit', function () {
+          // Throw in the case where the process exits without
+          // finishing tests, but no error was thrown
+          if (!jake.errorCode && (self.totalTests > self.executedTests)) {
+            throw new Error('Process exited without all tests completing.');
+          }
+        });
+
+        // Create the dummy top-level task. When calling a task internally
+        // with `invoke` that is async (or has async prereqs), have to listen
+        // for the 'complete' event to know when it's done
+        topLevel = task('__top__', prereqs);
+        topLevel._internal = true;
+        topLevel.addListener('complete', function () {
+          jake.logger.log('All tests ran successfully');
+          complete();
+        });
+
+        topLevel.invoke(); // Do the thing!
+      });
+
+    });
+    runTask._internal = true;
+
+  });
+
+
+};
+
+jake.TestTask = TestTask;
+exports.TestTask = TestTask;
+
diff --git a/d2d_app/node_modules/jake/lib/utils/file.js b/d2d_app/node_modules/jake/lib/utils/file.js
new file mode 100644 (file)
index 0000000..a436def
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ * Utilities: A classic collection of JavaScript utilities
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+let fs = require('fs');
+let path = require('path');
+
+/**
+  @name file
+  @namespace file
+*/
+
+let fileUtils = new (function () {
+
+  // Recursively copy files and directories
+  let _copyFile = function (fromPath, toPath, opts) {
+    let from = path.normalize(fromPath)
+    let to = path.normalize(toPath)
+    let options = opts || {}
+    let fromStat;
+    let toStat;
+    let destExists;
+    let destDoesNotExistErr;
+    let content;
+    let filename;
+    let dirContents;
+    let targetDir;
+
+    fromStat = fs.statSync(from);
+
+    try {
+      //console.dir(to + ' destExists');
+      toStat = fs.statSync(to);
+      destExists = true;
+    }
+    catch(e) {
+      //console.dir(to + ' does not exist');
+      destDoesNotExistErr = e;
+      destExists = false;
+    }
+    // Destination dir or file exists, copy into (directory)
+    // or overwrite (file)
+    if (destExists) {
+
+      // If there's a rename-via-copy file/dir name passed, use it.
+      // Otherwise use the actual file/dir name
+      filename = options.rename || path.basename(from);
+
+      // Copying a directory
+      if (fromStat.isDirectory()) {
+        dirContents = fs.readdirSync(from);
+        targetDir = path.join(to, filename);
+        // We don't care if the target dir already exists
+        try {
+          fs.mkdirSync(targetDir, {mode: fromStat.mode & 0o777});
+        }
+        catch(e) {
+          if (e.code !== 'EEXIST') {
+            throw e;
+          }
+        }
+        for (let i = 0, ii = dirContents.length; i < ii; i++) {
+          _copyFile(path.join(from, dirContents[i]), targetDir, {preserveMode: options.preserveMode});
+        }
+      }
+      // Copying a file
+      else {
+        content = fs.readFileSync(from);
+        let mode = fromStat.mode & 0o777;
+        let targetFile = to;
+
+        if (toStat.isDirectory()) {
+          targetFile = path.join(to, filename);
+        }
+
+        let fileExists = fs.existsSync(targetFile);
+        fs.writeFileSync(targetFile, content);
+
+        // If the file didn't already exist, use the original file mode.
+        // Otherwise, only update the mode if preserverMode is true.
+        if(!fileExists || options.preserveMode) {
+          fs.chmodSync(targetFile, mode);
+        }
+      }
+    }
+    // Dest doesn't exist, can't create it
+    else {
+      throw destDoesNotExistErr;
+    }
+  };
+
+  // Remove the given directory
+  let _rmDir = function (dirPath) {
+    let dir = path.normalize(dirPath);
+    let paths = [];
+    paths = fs.readdirSync(dir);
+    paths.forEach(function (p) {
+      let curr = path.join(dir, p);
+      let stat = fs.lstatSync(curr);
+      if (stat.isDirectory()) {
+        _rmDir(curr);
+      }
+      else {
+        try {
+          fs.unlinkSync(curr);
+        } catch(e) {
+          if (e.code === 'EPERM') {
+            fs.chmodSync(curr, parseInt(666, 8));
+            fs.unlinkSync(curr);
+          } else {
+            throw e;
+          }
+        }
+      }
+    });
+    fs.rmdirSync(dir);
+  };
+
+  /**
+    @name file#cpR
+    @public
+    @function
+    @description Copies a directory/file to a destination
+    @param {String} fromPath The source path to copy from
+    @param {String} toPath The destination path to copy to
+    @param {Object} opts Options to use
+      @param {Boolean} [opts.preserveMode] If target file already exists, this
+        determines whether the original file's mode is copied over. The default of
+        false mimics the behavior of the `cp` command line tool. (Default: false)
+  */
+  this.cpR = function (fromPath, toPath, options) {
+    let from = path.normalize(fromPath);
+    let to = path.normalize(toPath);
+    let toStat;
+    let doesNotExistErr;
+    let filename;
+    let opts = options || {};
+
+    if (from == to) {
+      throw new Error('Cannot copy ' + from + ' to itself.');
+    }
+
+    // Handle rename-via-copy
+    try {
+      toStat = fs.statSync(to);
+    }
+    catch(e) {
+      doesNotExistErr = e;
+
+      // Get abs path so it's possible to check parent dir
+      if (!this.isAbsolute(to)) {
+        to = path.join(process.cwd(), to);
+      }
+
+      // Save the file/dir name
+      filename = path.basename(to);
+      // See if a parent dir exists, so there's a place to put the
+      /// renamed file/dir (resets the destination for the copy)
+      to = path.dirname(to);
+      try {
+        toStat = fs.statSync(to);
+      }
+      catch(e) {}
+      if (toStat && toStat.isDirectory()) {
+        // Set the rename opt to pass to the copy func, will be used
+        // as the new file/dir name
+        opts.rename = filename;
+        //console.log('filename ' + filename);
+      }
+      else {
+        throw doesNotExistErr;
+      }
+    }
+
+    _copyFile(from, to, opts);
+  };
+
+  /**
+    @name file#mkdirP
+    @public
+    @function
+    @description Create the given directory(ies) using the given mode permissions
+    @param {String} dir The directory to create
+    @param {Number} mode The mode to give the created directory(ies)(Default: 0755)
+  */
+  this.mkdirP = function (dir, mode) {
+    let dirPath = path.normalize(dir);
+    let paths = dirPath.split(/\/|\\/);
+    let currPath = '';
+    let next;
+
+    if (paths[0] == '' || /^[A-Za-z]+:/.test(paths[0])) {
+      currPath = paths.shift() || '/';
+      currPath = path.join(currPath, paths.shift());
+      //console.log('basedir');
+    }
+    while ((next = paths.shift())) {
+      if (next == '..') {
+        currPath = path.join(currPath, next);
+        continue;
+      }
+      currPath = path.join(currPath, next);
+      try {
+        //console.log('making ' + currPath);
+        fs.mkdirSync(currPath, mode || parseInt(755, 8));
+      }
+      catch(e) {
+        if (e.code != 'EEXIST') {
+          throw e;
+        }
+      }
+    }
+  };
+
+  /**
+    @name file#rmRf
+    @public
+    @function
+    @description Deletes the given directory/file
+    @param {String} p The path to delete, can be a directory or file
+  */
+  this.rmRf = function (p, options) {
+    let stat;
+    try {
+      stat = fs.lstatSync(p);
+      if (stat.isDirectory()) {
+        _rmDir(p);
+      }
+      else {
+        fs.unlinkSync(p);
+      }
+    }
+    catch (e) {}
+  };
+
+  /**
+    @name file#isAbsolute
+    @public
+    @function
+    @return {Boolean/String} If it's absolute the first character is returned otherwise false
+    @description Checks if a given path is absolute or relative
+    @param {String} p Path to check
+  */
+  this.isAbsolute = function (p) {
+    let match = /^[A-Za-z]+:\\|^\//.exec(p);
+    if (match && match.length) {
+      return match[0];
+    }
+    return false;
+  };
+
+  /**
+    @name file#absolutize
+    @public
+    @function
+    @return {String} Returns the absolute path for the given path
+    @description Returns the absolute path for the given path
+    @param {String} p The path to get the absolute path for
+  */
+  this.absolutize = function (p) {
+    if (this.isAbsolute(p)) {
+      return p;
+    }
+    else {
+      return path.join(process.cwd(), p);
+    }
+  };
+
+})();
+
+module.exports = fileUtils;
+
diff --git a/d2d_app/node_modules/jake/lib/utils/index.js b/d2d_app/node_modules/jake/lib/utils/index.js
new file mode 100644 (file)
index 0000000..17d686b
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+
+let util = require('util'); // Native Node util module
+let spawn = require('child_process').spawn;
+let EventEmitter = require('events').EventEmitter;
+let logger = require('./logger');
+let file = require('./file');
+let Exec;
+
+const _UUID_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
+
+let parseArgs = function (argumentsObj) {
+  let args;
+  let arg;
+  let cmds;
+  let callback;
+  let opts = {
+    interactive: false,
+    printStdout: false,
+    printStderr: false,
+    breakOnError: true
+  };
+
+  args = Array.prototype.slice.call(argumentsObj);
+
+  cmds = args.shift();
+  // Arrayize if passed a single string command
+  if (typeof cmds == 'string') {
+    cmds = [cmds];
+  }
+  // Make a copy if it's an actual list
+  else {
+    cmds = cmds.slice();
+  }
+
+  // Get optional callback or opts
+  while((arg = args.shift())) {
+    if (typeof arg == 'function') {
+      callback = arg;
+    }
+    else if (typeof arg == 'object') {
+      opts = Object.assign(opts, arg);
+    }
+  }
+
+  // Backward-compat shim
+  if (typeof opts.stdout != 'undefined') {
+    opts.printStdout = opts.stdout;
+    delete opts.stdout;
+  }
+  if (typeof opts.stderr != 'undefined') {
+    opts.printStderr = opts.stderr;
+    delete opts.stderr;
+  }
+
+  return {
+    cmds: cmds,
+    opts: opts,
+    callback: callback
+  };
+};
+
+/**
+  @name jake
+  @namespace jake
+*/
+let utils = new (function () {
+  /**
+    @name jake.exec
+    @static
+    @function
+    @description Executes shell-commands asynchronously with an optional
+    final callback.
+    `
+    @param {String[]} cmds The list of shell-commands to execute
+    @param {Object} [opts]
+      @param {Boolean} [opts.printStdout=false] Print stdout from each command
+      @param {Boolean} [opts.printStderr=false] Print stderr from each command
+      @param {Boolean} [opts.breakOnError=true] Stop further execution on
+      the first error.
+      @param {Boolean} [opts.windowsVerbatimArguments=false] Don't translate
+      arguments on Windows.
+    @param {Function} [callback] Callback to run after executing  the
+    commands
+
+    @example
+    let cmds = [
+          'echo "showing directories"'
+        , 'ls -al | grep ^d'
+        , 'echo "moving up a directory"'
+        , 'cd ../'
+        ]
+      , callback = function () {
+          console.log('Finished running commands.');
+        }
+    jake.exec(cmds, {stdout: true}, callback);
+   */
+  this.exec = function (a, b, c) {
+    let parsed = parseArgs(arguments);
+    let cmds = parsed.cmds;
+    let opts = parsed.opts;
+    let callback = parsed.callback;
+
+    let ex = new Exec(cmds, opts, callback);
+
+    ex.addListener('error', function (msg, code) {
+      if (opts.breakOnError) {
+        fail(msg, code);
+      }
+    });
+    ex.run();
+
+    return ex;
+  };
+
+  this.createExec = function (a, b, c) {
+    return new Exec(a, b, c);
+  };
+
+  // From Math.uuid.js, https://github.com/broofa/node-uuid
+  // Robert Kieffer (robert@broofa.com), MIT license
+  this.uuid = function (length, radix) {
+    var chars = _UUID_CHARS
+      , uuid = []
+      , r
+      , i;
+
+    radix = radix || chars.length;
+
+    if (length) {
+      // Compact form
+      i = -1;
+      while (++i < length) {
+        uuid[i] = chars[0 | Math.random()*radix];
+      }
+    } else {
+      // rfc4122, version 4 form
+
+      // rfc4122 requires these characters
+      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
+      uuid[14] = '4';
+
+      // Fill in random data.  At i==19 set the high bits of clock sequence as
+      // per rfc4122, sec. 4.1.5
+      i = -1;
+      while (++i < 36) {
+        if (!uuid[i]) {
+          r = 0 | Math.random()*16;
+          uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
+        }
+      }
+    }
+
+    return uuid.join('');
+  };
+
+})();
+
+Exec = function () {
+  let parsed = parseArgs(arguments);
+  let cmds = parsed.cmds;
+  let opts = parsed.opts;
+  let callback = parsed.callback;
+
+  this._cmds = cmds;
+  this._callback = callback;
+  this._config = opts;
+};
+
+util.inherits(Exec, EventEmitter);
+
+Object.assign(Exec.prototype, new (function () {
+
+  let _run = function () {
+    let self = this;
+    let sh;
+    let cmd;
+    let args;
+    let next = this._cmds.shift();
+    let config = this._config;
+    let errData = '';
+    let shStdio;
+    let handleStdoutData = function (data) {
+      self.emit('stdout', data);
+    };
+    let handleStderrData = function (data) {
+      let d = data.toString();
+      self.emit('stderr', data);
+      // Accumulate the error-data so we can use it as the
+      // stack if the process exits with an error
+      errData += d;
+    };
+
+    // Keep running as long as there are commands in the array
+    if (next) {
+      let spawnOpts = {};
+      this.emit('cmdStart', next);
+
+      // Ganking part of Node's child_process.exec to get cmdline args parsed
+      if (process.platform == 'win32') {
+        cmd = 'cmd';
+        args = ['/c', next];
+        if (config.windowsVerbatimArguments) {
+          spawnOpts.windowsVerbatimArguments = true;
+        }
+      }
+      else {
+        cmd = '/bin/sh';
+        args = ['-c', next];
+      }
+
+      if (config.interactive) {
+        spawnOpts.stdio = 'inherit';
+        sh = spawn(cmd, args, spawnOpts);
+      }
+      else {
+        shStdio = [
+          process.stdin
+        ];
+        if (config.printStdout) {
+          shStdio.push(process.stdout);
+        }
+        else {
+          shStdio.push('pipe');
+        }
+        if (config.printStderr) {
+          shStdio.push(process.stderr);
+        }
+        else {
+          shStdio.push('pipe');
+        }
+        spawnOpts.stdio = shStdio;
+        sh = spawn(cmd, args, spawnOpts);
+        if (!config.printStdout) {
+          sh.stdout.addListener('data', handleStdoutData);
+        }
+        if (!config.printStderr) {
+          sh.stderr.addListener('data', handleStderrData);
+        }
+      }
+
+      // Exit, handle err or run next
+      sh.on('exit', function (code) {
+        let msg;
+        if (code !== 0) {
+          msg = errData || 'Process exited with error.';
+          msg = msg.trim();
+          self.emit('error', msg, code);
+        }
+        if (code === 0 || !config.breakOnError) {
+          self.emit('cmdEnd', next);
+          setTimeout(function () { _run.call(self); }, 0);
+        }
+      });
+
+    }
+    else {
+      self.emit('end');
+      if (typeof self._callback == 'function') {
+        self._callback();
+      }
+    }
+  };
+
+  this.append = function (cmd) {
+    this._cmds.push(cmd);
+  };
+
+  this.run = function () {
+    _run.call(this);
+  };
+
+})());
+
+utils.Exec = Exec;
+utils.file = file;
+utils.logger = logger;
+
+module.exports = utils;
+
diff --git a/d2d_app/node_modules/jake/lib/utils/logger.js b/d2d_app/node_modules/jake/lib/utils/logger.js
new file mode 100644 (file)
index 0000000..8f72686
--- /dev/null
@@ -0,0 +1,24 @@
+let util = require('util');
+
+let logger = new (function () {
+  let _output = function (type, out) {
+    let quiet = typeof jake != 'undefined' && jake.program &&
+        jake.program.opts && jake.program.opts.quiet;
+    let msg;
+    if (!quiet) {
+      msg = typeof out == 'string' ? out : util.inspect(out);
+      console[type](msg);
+    }
+  };
+
+  this.log = function (out) {
+    _output('log', out);
+  };
+
+  this.error = function (out) {
+    _output('error', out);
+  };
+
+})();
+
+module.exports = logger;
diff --git a/d2d_app/node_modules/jake/package.json b/d2d_app/node_modules/jake/package.json
new file mode 100644 (file)
index 0000000..d6c1458
--- /dev/null
@@ -0,0 +1,75 @@
+{
+  "_from": "jake@^10.6.1",
+  "_id": "jake@10.8.2",
+  "_inBundle": false,
+  "_integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
+  "_location": "/jake",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "jake@^10.6.1",
+    "name": "jake",
+    "escapedName": "jake",
+    "rawSpec": "^10.6.1",
+    "saveSpec": null,
+    "fetchSpec": "^10.6.1"
+  },
+  "_requiredBy": [
+    "/ejs"
+  ],
+  "_resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
+  "_shasum": "ebc9de8558160a66d82d0eadc6a2e58fbc500a7b",
+  "_spec": "jake@^10.6.1",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/ejs",
+  "author": {
+    "name": "Matthew Eernisse",
+    "email": "mde@fleegix.org",
+    "url": "http://fleegix.org"
+  },
+  "bin": {
+    "jake": "./bin/cli.js"
+  },
+  "bugs": {
+    "url": "https://github.com/jakejs/jake/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "async": "0.9.x",
+    "chalk": "^2.4.2",
+    "filelist": "^1.0.1",
+    "minimatch": "^3.0.4"
+  },
+  "deprecated": false,
+  "description": "JavaScript build tool, similar to Make or Rake",
+  "devDependencies": {
+    "eslint": "^6.8.0",
+    "mocha": "^7.1.1",
+    "q": "^1.5.1"
+  },
+  "engines": {
+    "node": "*"
+  },
+  "homepage": "https://github.com/jakejs/jake#readme",
+  "keywords": [
+    "build",
+    "cli",
+    "make",
+    "rake"
+  ],
+  "license": "Apache-2.0",
+  "main": "./lib/jake.js",
+  "name": "jake",
+  "preferGlobal": true,
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/jakejs/jake.git"
+  },
+  "scripts": {
+    "lint": "eslint --format codeframe \"lib/**/*.js\" \"test/**/*.js\"",
+    "lint:fix": "eslint --fix \"lib/**/*.js\" \"test/**/*.js\"",
+    "test": "./bin/cli.js test",
+    "test:ci": "npm run lint && npm run test"
+  },
+  "version": "10.8.2"
+}
diff --git a/d2d_app/node_modules/jake/test/integration/concurrent.js b/d2d_app/node_modules/jake/test/integration/concurrent.js
new file mode 100644 (file)
index 0000000..4ae41e8
--- /dev/null
@@ -0,0 +1,42 @@
+let assert = require('assert');
+let exec = require('child_process').execSync;
+
+suite('concurrent', function () {
+
+  this.timeout(7000);
+
+  test(' simple concurrent prerequisites 1', function () {
+    let out = exec('./node_modules/.bin/jake -q concurrent:simple1').toString().trim()
+    assert.equal('Started A\nStarted B\nFinished B\nFinished A', out);
+  });
+
+  test(' simple concurrent prerequisites 2', function () {
+    let out = exec('./node_modules/.bin/jake -q concurrent:simple2').toString().trim()
+    assert.equal('Started C\nStarted D\nFinished C\nFinished D', out);
+  });
+
+  test(' sequential concurrent prerequisites', function () {
+    let out = exec('./node_modules/.bin/jake -q concurrent:seqconcurrent').toString().trim()
+    assert.equal('Started A\nStarted B\nFinished B\nFinished A\nStarted C\nStarted D\nFinished C\nFinished D', out);
+  });
+
+  test(' concurrent concurrent prerequisites', function () {
+    let out = exec('./node_modules/.bin/jake -q concurrent:concurrentconcurrent').toString().trim()
+    assert.equal('Started A\nStarted B\nStarted C\nStarted D\nFinished B\nFinished C\nFinished A\nFinished D', out);
+  });
+
+  test(' concurrent prerequisites with subdependency', function () {
+    let out = exec('./node_modules/.bin/jake -q concurrent:subdep').toString().trim()
+    assert.equal('Started A\nFinished A\nStarted Ba\nFinished Ba', out);
+  });
+
+  test(' failing in concurrent prerequisites', function () {
+    try {
+      exec('./node_modules/.bin/jake -q concurrent:Cfail');
+    }
+    catch(err) {
+      assert(err.message.indexOf('Command failed') > -1);
+    }
+  });
+
+});
diff --git a/d2d_app/node_modules/jake/test/integration/file.js b/d2d_app/node_modules/jake/test/integration/file.js
new file mode 100644 (file)
index 0000000..97ed0d6
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+const PROJECT_DIR = process.env.PROJECT_DIR;
+
+let assert = require('assert');
+let fs = require('fs');
+let path = require('path');
+let file = require(`${PROJECT_DIR}/lib/utils/file`);
+let existsSync = fs.existsSync || path.existsSync;
+let exec = require('child_process').execSync;
+
+suite('fileUtils', function () {
+
+  test('mkdirP', function () {
+    let expected = [
+      ['foo'],
+      ['foo', 'bar'],
+      ['foo', 'bar', 'baz'],
+      ['foo', 'bar', 'baz', 'qux']
+    ];
+    file.mkdirP('foo/bar/baz/qux');
+    let res = exec('find foo').toString().trim().split('\n');
+    for (let i = 0, ii = res.length; i < ii; i++) {
+      assert.equal(path.join.apply(path, expected[i]), res[i]);
+    }
+    file.rmRf('foo');
+  });
+
+  test('rmRf', function () {
+    file.mkdirP('foo/bar/baz/qux');
+    file.rmRf('foo/bar');
+    let res = exec('find foo').toString().trim().split('\n');
+    assert.equal(1, res.length);
+    assert.equal('foo', res[0]);
+    fs.rmdirSync('foo');
+  });
+
+  test('rmRf with symlink subdir', function () {
+    file.mkdirP('foo');
+    file.mkdirP('bar');
+    fs.writeFileSync('foo/hello.txt', 'hello, it\'s me');
+    fs.symlinkSync('../foo', 'bar/foo'); file.rmRf('bar');
+
+    // Make sure the bar directory was successfully deleted
+    let barDeleted = false;
+    try {
+      fs.statSync('bar');
+    } catch(err) {
+      if(err.code == 'ENOENT') {
+        barDeleted = true;
+      }
+    }
+    assert.equal(true, barDeleted);
+
+    // Make sure that the file inside the linked folder wasn't deleted
+    let res = fs.readdirSync('foo');
+    assert.equal(1, res.length);
+    assert.equal('hello.txt', res[0]);
+
+    // Cleanup
+    fs.unlinkSync('foo/hello.txt');
+    fs.rmdirSync('foo');
+  });
+
+  test('rmRf with symlinked dir', function () {
+    file.mkdirP('foo');
+    fs.writeFileSync('foo/hello.txt', 'hello!');
+    fs.symlinkSync('foo', 'bar');
+    file.rmRf('bar');
+
+    // Make sure the bar directory was successfully deleted
+    let barDeleted = false;
+    try {
+      fs.statSync('bar');
+    } catch(err) {
+      if(err.code == 'ENOENT') {
+        barDeleted = true;
+      }
+    }
+    assert.equal(true, barDeleted);
+
+    // Make sure that the file inside the linked folder wasn't deleted
+    let res = fs.readdirSync('foo');
+    assert.equal(1, res.length);
+    assert.equal('hello.txt', res[0]);
+
+    // Cleanup
+    fs.unlinkSync('foo/hello.txt');
+    fs.rmdirSync('foo');
+  });
+
+  test('cpR with same name and different directory', function () {
+    file.mkdirP('foo');
+    fs.writeFileSync('foo/bar.txt', 'w00t');
+    file.cpR('foo', 'bar');
+    assert.ok(existsSync('bar/bar.txt'));
+    file.rmRf('foo');
+    file.rmRf('bar');
+  });
+
+  test('cpR with same to and from will throw', function () {
+    assert.throws(function () {
+      file.cpR('foo.txt', 'foo.txt');
+    });
+  });
+
+  test('cpR rename via copy in directory', function () {
+    file.mkdirP('foo');
+    fs.writeFileSync('foo/bar.txt', 'w00t');
+    file.cpR('foo/bar.txt', 'foo/baz.txt');
+    assert.ok(existsSync('foo/baz.txt'));
+    file.rmRf('foo');
+  });
+
+  test('cpR rename via copy in base', function () {
+    fs.writeFileSync('bar.txt', 'w00t');
+    file.cpR('bar.txt', 'baz.txt');
+    assert.ok(existsSync('baz.txt'));
+    file.rmRf('bar.txt');
+    file.rmRf('baz.txt');
+  });
+
+  test('cpR keeps file mode', function () {
+    fs.writeFileSync('bar.txt', 'w00t', {mode: 0o750});
+    fs.writeFileSync('bar1.txt', 'w00t!', {mode: 0o744});
+    file.cpR('bar.txt', 'baz.txt');
+    file.cpR('bar1.txt', 'baz1.txt');
+
+    assert.ok(existsSync('baz.txt'));
+    assert.ok(existsSync('baz1.txt'));
+    let bazStat = fs.statSync('baz.txt');
+    let bazStat1 = fs.statSync('baz1.txt');
+    assert.equal(0o750, bazStat.mode & 0o7777);
+    assert.equal(0o744, bazStat1.mode & 0o7777);
+
+    file.rmRf('bar.txt');
+    file.rmRf('baz.txt');
+    file.rmRf('bar1.txt');
+    file.rmRf('baz1.txt');
+  });
+
+  test('cpR keeps file mode when overwriting with preserveMode', function () {
+    fs.writeFileSync('bar.txt', 'w00t', {mode: 0o755});
+    fs.writeFileSync('baz.txt', 'w00t!', {mode: 0o744});
+    file.cpR('bar.txt', 'baz.txt', {silent: true, preserveMode: true});
+
+    assert.ok(existsSync('baz.txt'));
+    let bazStat = fs.statSync('baz.txt');
+    assert.equal(0o755, bazStat.mode & 0o777);
+
+    file.rmRf('bar.txt');
+    file.rmRf('baz.txt');
+  });
+
+  test('cpR does not keep file mode when overwriting', function () {
+    fs.writeFileSync('bar.txt', 'w00t', {mode: 0o766});
+    fs.writeFileSync('baz.txt', 'w00t!', {mode: 0o744});
+    file.cpR('bar.txt', 'baz.txt');
+
+    assert.ok(existsSync('baz.txt'));
+    let bazStat = fs.statSync('baz.txt');
+    assert.equal(0o744, bazStat.mode & 0o777);
+
+    file.rmRf('bar.txt');
+    file.rmRf('baz.txt');
+  });
+
+  test('cpR copies file mode recursively', function () {
+    fs.mkdirSync('foo');
+    fs.writeFileSync('foo/bar.txt', 'w00t', {mode: 0o740});
+    file.cpR('foo', 'baz');
+
+    assert.ok(existsSync('baz'));
+    let barStat = fs.statSync('baz/bar.txt');
+    assert.equal(0o740, barStat.mode & 0o777);
+
+    file.rmRf('foo');
+    file.rmRf('baz');
+  });
+
+  test('cpR keeps file mode recursively', function () {
+    fs.mkdirSync('foo');
+    fs.writeFileSync('foo/bar.txt', 'w00t', {mode: 0o740});
+    fs.mkdirSync('baz');
+    fs.mkdirSync('baz/foo');
+    fs.writeFileSync('baz/foo/bar.txt', 'w00t!', {mode: 0o755});
+    file.cpR('foo', 'baz', {silent: true, preserveMode: true});
+
+    assert.ok(existsSync('baz'));
+    let barStat = fs.statSync('baz/foo/bar.txt');
+    assert.equal(0o740, barStat.mode & 0o777);
+
+    file.rmRf('foo');
+    file.rmRf('baz');
+  });
+
+  test('cpR copies directory mode recursively', function () {
+    fs.mkdirSync('foo', 0o755);
+    fs.mkdirSync('foo/bar', 0o700);
+    file.cpR('foo', 'bar');
+
+    assert.ok(existsSync('foo'));
+    let fooBarStat = fs.statSync('bar/bar');
+    assert.equal(0o700, fooBarStat.mode & 0o777);
+
+    file.rmRf('foo');
+    file.rmRf('bar');
+  });
+
+});
+
+
diff --git a/d2d_app/node_modules/jake/test/integration/file_task.js b/d2d_app/node_modules/jake/test/integration/file_task.js
new file mode 100644 (file)
index 0000000..b48f07e
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+const PROJECT_DIR = process.env.PROJECT_DIR;
+
+let assert = require('assert');
+let fs = require('fs');
+let exec = require('child_process').execSync;
+let { rmRf } = require(`${PROJECT_DIR}/lib/jake`);
+
+let cleanUpAndNext = function (callback) {
+  rmRf('./foo', {
+    silent: true
+  });
+  callback && callback();
+};
+
+suite('fileTask', function () {
+  this.timeout(7000);
+
+  setup(function () {
+    cleanUpAndNext();
+  });
+
+  test('where a file-task prereq does not change with --always-make', function () {
+    let out;
+    out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim();
+    assert.equal('fileTest:foo/src1.txt task\nfileTest:foo/from-src1.txt task',
+      out);
+    out = exec('./node_modules/.bin/jake -q -B fileTest:foo/from-src1.txt').toString().trim();
+    assert.equal('fileTest:foo/src1.txt task\nfileTest:foo/from-src1.txt task',
+      out);
+    cleanUpAndNext();
+  });
+
+  test('concating two files', function () {
+    let out;
+    out = exec('./node_modules/.bin/jake -q fileTest:foo/concat.txt').toString().trim();
+    assert.equal('fileTest:foo/src1.txt task\ndefault task\nfileTest:foo/src2.txt task\n' +
+          'fileTest:foo/concat.txt task', out);
+    // Check to see the two files got concat'd
+    let data = fs.readFileSync(process.cwd() + '/foo/concat.txt');
+    assert.equal('src1src2', data.toString());
+    cleanUpAndNext();
+  });
+
+  test('where a file-task prereq does not change', function () {
+    let out;
+    out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim();
+    assert.equal('fileTest:foo/src1.txt task\nfileTest:foo/from-src1.txt task', out);
+    out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim();
+    // Second time should be a no-op
+    assert.equal('', out);
+    cleanUpAndNext();
+  });
+
+  test('where a file-task prereq does change, then does not', function (next) {
+    exec('mkdir -p ./foo');
+    exec('touch ./foo/from-src1.txt');
+    setTimeout(() => {
+      fs.writeFileSync('./foo/src1.txt', '-SRC');
+      // Task should run the first time
+      let out;
+      out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim();
+      assert.equal('fileTest:foo/from-src1.txt task', out);
+      // Task should not run on subsequent invocation
+      out = exec('./node_modules/.bin/jake -q fileTest:foo/from-src1.txt').toString().trim();
+      assert.equal('', out);
+      cleanUpAndNext(next);
+    }, 1000);
+  });
+
+  test('a preexisting file', function () {
+    let prereqData = 'howdy';
+    exec('mkdir -p ./foo');
+    fs.writeFileSync('foo/prereq.txt', prereqData);
+    let out;
+    out = exec('./node_modules/.bin/jake -q fileTest:foo/from-prereq.txt').toString().trim();
+    assert.equal('fileTest:foo/from-prereq.txt task', out);
+    let data = fs.readFileSync(process.cwd() + '/foo/from-prereq.txt');
+    assert.equal(prereqData, data.toString());
+    out = exec('./node_modules/.bin/jake -q fileTest:foo/from-prereq.txt').toString().trim();
+    // Second time should be a no-op
+    assert.equal('', out);
+    cleanUpAndNext();
+  });
+
+  test('a preexisting file with --always-make flag', function () {
+    let prereqData = 'howdy';
+    exec('mkdir -p ./foo');
+    fs.writeFileSync('foo/prereq.txt', prereqData);
+    let out;
+    out = exec('./node_modules/.bin/jake -q fileTest:foo/from-prereq.txt').toString().trim();
+    assert.equal('fileTest:foo/from-prereq.txt task', out);
+    let data = fs.readFileSync(process.cwd() + '/foo/from-prereq.txt');
+    assert.equal(prereqData, data.toString());
+    out = exec('./node_modules/.bin/jake -q -B fileTest:foo/from-prereq.txt').toString().trim();
+    assert.equal('fileTest:foo/from-prereq.txt task', out);
+    cleanUpAndNext();
+  });
+
+  test('nested directory-task', function () {
+    exec('./node_modules/.bin/jake -q fileTest:foo/bar/baz/bamf.txt');
+    let data = fs.readFileSync(process.cwd() + '/foo/bar/baz/bamf.txt');
+    assert.equal('w00t', data);
+    cleanUpAndNext();
+  });
+
+});
+
diff --git a/d2d_app/node_modules/jake/test/integration/helpers.js b/d2d_app/node_modules/jake/test/integration/helpers.js
new file mode 100644 (file)
index 0000000..9caaa4e
--- /dev/null
@@ -0,0 +1,80 @@
+var exec = require('child_process').exec;
+
+var helpers = new (function () {
+  var _tests;
+  var _names = [];
+  var _name;
+  var _callback;
+  var _runner = function () {
+    if ((_name = _names.shift())) {
+      console.log('Running ' + _name);
+      _tests[_name]();
+    }
+    else {
+      _callback();
+    }
+  };
+
+  this.exec = function () {
+    var args = Array.prototype.slice.call(arguments);
+    var arg;
+    var cmd = args.shift();
+    var opts = {};
+    var callback;
+    // Optional opts/callback or callback/opts
+    while ((arg = args.shift())) {
+      if (typeof arg == 'function') {
+        callback = arg;
+      }
+      else {
+        opts = arg;
+      }
+    }
+
+    cmd += ' --trace';
+    var execOpts = opts.execOpts ? opts.execOpts : {};
+    exec(cmd, execOpts, function (err, stdout, stderr) {
+      var out = helpers.trim(stdout);
+      if (err) {
+        if (opts.breakOnError === false) {
+          return callback(err);
+        }
+        else {
+          throw err;
+        }
+      }
+      if (stderr) {
+        callback(stderr);
+      }
+      else {
+        callback(out);
+      }
+    });
+  };
+
+  this.trim = function (s) {
+    var str = s || '';
+    return str.replace(/^\s*|\s*$/g, '');
+  };
+
+  this.parse = function (s) {
+    var str = s || '';
+    str = helpers.trim(str);
+    str = str.replace(/'/g, '"');
+    return JSON.parse(str);
+  };
+
+  this.run = function (tests, callback) {
+    _tests = tests;
+    _names = Object.keys(tests);
+    _callback = callback;
+    _runner();
+  };
+
+  this.next = function () {
+    _runner();
+  };
+
+})();
+
+module.exports = helpers;
diff --git a/d2d_app/node_modules/jake/test/integration/jakefile.js b/d2d_app/node_modules/jake/test/integration/jakefile.js
new file mode 100644 (file)
index 0000000..f3b7d1a
--- /dev/null
@@ -0,0 +1,337 @@
+let fs = require('fs');
+let Q = require('q');
+
+desc('The default t.');
+task('default', function () {
+  console.log('default task');
+});
+
+desc('No action.');
+task({'noAction': ['default']});
+
+desc('No action, no prereqs.');
+task('noActionNoPrereqs');
+
+desc('Top-level zerbofrangazoomy task');
+task('zerbofrangazoomy', function () {
+  console.log('Whaaaaaaaa? Ran the zerbofrangazoomy task!')
+});
+
+desc('Task that throws');
+task('throwy', function () {
+  let errorListener = function (err) {
+    console.log('Emitted');
+    console.log(err.toString());
+
+    jake.removeListener('error', errorListener);
+  };
+
+  jake.on('error', errorListener);
+
+  throw new Error('I am bad');
+});
+
+desc('Task that rejects a Promise');
+task('promiseRejecter', function () {
+  const originalOption = jake.program.opts['allow-rejection'];
+
+  const errorListener = function (err) {
+    console.log(err.toString());
+    jake.removeListener('error', errorListener);
+    jake.program.opts['allow-rejection'] = originalOption; // Restore original 'allow-rejection' option
+  };
+  jake.on('error', errorListener);
+
+  jake.program.opts['allow-rejection'] = false; // Do not allow rejection so the rejection is passed to error handlers
+
+  Promise.reject('<promise rejected on purpose>');
+});
+
+desc('Accepts args and env vars.');
+task('argsEnvVars', function () {
+  let res = {
+    args: arguments
+    , env: {
+      foo: process.env.foo
+      , baz: process.env.baz
+    }
+  };
+  console.log(JSON.stringify(res));
+});
+
+namespace('foo', function () {
+  desc('The foo:bar t.');
+  task('bar', function () {
+    if (arguments.length) {
+      console.log('foo:bar[' +
+          Array.prototype.join.call(arguments, ',') +
+          '] task');
+    }
+    else {
+      console.log('foo:bar task');
+    }
+  });
+
+  desc('The foo:baz task, calls foo:bar as a prerequisite.');
+  task('baz', ['foo:bar'], function () {
+    console.log('foo:baz task');
+  });
+
+  desc('The foo:qux task, calls foo:bar with cmdline args as a prerequisite.');
+  task('qux', ['foo:bar[asdf,qwer]'], function () {
+    console.log('foo:qux task');
+  });
+
+  desc('The foo:frang task,`invokes` foo:bar with passed args as a prerequisite.');
+  task('frang', function () {
+    let t = jake.Task['foo:bar'];
+    // Do args pass-through
+    t.invoke.apply(t, arguments);
+    t.on('complete', () => {
+      console.log('foo:frang task');
+    });
+  });
+
+  desc('The foo:zerb task, `executes` foo:bar with passed args as a prerequisite.');
+  task('zerb', function () {
+    let t = jake.Task['foo:bar'];
+    // Do args pass-through
+    t.execute.apply(t, arguments);
+    t.on('complete', () => {
+      console.log('foo:zerb task');
+    });
+  });
+
+  desc('The foo:zoobie task, has no prerequisites.');
+  task('zoobie', function () {
+    console.log('foo:zoobie task');
+  });
+
+  desc('The foo:voom task, run the foo:zoobie task repeatedly.');
+  task('voom', function () {
+    let t = jake.Task['foo:bar'];
+    t.on('complete', function () {
+      console.log('complete');
+    });
+    t.execute.apply(t);
+    t.execute.apply(t);
+  });
+
+  desc('The foo:asdf task, has the same prereq twice.');
+  task('asdf', ['foo:bar', 'foo:baz'], function () {
+    console.log('foo:asdf task');
+  });
+
+});
+
+namespace('bar', function () {
+  desc('The bar:foo task, has no prerequisites, is async, returns Promise which resolves.');
+  task('foo', async function () {
+    return new Promise((resolve, reject) => {
+      console.log('bar:foo task');
+      resolve();
+    });
+  });
+
+  desc('The bar:promise task has no prerequisites, is async, returns Q-based promise.');
+  task('promise', function () {
+    return Q()
+      .then(function () {
+        console.log('bar:promise task');
+        return 123654;
+      });
+  });
+
+  desc('The bar:dependOnpromise task waits for a promise based async test');
+  task('dependOnpromise', ['promise'], function () {
+    console.log('bar:dependOnpromise task saw value', jake.Task["bar:promise"].value);
+  });
+
+  desc('The bar:brokenPromise task is a failing Q-promise based async task.');
+  task('brokenPromise', function () {
+    return Q()
+      .then(function () {
+        throw new Error("nom nom nom");
+      });
+  });
+
+  desc('The bar:bar task, has the async bar:foo task as a prerequisite.');
+  task('bar', ['bar:foo'], function () {
+    console.log('bar:bar task');
+  });
+
+});
+
+namespace('hoge', function () {
+  desc('The hoge:hoge task, has no prerequisites.');
+  task('hoge', function () {
+    console.log('hoge:hoge task');
+  });
+
+  desc('The hoge:piyo task, has no prerequisites.');
+  task('piyo', function () {
+    console.log('hoge:piyo task');
+  });
+
+  desc('The hoge:fuga task, has hoge:hoge and hoge:piyo as prerequisites.');
+  task('fuga', ['hoge:hoge', 'hoge:piyo'], function () {
+    console.log('hoge:fuga task');
+  });
+
+  desc('The hoge:charan task, has hoge:fuga as a prerequisite.');
+  task('charan', ['hoge:fuga'], function () {
+    console.log('hoge:charan task');
+  });
+
+  desc('The hoge:gero task, has hoge:fuga as a prerequisite.');
+  task('gero', ['hoge:fuga'], function () {
+    console.log('hoge:gero task');
+  });
+
+  desc('The hoge:kira task, has hoge:charan and hoge:gero as prerequisites.');
+  task('kira', ['hoge:charan', 'hoge:gero'], function () {
+    console.log('hoge:kira task');
+  });
+
+});
+
+namespace('fileTest', function () {
+  directory('foo');
+
+  desc('File task, concatenating two files together');
+  file('foo/concat.txt', ['fileTest:foo', 'fileTest:foo/src1.txt', 'fileTest:foo/src2.txt'], function () {
+    console.log('fileTest:foo/concat.txt task');
+    let data1 = fs.readFileSync('foo/src1.txt');
+    let data2 = fs.readFileSync('foo/src2.txt');
+    fs.writeFileSync('foo/concat.txt', data1 + data2);
+  });
+
+  desc('File task, async creation with writeFile');
+  file('foo/src1.txt', function () {
+    return new Promise(function (resolve, reject) {
+      fs.writeFile('foo/src1.txt', 'src1', function (err) {
+        if (err) {
+          reject(err);
+        }
+        else {
+          console.log('fileTest:foo/src1.txt task');
+          resolve();
+        }
+      });
+    });
+  });
+
+  desc('File task, sync creation with writeFileSync');
+  file('foo/src2.txt', ['default'], function () {
+    fs.writeFileSync('foo/src2.txt', 'src2');
+    console.log('fileTest:foo/src2.txt task');
+  });
+
+  desc('File task, do not run unless the prereq file changes');
+  file('foo/from-src1.txt', ['fileTest:foo', 'fileTest:foo/src1.txt'], function () {
+    let data = fs.readFileSync('foo/src1.txt').toString();
+    fs.writeFileSync('foo/from-src1.txt', data);
+    console.log('fileTest:foo/from-src1.txt task');
+  });
+
+  desc('File task, run if the prereq file changes');
+  task('touch-prereq', function () {
+    fs.writeFileSync('foo/prereq.txt', 'UPDATED');
+  })
+
+  desc('File task, has a preexisting file (with no associated task) as a prereq');
+  file('foo/from-prereq.txt', ['fileTest:foo', 'foo/prereq.txt'], function () {
+    let data = fs.readFileSync('foo/prereq.txt');
+    fs.writeFileSync('foo/from-prereq.txt', data);
+    console.log('fileTest:foo/from-prereq.txt task');
+  });
+
+  directory('foo/bar/baz');
+
+  desc('Write a file in a nested subdirectory');
+  file('foo/bar/baz/bamf.txt', ['foo/bar/baz'], function () {
+    fs.writeFileSync('foo/bar/baz/bamf.txt', 'w00t');
+  });
+
+});
+
+task('blammo');
+// Define task
+task('voom', ['blammo'], function () {
+  console.log(this.prereqs.length);
+});
+
+// Modify, add a prereq
+task('voom', ['noActionNoPrereqs']);
+
+namespace('vronk', function () {
+  task('groo', function () {
+    let t = jake.Task['vronk:zong'];
+    t.addListener('error', function (e) {
+      console.log(e.message);
+    });
+    t.invoke();
+  });
+  task('zong', function () {
+    throw new Error('OMFGZONG');
+  });
+});
+
+// define namespace
+namespace('one', function () {
+  task('one', function () {
+    console.log('one:one');
+  });
+});
+
+// modify namespace (add task)
+namespace('one', function () {
+  task('two', ['one:one'], function () {
+    console.log('one:two');
+  });
+});
+
+task('selfdepconst', [], function () {
+  task('selfdep', ['selfdep'], function () {
+    console.log("I made a task that depends on itself");
+  });
+});
+task('selfdepdyn', function () {
+  task('selfdeppar', [], {concurrency: 2}, function () {
+    console.log("I will depend on myself and will fail at runtime");
+  });
+  task('selfdeppar', ['selfdeppar']);
+  jake.Task['selfdeppar'].invoke();
+});
+
+namespace("large", function () {
+  task("leaf", function () {
+    console.log("large:leaf");
+  });
+
+  const same = [];
+  for (let i = 0; i < 2000; i++) {
+    same.push("leaf");
+  }
+
+  desc("Task with a large number of same prereqs");
+  task("same", same, { concurrency: 2 }, function () {
+    console.log("large:same");
+  });
+
+  const different = [];
+  for (let i = 0; i < 2000; i++) {
+    const name = "leaf-" + i;
+    task(name, function () {
+      if (name === "leaf-12" || name === "leaf-123") {
+        console.log(name);
+      }
+    });
+    different.push(name);
+  }
+
+  desc("Task with a large number of different prereqs");
+  task("different", different, { concurrency: 2 } , function () {
+    console.log("large:different")
+  })
+});
diff --git a/d2d_app/node_modules/jake/test/integration/jakelib/concurrent.jake.js b/d2d_app/node_modules/jake/test/integration/jakelib/concurrent.jake.js
new file mode 100644 (file)
index 0000000..684c86f
--- /dev/null
@@ -0,0 +1,113 @@
+
+namespace('concurrent', function () {
+  task('A', function () {
+    console.log('Started A');
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        console.log('Finished A');
+        resolve();
+      }, 200);
+    });
+  });
+
+  task('B', function () {
+    console.log('Started B');
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        console.log('Finished B');
+        resolve();
+      }, 50);
+    });
+  });
+
+  task('C', function () {
+    console.log('Started C');
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        console.log('Finished C');
+        resolve();
+      }, 100);
+    });
+  });
+
+  task('D', function () {
+    console.log('Started D');
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        console.log('Finished D');
+        resolve();
+      }, 300);
+    });
+  });
+
+  task('Ba', ['A'], function () {
+    console.log('Started Ba');
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        console.log('Finished Ba');
+        resolve();
+      }, 50);
+    });
+  });
+
+  task('Afail', function () {
+    console.log('Started failing task');
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        console.log('Failing B with error');
+        throw new Error('I failed');
+      }, 50);
+    });
+  });
+
+  task('simple1', ['A','B'], {concurrency: 2}, function () {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        resolve();
+      }, 50);
+    });
+  });
+
+  task('simple2', ['C','D'], {concurrency: 2}, function () {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        resolve();
+      }, 50);
+    });
+  });
+
+  task('seqconcurrent', ['simple1','simple2'], function () {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        resolve();
+      }, 50);
+    });
+  });
+
+  task('concurrentconcurrent', ['simple1','simple2'], {concurrency: 2}, function () {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        resolve();
+      }, 50);
+    });
+  });
+
+  task('subdep', ['A','Ba'], {concurrency: 2}, function () {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        resolve();
+      }, 50);
+    });
+  });
+
+  task('fail', ['A', 'B', 'Afail'], {concurrency: 3}, function () {
+    return new Promise((resolve, reject) => {
+      setTimeout(() => {
+        resolve();
+      }, 50);
+    });
+  });
+
+});
+
+
diff --git a/d2d_app/node_modules/jake/test/integration/jakelib/publish.jake.js b/d2d_app/node_modules/jake/test/integration/jakelib/publish.jake.js
new file mode 100644 (file)
index 0000000..52dd04a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+const PROJECT_DIR = process.env.PROJECT_DIR;
+
+let fs = require('fs');
+let { publishTask, rmRf, mkdirP } = require(`${PROJECT_DIR}/lib/jake`);
+
+fs.writeFileSync('package.json', '{"version": "0.0.1"}');
+mkdirP('tmp_publish');
+fs.writeFileSync('tmp_publish/foo.txt', 'FOO');
+
+publishTask('zerb', function () {
+  this.packageFiles.include([
+    'package.json'
+    , 'tmp_publish/**'
+  ]);
+  this.publishCmd = 'node -p -e "\'%filename\'"';
+  this.gitCmd = 'echo'
+  this.scheduleDelay = 0;
+
+  this._ensureRepoClean = function () {};
+  this._getCurrentBranch = function () {
+    return 'v0.0'
+  };
+});
+
+jake.setTaskTimeout(5000);
+
+jake.Task['publish'].on('complete', function () {
+  rmRf('tmp_publish', {silent: true});
+  rmRf('package.json', {silent: true});
+});
+
diff --git a/d2d_app/node_modules/jake/test/integration/jakelib/required_module.jake.js b/d2d_app/node_modules/jake/test/integration/jakelib/required_module.jake.js
new file mode 100644 (file)
index 0000000..c63751d
--- /dev/null
@@ -0,0 +1,10 @@
+let { task, namespace } = require("jake");
+
+namespace('usingRequire', function () {
+  task('test', () => {
+    console.log('howdy test');
+  });
+});
+
+
+
diff --git a/d2d_app/node_modules/jake/test/integration/jakelib/rule.jake.js b/d2d_app/node_modules/jake/test/integration/jakelib/rule.jake.js
new file mode 100644 (file)
index 0000000..8e977dd
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+const PROJECT_DIR = process.env.PROJECT_DIR;
+
+let exec = require('child_process').execSync;
+let fs = require('fs');
+let util = require('util');
+let { rule, rmRf } = require(`${PROJECT_DIR}/lib/jake`);
+
+directory('tmpsrc');
+directory('tmpbin');
+
+////////////////////////////////////////////////////////////
+// Simple Suffix Rule
+file('tmp', ['tmp_init', 'tmp_dep1.o', 'tmp_dep2.o'], function (params) {
+  console.log('tmp task');
+  let data1 = fs.readFileSync('tmp_dep1.o');
+  let data2 = fs.readFileSync('tmp_dep2.o');
+  fs.writeFileSync('tmp', data1 + data2);
+});
+
+rule('.o', '.c', function () {
+  let cmd = util.format('cp %s %s', this.source, this.name);
+  console.log(cmd + ' task');
+  exec(cmd);
+});
+
+file('tmp_dep1.c', function () {
+  fs.writeFileSync('tmp_dep1.c', 'src_1');
+  console.log('tmp_dep1.c task');
+});
+
+// note that tmp_dep2.o depends on tmp_dep2.c, which is a
+// static file.
+task('tmp_init', function () {
+  fs.writeFileSync('tmp_dep2.c', 'src_2');
+  console.log('tmp_dep2.c task');
+});
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Pattern Rule
+file('tmp_p', ['tmp_init', 'tmp_dep1.oo', 'tmp_dep2.oo'], function (params) {
+  console.log('tmp pattern task');
+  let data1 = fs.readFileSync('tmp_dep1.oo');
+  let data2 = fs.readFileSync('tmp_dep2.oo');
+  fs.writeFileSync('tmp_p', data1 + data2 + ' pattern');
+});
+
+rule('%.oo', '%.c', function () {
+  let cmd = util.format('cp %s %s', this.source, this.name);
+  console.log(cmd + ' task');
+  exec(cmd);
+});
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Pattern Rule with Folder
+// i.e.  rule('tmpbin/%.oo', 'tmpsrc/%.c', ...
+file('tmp_pf', [
+  'tmp_src_init'
+  , 'tmpbin'
+  , 'tmpbin/tmp_dep1.oo'
+  , 'tmpbin/tmp_dep2.oo' ], function (params) {
+  console.log('tmp pattern folder task');
+  let data1 = fs.readFileSync('tmpbin/tmp_dep1.oo');
+  let data2 = fs.readFileSync('tmpbin/tmp_dep2.oo');
+  fs.writeFileSync('tmp_pf', data1 + data2 + ' pattern folder');
+});
+
+rule('tmpbin/%.oo', 'tmpsrc/%.c', function () {
+  let cmd = util.format('cp %s %s', this.source, this.name);
+  console.log(cmd + ' task');
+  exec(cmd);
+});
+
+file('tmpsrc/tmp_dep2.c',['tmpsrc'], function () {
+  fs.writeFileSync('tmpsrc/tmp_dep2.c', 'src/src_2');
+  console.log('tmpsrc/tmp_dep2.c task');
+});
+
+// Create static files in folder tmpsrc.
+task('tmp_src_init', ['tmpsrc'], function () {
+  fs.writeFileSync('tmpsrc/tmp_dep1.c', 'src/src_1');
+  console.log('tmpsrc/tmp_dep1.c task');
+});
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+// Namespace Test. This is a Mixed Test.
+// Test for
+// -  rules belonging to different namespace.
+// -  rules with folder and pattern
+task('tmp_ns', [
+  'tmpbin'
+  , 'rule:init'
+  , 'tmpbin/tmp_dep2.oo'    // *** This relies on a rule defined before.
+  , 'rule:tmpbin/dep1.oo'
+  , 'rule:tmpbin/file2.oo' ], function () {
+  console.log('tmp pattern folder namespace task');
+  let data1 = fs.readFileSync('tmpbin/dep1.oo');
+  let data2 = fs.readFileSync('tmpbin/tmp_dep2.oo');
+  let data3 = fs.readFileSync('tmpbin/file2.oo');
+  fs.writeFileSync('tmp_ns', data1 + data2 + data3 + ' pattern folder namespace');
+});
+
+namespace('rule', function () {
+  task('init', ['tmpsrc'], function () {
+    fs.writeFileSync('tmpsrc/file2.c', 'src/src_3');
+    console.log('tmpsrc/file2.c init task');
+  });
+
+  file('tmpsrc/dep1.c',['tmpsrc'], function () {
+    fs.writeFileSync('tmpsrc/dep1.c', 'src/src_1');
+    console.log('tmpsrc/dep1.c task');
+  }, {async: true});
+
+  rule('tmpbin/%.oo', 'tmpsrc/%.c', function () {
+    let cmd = util.format('cp %s %s', this.source, this.name);
+    console.log(cmd + ' ns task');
+    exec(cmd);
+  });
+});
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Chain rule
+// rule('tmpbin/%.pdf', 'tmpbin/%.dvi', function() { ...
+// rule('tmpbin/%.dvi', 'tmpsrc/%.tex', ['tmpbin'], function() { ...
+task('tmp_cr', [
+  'chainrule:init'
+  , 'chainrule:tmpbin/file1.pdf'
+  , 'chainrule:tmpbin/file2.pdf' ], function () {
+  console.log('tmp chainrule namespace task');
+  let data1 = fs.readFileSync('tmpbin/file1.pdf');
+  let data2 = fs.readFileSync('tmpbin/file2.pdf');
+  fs.writeFileSync('tmp_cr', data1 + data2 + ' chainrule namespace');
+});
+
+namespace('chainrule', function () {
+  task('init', ['tmpsrc', 'tmpbin'], function () {
+    fs.writeFileSync('tmpsrc/file1.tex', 'tex1 ');
+    fs.writeFileSync('tmpsrc/file2.tex', 'tex2 ');
+    console.log('chainrule init task');
+  });
+
+  rule('tmpbin/%.pdf', 'tmpbin/%.dvi', function () {
+    let cmd = util.format('cp %s %s', this.source, this.name);
+    console.log(cmd + ' dvi->pdf task');
+    exec(cmd);
+  });
+
+  rule('tmpbin/%.dvi', 'tmpsrc/%.tex', ['tmpbin'], function () {
+    let cmd = util.format('cp %s %s', this.source, this.name);
+    console.log(cmd + ' tex->dvi task');
+    exec(cmd);
+  });
+});
+////////////////////////////////////////////////////////////
+namespace('precedence', function () {
+  task('test', ['foo.html'], function () {
+    console.log('ran test');
+  });
+
+  rule('.html', '.txt', function () {
+    console.log('created html');
+    let data = fs.readFileSync(this.source);
+    fs.writeFileSync(this.name, data.toString());
+  });
+});
+
+namespace('regexPattern', function () {
+  task('test', ['foo.html'], function () {
+    console.log('ran test');
+  });
+
+  rule(/\.html$/, '.txt', function () {
+    console.log('created html');
+    let data = fs.readFileSync(this.source);
+    fs.writeFileSync(this.name, data.toString());
+  });
+});
+
+namespace('sourceFunction', function () {
+
+  let srcFunc = function (taskName) {
+    return taskName.replace(/\.[^.]+$/, '.txt');
+  };
+
+  task('test', ['foo.html'], function () {
+    console.log('ran test');
+  });
+
+  rule('.html', srcFunc, function () {
+    console.log('created html');
+    let data = fs.readFileSync(this.source);
+    fs.writeFileSync(this.name, data.toString());
+  });
+});
+
+////////////////////////////////////////////////////////////
+task('clean', function () {
+  rmRf('./foo');
+  rmRf('./tmp');
+});
diff --git a/d2d_app/node_modules/jake/test/integration/publish_task.js b/d2d_app/node_modules/jake/test/integration/publish_task.js
new file mode 100644 (file)
index 0000000..034fd94
--- /dev/null
@@ -0,0 +1,24 @@
+let assert = require('assert');
+let exec = require('child_process').execSync;
+
+suite('publishTask', function () {
+
+  this.timeout(7000);
+
+  test('default task', function () {
+    let out = exec('./node_modules/.bin/jake  -q publish').toString().trim();
+    let expected = [
+      'Fetched remote tags.'
+      , 'On branch v0.0'
+      , 'Bumped version number to v0.0.2.'
+      , 'Created package for zerb v0.0.2'
+      , 'Publishing zerb v0.0.2'
+      , './pkg/zerb-v0.0.2.tar.gz'
+      , 'BOOM! Published.'
+      , 'Cleaned up package'
+    ].join('\n');
+    assert.equal(expected, out);
+  });
+
+});
+
diff --git a/d2d_app/node_modules/jake/test/integration/rule.js b/d2d_app/node_modules/jake/test/integration/rule.js
new file mode 100644 (file)
index 0000000..b837b1d
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+const PROJECT_DIR = process.env.PROJECT_DIR;
+
+let assert = require('assert');
+let exec = require('child_process').execSync;
+let fs = require('fs');
+let { Rule } = require(`${PROJECT_DIR}/lib/rule`);
+let { rmRf } = require(`${PROJECT_DIR}/lib/jake`);
+
+let cleanUpAndNext = function (callback) {
+  // Gotta add globbing to file utils rmRf
+  let tmpFiles = [
+    'tmp'
+    , 'tmp_ns'
+    , 'tmp_cr'
+    , 'tmp_p'
+    , 'tmp_pf'
+    , 'tmpbin'
+    , 'tmpsrc'
+    , 'tmp_dep1.c'
+    , 'tmp_dep1.o'
+    , 'tmp_dep1.oo'
+    , 'tmp_dep2.c'
+    , 'tmp_dep2.o'
+    , 'tmp_dep2.oo'
+    , 'foo'
+    , 'foo.html'
+  ];
+  tmpFiles.forEach(function (f) {
+    rmRf(f, {
+      silent: true
+    });
+  });
+  callback && callback();
+};
+
+suite('rule', function () {
+
+  this.timeout(7000);
+
+  setup(function (next) {
+    cleanUpAndNext(next);
+  });
+
+
+  //  - name   foo:bin/main.o
+  //  - pattern    bin/%.o
+  //  - source    src/%.c
+  //
+  // return {
+  //    'dep' : 'foo:src/main.c',
+  //    'file': 'src/main.c'
+  //  };
+  test('Rule.getSource', function () {
+    let src = Rule.getSource('foo:bin/main.o', 'bin/%.o', 'src/%.c');
+    assert.equal('foo:src/main.c', src);
+  });
+
+  test('rule w/o pattern', function () {
+    let out = exec( './node_modules/.bin/jake -q  tmp').toString().trim();
+    let output = [
+      "tmp_dep2.c task"
+      , "tmp_dep1.c task"
+      , "cp tmp_dep1.c tmp_dep1.o task"
+      , "cp tmp_dep2.c tmp_dep2.o task"
+      , "tmp task"];
+    assert.equal( output.join('\n'), out);
+    let data = fs.readFileSync(process.cwd() + '/tmp');
+    assert.equal('src_1src_2', data.toString());
+    cleanUpAndNext();
+  });
+
+  test('rule w pattern w/o folder w/o namespace', function () {
+    let out = exec( './node_modules/.bin/jake  -q  tmp_p').toString().trim();
+    let output = [
+      "tmp_dep2.c task"
+      , "tmp_dep1.c task"
+      , "cp tmp_dep1.c tmp_dep1.oo task"
+      , "cp tmp_dep2.c tmp_dep2.oo task"
+      , "tmp pattern task"];
+    let data;
+    assert.equal( output.join('\n'), out);
+    data = fs.readFileSync(process.cwd() + '/tmp_p');
+    assert.equal('src_1src_2 pattern', data.toString());
+    cleanUpAndNext();
+  });
+
+  test('rule w pattern w folder w/o namespace', function () {
+    let out = exec( './node_modules/.bin/jake  -q  tmp_pf').toString().trim();
+    let output = [
+      "tmpsrc/tmp_dep1.c task"
+      , "cp tmpsrc/tmp_dep1.c tmpbin/tmp_dep1.oo task"
+      , "tmpsrc/tmp_dep2.c task"
+      , "cp tmpsrc/tmp_dep2.c tmpbin/tmp_dep2.oo task"
+      , "tmp pattern folder task"];
+    let data;
+    assert.equal( output.join('\n'), out);
+    data = fs.readFileSync(process.cwd() + '/tmp_pf');
+    assert.equal('src/src_1src/src_2 pattern folder', data.toString());
+    cleanUpAndNext();
+  });
+
+  test.skip('rule w pattern w folder w namespace', function () {
+    let out = exec( './node_modules/.bin/jake -q   tmp_ns').toString().trim();
+    let output = [
+      "tmpsrc/file2.c init task" // yes
+      , "tmpsrc/tmp_dep2.c task" // no
+      , "cp tmpsrc/tmp_dep2.c tmpbin/tmp_dep2.oo task" // no
+      , "tmpsrc/dep1.c task" // no
+      , "cp tmpsrc/dep1.c tmpbin/dep1.oo ns task" // no
+      , "cp tmpsrc/file2.c tmpbin/file2.oo ns task" // yes
+      , "tmp pattern folder namespace task"]; // yes
+    let data;
+    assert.equal( output.join('\n'), out);
+    data = fs.readFileSync(process.cwd() + '/tmp_ns');
+    assert.equal('src/src_1src/src_2src/src_3 pattern folder namespace', data.toString());
+    cleanUpAndNext();
+  });
+
+  test.skip('rule w chain w pattern w folder w namespace', function () {
+    let out = exec( './node_modules/.bin/jake -q tmp_cr').toString().trim();
+    let output = [
+      "chainrule init task"
+      , "cp tmpsrc/file1.tex tmpbin/file1.dvi tex->dvi task"
+      , "cp tmpbin/file1.dvi tmpbin/file1.pdf dvi->pdf task"
+      , "cp tmpsrc/file2.tex tmpbin/file2.dvi tex->dvi task"
+      , "cp tmpbin/file2.dvi tmpbin/file2.pdf dvi->pdf task"
+      , "tmp chainrule namespace task"];
+    let data;
+    assert.equal( output.join('\n'), out);
+    data = fs.readFileSync(process.cwd() + '/tmp_cr');
+    assert.equal('tex1 tex2  chainrule namespace', data.toString());
+    cleanUpAndNext();
+  });
+
+
+  ['precedence', 'regexPattern', 'sourceFunction'].forEach(function (key) {
+
+    test('rule with source file not created yet (' + key  + ')', function () {
+      let write = process.stderr.write;
+      process.stderr.write = () => {};
+      rmRf('foo.txt', {silent: true});
+      rmRf('foo.html', {silent: true});
+      try {
+        exec('./node_modules/.bin/jake  ' + key + ':test');
+      }
+      catch(err) {
+        // foo.txt prereq doesn't exist yet
+        assert.ok(err.message.indexOf('Unknown task "foo.html"') > -1);
+      }
+      process.stderr.write = write;
+    });
+
+    test('rule with source file now created (' + key  + ')', function () {
+      fs.writeFileSync('foo.txt', '');
+      let out = exec('./node_modules/.bin/jake -q  ' + key + ':test').toString().trim();
+      // Should run prereq and test task
+      let output = [
+        'created html'
+        , 'ran test'
+      ];
+      assert.equal(output.join('\n'), out);
+    });
+
+    test('rule with source file modified (' + key  + ')', function (next) {
+      setTimeout(function () {
+        fs.writeFileSync('foo.txt', '');
+        let out = exec('./node_modules/.bin/jake -q  ' + key + ':test').toString().trim();
+        // Should again run both prereq and test task
+        let output = [
+          'created html'
+          , 'ran test'
+        ];
+        assert.equal(output.join('\n'), out);
+        //next();
+        cleanUpAndNext(next);
+      }, 1000); // Wait to do the touch to ensure mod-time is different
+    });
+
+    test('rule with existing objective file and no source ' +
+        ' (should be normal file-task) (' + key  + ')', function () {
+      // Remove just the source file
+      fs.writeFileSync('foo.html', '');
+      rmRf('foo.txt', {silent: true});
+      let out = exec('./node_modules/.bin/jake -q  ' + key + ':test').toString().trim();
+      // Should treat existing objective file as plain file-task,
+      // and just run test-task
+      let output = [
+        'ran test'
+      ];
+      assert.equal(output.join('\n'), out);
+      cleanUpAndNext();
+    });
+
+  });
+
+});
+
+
diff --git a/d2d_app/node_modules/jake/test/integration/selfdep.js b/d2d_app/node_modules/jake/test/integration/selfdep.js
new file mode 100644 (file)
index 0000000..22d58d1
--- /dev/null
@@ -0,0 +1,39 @@
+let assert = require('assert');
+let exec = require('child_process').execSync;
+
+suite('selfDep', function () {
+
+  this.timeout(7000);
+
+  let origStderrWrite;
+
+  setup(function () {
+    origStderrWrite = process.stderr.write;
+    process.stderr.write = function () {};
+  });
+
+  teardown(function () {
+    process.stderr.write = origStderrWrite;
+  });
+
+  test('self dep const', function () {
+    try {
+      exec('./node_modules/.bin/jake selfdepconst');
+    }
+    catch(e) {
+      assert(e.message.indexOf('dependency of itself') > -1)
+    }
+  });
+
+  test('self dep dyn', function () {
+    try {
+      exec('./node_modules/.bin/jake selfdepdyn');
+    }
+    catch(e) {
+      assert(e.message.indexOf('dependency of itself') > -1)
+    }
+  });
+
+});
+
+
diff --git a/d2d_app/node_modules/jake/test/integration/task_base.js b/d2d_app/node_modules/jake/test/integration/task_base.js
new file mode 100644 (file)
index 0000000..36e20e8
--- /dev/null
@@ -0,0 +1,164 @@
+let assert = require('assert');
+let h = require('./helpers');
+let exec = require('child_process').execSync;
+
+suite('taskBase', function () {
+
+  this.timeout(7000);
+
+  test('default task', function () {
+    let out;
+    out = exec('./node_modules/.bin/jake -q').toString().trim();
+    assert.equal(out, 'default task');
+    out = exec('./node_modules/.bin/jake -q default').toString().trim();
+    assert.equal(out, 'default task');
+  });
+
+  test('task with no action', function () {
+    let out = exec('./node_modules/.bin/jake -q noAction').toString().trim();
+    assert.equal(out, 'default task');
+  });
+
+  test('a task with no action and no prereqs', function () {
+    exec('./node_modules/.bin/jake noActionNoPrereqs');
+  });
+
+  test('a task that exists at the top-level, and not in the specified namespace, should error', function () {
+    let res = require('child_process').spawnSync('./node_modules/.bin/jake',
+    ['asdfasdfasdf:zerbofrangazoomy']);
+    let err = res.stderr.toString();
+    assert.ok(err.indexOf('Unknown task' > -1));
+  });
+
+  test('passing args to a task', function () {
+    let out = exec('./node_modules/.bin/jake -q argsEnvVars[foo,bar]').toString().trim();
+    let parsed = h.parse(out);
+    let args = parsed.args;
+    assert.equal(args[0], 'foo');
+    assert.equal(args[1], 'bar');
+  });
+
+  test('a task with environment vars', function () {
+    let out = exec('./node_modules/.bin/jake -q argsEnvVars foo=bar baz=qux').toString().trim();
+    let parsed = h.parse(out);
+    let env = parsed.env;
+    assert.equal(env.foo, 'bar');
+    assert.equal(env.baz, 'qux');
+  });
+
+  test('passing args and using environment vars', function () {
+    let out = exec('./node_modules/.bin/jake -q argsEnvVars[foo,bar] foo=bar baz=qux').toString().trim();
+    let parsed = h.parse(out);
+    let args = parsed.args;
+    let env = parsed.env;
+    assert.equal(args[0], 'foo');
+    assert.equal(args[1], 'bar');
+    assert.equal(env.foo, 'bar');
+    assert.equal(env.baz, 'qux');
+  });
+
+  test('a simple prereq', function () {
+    let out = exec('./node_modules/.bin/jake -q foo:baz').toString().trim();
+    assert.equal(out, 'foo:bar task\nfoo:baz task');
+  });
+
+  test('a duplicate prereq only runs once', function () {
+    let out = exec('./node_modules/.bin/jake -q foo:asdf').toString().trim();
+    assert.equal(out, 'foo:bar task\nfoo:baz task\nfoo:asdf task');
+  });
+
+  test('a prereq with command-line args', function () {
+    let out = exec('./node_modules/.bin/jake -q foo:qux').toString().trim();
+    assert.equal(out, 'foo:bar[asdf,qwer] task\nfoo:qux task');
+  });
+
+  test('a prereq with args via invoke', function () {
+    let out = exec('./node_modules/.bin/jake -q foo:frang[zxcv,uiop]').toString().trim();
+    assert.equal(out, 'foo:bar[zxcv,uiop] task\nfoo:frang task');
+  });
+
+  test('a prereq with args via execute', function () {
+    let out = exec('./node_modules/.bin/jake -q foo:zerb[zxcv,uiop]').toString().trim();
+    assert.equal(out, 'foo:bar[zxcv,uiop] task\nfoo:zerb task');
+  });
+
+  test('repeating the task via execute', function () {
+    let out = exec('./node_modules/.bin/jake -q foo:voom').toString().trim();
+    assert.equal(out, 'foo:bar task\nfoo:bar task\ncomplete\ncomplete');
+  });
+
+  test('prereq execution-order', function () {
+    let out = exec('./node_modules/.bin/jake -q hoge:fuga').toString().trim();
+    assert.equal(out, 'hoge:hoge task\nhoge:piyo task\nhoge:fuga task');
+  });
+
+  test('basic async task', function () {
+    let out = exec('./node_modules/.bin/jake -q bar:bar').toString().trim();
+    assert.equal(out, 'bar:foo task\nbar:bar task');
+  });
+
+  test('promise async task', function () {
+    let out = exec('./node_modules/.bin/jake -q bar:dependOnpromise').toString().trim();
+    assert.equal(out, 'bar:promise task\nbar:dependOnpromise task saw value 123654');
+  });
+
+  test('failing promise async task', function () {
+    try {
+      exec('./node_modules/.bin/jake -q bar:brokenPromise');
+    }
+    catch(e) {
+      assert(e.message.indexOf('Command failed') > -1);
+    }
+  });
+
+  test('that current-prereq index gets reset', function () {
+    let out = exec('./node_modules/.bin/jake -q hoge:kira').toString().trim();
+    assert.equal(out, 'hoge:hoge task\nhoge:piyo task\nhoge:fuga task\n' +
+        'hoge:charan task\nhoge:gero task\nhoge:kira task');
+  });
+
+  test('modifying a task by adding prereq during execution', function () {
+    let out = exec('./node_modules/.bin/jake -q voom').toString().trim();
+    assert.equal(out, 2);
+  });
+
+  test('listening for task error-event', function () {
+    try {
+      exec('./node_modules/.bin/jake -q vronk:groo').toString().trim();
+    }
+    catch(e) {
+      assert(e.message.indexOf('OMFGZONG') > -1);
+    }
+  });
+
+  test('listening for jake error-event', function () {
+    let out = exec('./node_modules/.bin/jake -q throwy').toString().trim();
+    assert(out.indexOf('Emitted\nError: I am bad') > -1);
+  });
+
+  test('listening for jake unhandledRejection-event', function () {
+    let out = exec('./node_modules/.bin/jake -q promiseRejecter').toString().trim();
+    assert.equal(out, '<promise rejected on purpose>');
+  });
+
+  test('large number of same prereqs', function () {
+    let out = exec('./node_modules/.bin/jake -q large:same').toString().trim();
+    assert.equal(out, 'large:leaf\nlarge:same');
+  });
+
+  test('large number of different prereqs', function () {
+    let out = exec('./node_modules/.bin/jake -q large:different').toString().trim();
+    assert.equal(out, 'leaf-12\nleaf-123\nlarge:different');
+  });
+
+  test('large number of different prereqs', function () {
+    let out = exec('./node_modules/.bin/jake -q usingRequire:test').toString().trim();
+    assert.equal(out, 'howdy test');
+  });
+
+  test('modifying a namespace by adding a new task', function () {
+    let out = exec('./node_modules/.bin/jake -q one:two').toString().trim();
+    assert.equal('one:one\none:two', out);
+  });
+
+});
diff --git a/d2d_app/node_modules/jake/test/unit/jakefile.js b/d2d_app/node_modules/jake/test/unit/jakefile.js
new file mode 100644 (file)
index 0000000..89ff523
--- /dev/null
@@ -0,0 +1,36 @@
+
+task('foo', function () {
+  console.log('ran top-level foo');
+});
+
+task('bar', function () {
+  console.log('ran top-level bar');
+});
+
+task('zerb', function () {
+  console.log('ran zerb');
+});
+
+namespace('zooby', function () {
+  task('zerp', function () {});
+
+  task('derp', ['zerp'], function () {});
+
+  namespace('frang', function () {
+
+    namespace('w00t', function () {
+      task('bar', function () {
+        console.log('ran zooby:frang:w00t:bar');
+      });
+    });
+
+    task('asdf', function () {});
+  });
+
+});
+
+namespace('hurr', function () {
+  namespace('durr');
+});
+
+
diff --git a/d2d_app/node_modules/jake/test/unit/namespace.js b/d2d_app/node_modules/jake/test/unit/namespace.js
new file mode 100644 (file)
index 0000000..c6b3ff5
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+const PROJECT_DIR = process.env.PROJECT_DIR;
+
+// Load the jake global
+require(`${PROJECT_DIR}/lib/jake`);
+let { Namespace } = require(`${PROJECT_DIR}/lib/namespace`);
+
+require('./jakefile');
+
+let assert = require('assert');
+
+suite('namespace', function () {
+
+  this.timeout(7000);
+
+  test('resolve namespace by relative name', function () {
+    let aaa, bbb, ccc;
+    aaa = namespace('aaa', function () {
+      bbb = namespace('bbb', function () {
+        ccc = namespace('ccc', function () {
+        });
+      });
+    });
+
+    assert.ok(aaa, Namespace.ROOT_NAMESPACE.resolveNamespace('aaa'));
+    assert.ok(bbb === aaa.resolveNamespace('bbb'));
+    assert.ok(ccc === aaa.resolveNamespace('bbb:ccc'));
+  });
+
+  test('resolve task in sub-namespace by relative path', function () {
+    let curr = Namespace.ROOT_NAMESPACE.resolveNamespace('zooby');
+    let task = curr.resolveTask('frang:w00t:bar');
+    assert.ok(task.action.toString().indexOf('zooby:frang:w00t:bar') > -1);
+  });
+
+  test('prefer local to top-level', function () {
+    let curr = Namespace.ROOT_NAMESPACE.resolveNamespace('zooby:frang:w00t');
+    let task = curr.resolveTask('bar');
+    assert.ok(task.action.toString().indexOf('zooby:frang:w00t:bar') > -1);
+  });
+
+  test('does resolve top-level', function () {
+    let curr = Namespace.ROOT_NAMESPACE.resolveNamespace('zooby:frang:w00t');
+    let task = curr.resolveTask('foo');
+    assert.ok(task.action.toString().indexOf('top-level foo') > -1);
+  });
+
+  test('absolute lookup works from sub-namespaces', function () {
+    let curr = Namespace.ROOT_NAMESPACE.resolveNamespace('hurr:durr');
+    let task = curr.resolveTask('zooby:frang:w00t:bar');
+    assert.ok(task.action.toString().indexOf('zooby:frang:w00t:bar') > -1);
+  });
+
+  test('resolution miss with throw error', function () {
+    let curr = Namespace.ROOT_NAMESPACE;
+    let task = curr.resolveTask('asdf:qwer');
+    assert.ok(!task);
+  });
+
+});
diff --git a/d2d_app/node_modules/jake/test/unit/parseargs.js b/d2d_app/node_modules/jake/test/unit/parseargs.js
new file mode 100644 (file)
index 0000000..7a3ddd5
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Jake JavaScript build tool
+ * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+*/
+
+const PROJECT_DIR = process.env.PROJECT_DIR;
+
+let parseargs = require(`${PROJECT_DIR}/lib/parseargs`);
+let assert = require('assert');
+let optsReg = [
+  { full: 'directory',
+    abbr: 'C',
+    preempts: false,
+    expectValue: true
+  },
+  { full: 'jakefile',
+    abbr: 'f',
+    preempts: false,
+    expectValue: true
+  },
+  { full: 'tasks',
+    abbr: 'T',
+    preempts: true
+  },
+  { full: 'tasks',
+    abbr: 'ls',
+    preempts: true
+  },
+  { full: 'trace',
+    abbr: 't',
+    preempts: false,
+    expectValue: false
+  },
+  { full: 'help',
+    abbr: 'h',
+    preempts: true
+  },
+  { full: 'version',
+    abbr: 'V',
+    preempts: true
+  }
+];
+let p = new parseargs.Parser(optsReg);
+let z = function (s) { return s.split(' '); };
+let res;
+
+suite('parseargs', function () {
+
+  test('long preemptive opt and val with equal-sign, ignore further opts', function () {
+    res = p.parse(z('--tasks=foo --jakefile=asdf'));
+    assert.equal('foo', res.opts.tasks);
+    assert.equal(undefined, res.opts.jakefile);
+  });
+
+  test('long preemptive opt and val without equal-sign, ignore further opts', function () {
+    res = p.parse(z('--tasks foo --jakefile=asdf'));
+    assert.equal('foo', res.opts.tasks);
+    assert.equal(undefined, res.opts.jakefile);
+  });
+
+  test('long preemptive opt and no val, ignore further opts', function () {
+    res = p.parse(z('--tasks --jakefile=asdf'));
+    assert.equal(true, res.opts.tasks);
+    assert.equal(undefined, res.opts.jakefile);
+  });
+
+  test('preemptive opt with no val, should be true', function () {
+    res = p.parse(z('-T'));
+    assert.equal(true, res.opts.tasks);
+  });
+
+  test('preemptive opt with no val, should be true and ignore further opts', function () {
+    res = p.parse(z('-T -f'));
+    assert.equal(true, res.opts.tasks);
+    assert.equal(undefined, res.opts.jakefile);
+  });
+
+  test('preemptive opt with val, should be val', function () {
+    res = p.parse(z('-T zoobie -f foo/bar/baz'));
+    assert.equal('zoobie', res.opts.tasks);
+    assert.equal(undefined, res.opts.jakefile);
+  });
+
+  test('-f expects a value, -t does not (howdy is task-name)', function () {
+    res = p.parse(z('-f zoobie -t howdy'));
+    assert.equal('zoobie', res.opts.jakefile);
+    assert.equal(true, res.opts.trace);
+    assert.equal('howdy', res.taskNames[0]);
+  });
+
+  test('different order, -f expects a value, -t does not (howdy is task-name)', function () {
+    res = p.parse(z('-f zoobie howdy -t'));
+    assert.equal('zoobie', res.opts.jakefile);
+    assert.equal(true, res.opts.trace);
+    assert.equal('howdy', res.taskNames[0]);
+  });
+
+  test('-f expects a value, -t does not (foo=bar is env var)', function () {
+    res = p.parse(z('-f zoobie -t foo=bar'));
+    assert.equal('zoobie', res.opts.jakefile);
+    assert.equal(true, res.opts.trace);
+    assert.equal('bar', res.envVars.foo);
+    assert.equal(undefined, res.taskNames[0]);
+  });
+
+  test('-f expects a value, -t does not (foo=bar is env-var, task-name follows)', function () {
+    res = p.parse(z('-f zoobie -t howdy foo=bar'));
+    assert.equal('zoobie', res.opts.jakefile);
+    assert.equal(true, res.opts.trace);
+    assert.equal('bar', res.envVars.foo);
+    assert.equal('howdy', res.taskNames[0]);
+  });
+
+  test('-t does not expect a value, -f does (howdy is task-name)', function () {
+    res = p.parse(z('-t howdy -f zoobie'));
+    assert.equal(true, res.opts.trace);
+    assert.equal('zoobie', res.opts.jakefile);
+    assert.equal('howdy', res.taskNames[0]);
+  });
+
+  test('--trace does not expect a value, -f does (howdy is task-name)', function () {
+    res = p.parse(z('--trace howdy --jakefile zoobie'));
+    assert.equal(true, res.opts.trace);
+    assert.equal('zoobie', res.opts.jakefile);
+    assert.equal('howdy', res.taskNames[0]);
+  });
+
+  test('--trace does not expect a value (equal), -f does (throw howdy away)', function () {
+    res = p.parse(z('--trace=howdy --jakefile=zoobie'));
+    assert.equal(true, res.opts.trace);
+    assert.equal('zoobie', res.opts.jakefile);
+    assert.equal(undefined, res.taskNames[0]);
+  });
+
+  /*
+, test('task-name with positional args', function () {
+    res = p.parse(z('foo:bar[asdf,qwer]'));
+    assert.equal('asdf', p.taskArgs[0]);
+    assert.equal('qwer', p.taskArgs[1]);
+  }
+
+, test('opts, env vars, task-name with positional args', function () {
+    res = p.parse(z('-f ./tests/Jakefile -t default[asdf,qwer] foo=bar'));
+    assert.equal('./tests/Jakefile', res.opts.jakefile);
+    assert.equal(true, res.opts.trace);
+    assert.equal('bar', res.envVars.foo);
+    assert.equal('default', res.taskName);
+    assert.equal('asdf', p.taskArgs[0]);
+    assert.equal('qwer', p.taskArgs[1]);
+  }
+*/
+
+
+});
+
+
diff --git a/d2d_app/node_modules/jake/usage.txt b/d2d_app/node_modules/jake/usage.txt
new file mode 100644 (file)
index 0000000..392b6d8
--- /dev/null
@@ -0,0 +1,16 @@
+Jake JavaScript build tool
+********************************************************************************
+If no flags are given, Jake looks for a Jakefile or Jakefile.js in the current directory.
+********************************************************************************
+{Usage}: jake [options ...] [env variables ...] target
+
+{Options}:
+  -f,     --jakefile FILE            Use FILE as the Jakefile.
+  -C,     --directory DIRECTORY      Change to DIRECTORY before running tasks.
+  -B,     --always-make              Unconditionally make all targets.
+  -T/ls,  --tasks                 Display the tasks (matching optional PATTERN) with descriptions, then exit.
+  -J,     --jakelibdir JAKELIBDIR    Auto-import any .jake files in JAKELIBDIR. (default is \'jakelib\')
+  -h,     --help                     Display this help message.
+  -V/v,   --version                  Display the Jake version.
+  -ar,    --allow-rejection          Keep running even after unhandled promise rejection
+
diff --git a/d2d_app/node_modules/minimatch/LICENSE b/d2d_app/node_modules/minimatch/LICENSE
new file mode 100644 (file)
index 0000000..19129e3
--- /dev/null
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter and Contributors
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/d2d_app/node_modules/minimatch/README.md b/d2d_app/node_modules/minimatch/README.md
new file mode 100644 (file)
index 0000000..ad72b81
--- /dev/null
@@ -0,0 +1,209 @@
+# minimatch
+
+A minimal matching utility.
+
+[![Build Status](https://secure.travis-ci.org/isaacs/minimatch.svg)](http://travis-ci.org/isaacs/minimatch)
+
+
+This is the matching library used internally by npm.
+
+It works by converting glob expressions into JavaScript `RegExp`
+objects.
+
+## Usage
+
+```javascript
+var minimatch = require("minimatch")
+
+minimatch("bar.foo", "*.foo") // true!
+minimatch("bar.foo", "*.bar") // false!
+minimatch("bar.foo", "*.+(bar|foo)", { debug: true }) // true, and noisy!
+```
+
+## Features
+
+Supports these glob features:
+
+* Brace Expansion
+* Extended glob matching
+* "Globstar" `**` matching
+
+See:
+
+* `man sh`
+* `man bash`
+* `man 3 fnmatch`
+* `man 5 gitignore`
+
+## Minimatch Class
+
+Create a minimatch object by instantiating the `minimatch.Minimatch` class.
+
+```javascript
+var Minimatch = require("minimatch").Minimatch
+var mm = new Minimatch(pattern, options)
+```
+
+### Properties
+
+* `pattern` The original pattern the minimatch object represents.
+* `options` The options supplied to the constructor.
+* `set` A 2-dimensional array of regexp or string expressions.
+  Each row in the
+  array corresponds to a brace-expanded pattern.  Each item in the row
+  corresponds to a single path-part.  For example, the pattern
+  `{a,b/c}/d` would expand to a set of patterns like:
+
+        [ [ a, d ]
+        , [ b, c, d ] ]
+
+    If a portion of the pattern doesn't have any "magic" in it
+    (that is, it's something like `"foo"` rather than `fo*o?`), then it
+    will be left as a string rather than converted to a regular
+    expression.
+
+* `regexp` Created by the `makeRe` method.  A single regular expression
+  expressing the entire pattern.  This is useful in cases where you wish
+  to use the pattern somewhat like `fnmatch(3)` with `FNM_PATH` enabled.
+* `negate` True if the pattern is negated.
+* `comment` True if the pattern is a comment.
+* `empty` True if the pattern is `""`.
+
+### Methods
+
+* `makeRe` Generate the `regexp` member if necessary, and return it.
+  Will return `false` if the pattern is invalid.
+* `match(fname)` Return true if the filename matches the pattern, or
+  false otherwise.
+* `matchOne(fileArray, patternArray, partial)` Take a `/`-split
+  filename, and match it against a single row in the `regExpSet`.  This
+  method is mainly for internal use, but is exposed so that it can be
+  used by a glob-walker that needs to avoid excessive filesystem calls.
+
+All other methods are internal, and will be called as necessary.
+
+### minimatch(path, pattern, options)
+
+Main export.  Tests a path against the pattern using the options.
+
+```javascript
+var isJS = minimatch(file, "*.js", { matchBase: true })
+```
+
+### minimatch.filter(pattern, options)
+
+Returns a function that tests its
+supplied argument, suitable for use with `Array.filter`.  Example:
+
+```javascript
+var javascripts = fileList.filter(minimatch.filter("*.js", {matchBase: true}))
+```
+
+### minimatch.match(list, pattern, options)
+
+Match against the list of
+files, in the style of fnmatch or glob.  If nothing is matched, and
+options.nonull is set, then return a list containing the pattern itself.
+
+```javascript
+var javascripts = minimatch.match(fileList, "*.js", {matchBase: true}))
+```
+
+### minimatch.makeRe(pattern, options)
+
+Make a regular expression object from the pattern.
+
+## Options
+
+All options are `false` by default.
+
+### debug
+
+Dump a ton of stuff to stderr.
+
+### nobrace
+
+Do not expand `{a,b}` and `{1..3}` brace sets.
+
+### noglobstar
+
+Disable `**` matching against multiple folder names.
+
+### dot
+
+Allow patterns to match filenames starting with a period, even if
+the pattern does not explicitly have a period in that spot.
+
+Note that by default, `a/**/b` will **not** match `a/.d/b`, unless `dot`
+is set.
+
+### noext
+
+Disable "extglob" style patterns like `+(a|b)`.
+
+### nocase
+
+Perform a case-insensitive match.
+
+### nonull
+
+When a match is not found by `minimatch.match`, return a list containing
+the pattern itself if this option is set.  When not set, an empty list
+is returned if there are no matches.
+
+### matchBase
+
+If set, then patterns without slashes will be matched
+against the basename of the path if it contains slashes.  For example,
+`a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
+
+### nocomment
+
+Suppress the behavior of treating `#` at the start of a pattern as a
+comment.
+
+### nonegate
+
+Suppress the behavior of treating a leading `!` character as negation.
+
+### flipNegate
+
+Returns from negate expressions the same as if they were not negated.
+(Ie, true on a hit, false on a miss.)
+
+
+## Comparisons to other fnmatch/glob implementations
+
+While strict compliance with the existing standards is a worthwhile
+goal, some discrepancies exist between minimatch and other
+implementations, and are intentional.
+
+If the pattern starts with a `!` character, then it is negated.  Set the
+`nonegate` flag to suppress this behavior, and treat leading `!`
+characters normally.  This is perhaps relevant if you wish to start the
+pattern with a negative extglob pattern like `!(a|B)`.  Multiple `!`
+characters at the start of a pattern will negate the pattern multiple
+times.
+
+If a pattern starts with `#`, then it is treated as a comment, and
+will not match anything.  Use `\#` to match a literal `#` at the
+start of a line, or set the `nocomment` flag to suppress this behavior.
+
+The double-star character `**` is supported by default, unless the
+`noglobstar` flag is set.  This is supported in the manner of bsdglob
+and bash 4.1, where `**` only has special significance if it is the only
+thing in a path part.  That is, `a/**/b` will match `a/x/y/b`, but
+`a/**b` will not.
+
+If an escaped pattern has no matches, and the `nonull` flag is set,
+then minimatch.match returns the pattern as-provided, rather than
+interpreting the character escapes.  For example,
+`minimatch.match([], "\\*a\\?")` will return `"\\*a\\?"` rather than
+`"*a?"`.  This is akin to setting the `nullglob` option in bash, except
+that it does not resolve escaped pattern characters.
+
+If brace expansion is not disabled, then it is performed before any
+other interpretation of the glob pattern.  Thus, a pattern like
+`+(a|{b),c)}`, which would not be valid in bash or zsh, is expanded
+**first** into the set of `+(a|b)` and `+(a|c)`, and those patterns are
+checked for validity.  Since those two are valid, matching proceeds.
diff --git a/d2d_app/node_modules/minimatch/minimatch.js b/d2d_app/node_modules/minimatch/minimatch.js
new file mode 100644 (file)
index 0000000..5b5f8cf
--- /dev/null
@@ -0,0 +1,923 @@
+module.exports = minimatch
+minimatch.Minimatch = Minimatch
+
+var path = { sep: '/' }
+try {
+  path = require('path')
+} catch (er) {}
+
+var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
+var expand = require('brace-expansion')
+
+var plTypes = {
+  '!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
+  '?': { open: '(?:', close: ')?' },
+  '+': { open: '(?:', close: ')+' },
+  '*': { open: '(?:', close: ')*' },
+  '@': { open: '(?:', close: ')' }
+}
+
+// any single thing other than /
+// don't need to escape / when using new RegExp()
+var qmark = '[^/]'
+
+// * => any number of characters
+var star = qmark + '*?'
+
+// ** when dots are allowed.  Anything goes, except .. and .
+// not (^ or / followed by one or two dots followed by $ or /),
+// followed by anything, any number of times.
+var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
+
+// not a ^ or / followed by a dot,
+// followed by anything, any number of times.
+var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
+
+// characters that need to be escaped in RegExp.
+var reSpecials = charSet('().*{}+?[]^$\\!')
+
+// "abc" -> { a:true, b:true, c:true }
+function charSet (s) {
+  return s.split('').reduce(function (set, c) {
+    set[c] = true
+    return set
+  }, {})
+}
+
+// normalizes slashes.
+var slashSplit = /\/+/
+
+minimatch.filter = filter
+function filter (pattern, options) {
+  options = options || {}
+  return function (p, i, list) {
+    return minimatch(p, pattern, options)
+  }
+}
+
+function ext (a, b) {
+  a = a || {}
+  b = b || {}
+  var t = {}
+  Object.keys(b).forEach(function (k) {
+    t[k] = b[k]
+  })
+  Object.keys(a).forEach(function (k) {
+    t[k] = a[k]
+  })
+  return t
+}
+
+minimatch.defaults = function (def) {
+  if (!def || !Object.keys(def).length) return minimatch
+
+  var orig = minimatch
+
+  var m = function minimatch (p, pattern, options) {
+    return orig.minimatch(p, pattern, ext(def, options))
+  }
+
+  m.Minimatch = function Minimatch (pattern, options) {
+    return new orig.Minimatch(pattern, ext(def, options))
+  }
+
+  return m
+}
+
+Minimatch.defaults = function (def) {
+  if (!def || !Object.keys(def).length) return Minimatch
+  return minimatch.defaults(def).Minimatch
+}
+
+function minimatch (p, pattern, options) {
+  if (typeof pattern !== 'string') {
+    throw new TypeError('glob pattern string required')
+  }
+
+  if (!options) options = {}
+
+  // shortcut: comments match nothing.
+  if (!options.nocomment && pattern.charAt(0) === '#') {
+    return false
+  }
+
+  // "" only matches ""
+  if (pattern.trim() === '') return p === ''
+
+  return new Minimatch(pattern, options).match(p)
+}
+
+function Minimatch (pattern, options) {
+  if (!(this instanceof Minimatch)) {
+    return new Minimatch(pattern, options)
+  }
+
+  if (typeof pattern !== 'string') {
+    throw new TypeError('glob pattern string required')
+  }
+
+  if (!options) options = {}
+  pattern = pattern.trim()
+
+  // windows support: need to use /, not \
+  if (path.sep !== '/') {
+    pattern = pattern.split(path.sep).join('/')
+  }
+
+  this.options = options
+  this.set = []
+  this.pattern = pattern
+  this.regexp = null
+  this.negate = false
+  this.comment = false
+  this.empty = false
+
+  // make the set of regexps etc.
+  this.make()
+}
+
+Minimatch.prototype.debug = function () {}
+
+Minimatch.prototype.make = make
+function make () {
+  // don't do it more than once.
+  if (this._made) return
+
+  var pattern = this.pattern
+  var options = this.options
+
+  // empty patterns and comments match nothing.
+  if (!options.nocomment && pattern.charAt(0) === '#') {
+    this.comment = true
+    return
+  }
+  if (!pattern) {
+    this.empty = true
+    return
+  }
+
+  // step 1: figure out negation, etc.
+  this.parseNegate()
+
+  // step 2: expand braces
+  var set = this.globSet = this.braceExpand()
+
+  if (options.debug) this.debug = console.error
+
+  this.debug(this.pattern, set)
+
+  // step 3: now we have a set, so turn each one into a series of path-portion
+  // matching patterns.
+  // These will be regexps, except in the case of "**", which is
+  // set to the GLOBSTAR object for globstar behavior,
+  // and will not contain any / characters
+  set = this.globParts = set.map(function (s) {
+    return s.split(slashSplit)
+  })
+
+  this.debug(this.pattern, set)
+
+  // glob --> regexps
+  set = set.map(function (s, si, set) {
+    return s.map(this.parse, this)
+  }, this)
+
+  this.debug(this.pattern, set)
+
+  // filter out everything that didn't compile properly.
+  set = set.filter(function (s) {
+    return s.indexOf(false) === -1
+  })
+
+  this.debug(this.pattern, set)
+
+  this.set = set
+}
+
+Minimatch.prototype.parseNegate = parseNegate
+function parseNegate () {
+  var pattern = this.pattern
+  var negate = false
+  var options = this.options
+  var negateOffset = 0
+
+  if (options.nonegate) return
+
+  for (var i = 0, l = pattern.length
+    ; i < l && pattern.charAt(i) === '!'
+    ; i++) {
+    negate = !negate
+    negateOffset++
+  }
+
+  if (negateOffset) this.pattern = pattern.substr(negateOffset)
+  this.negate = negate
+}
+
+// Brace expansion:
+// a{b,c}d -> abd acd
+// a{b,}c -> abc ac
+// a{0..3}d -> a0d a1d a2d a3d
+// a{b,c{d,e}f}g -> abg acdfg acefg
+// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
+//
+// Invalid sets are not expanded.
+// a{2..}b -> a{2..}b
+// a{b}c -> a{b}c
+minimatch.braceExpand = function (pattern, options) {
+  return braceExpand(pattern, options)
+}
+
+Minimatch.prototype.braceExpand = braceExpand
+
+function braceExpand (pattern, options) {
+  if (!options) {
+    if (this instanceof Minimatch) {
+      options = this.options
+    } else {
+      options = {}
+    }
+  }
+
+  pattern = typeof pattern === 'undefined'
+    ? this.pattern : pattern
+
+  if (typeof pattern === 'undefined') {
+    throw new TypeError('undefined pattern')
+  }
+
+  if (options.nobrace ||
+    !pattern.match(/\{.*\}/)) {
+    // shortcut. no need to expand.
+    return [pattern]
+  }
+
+  return expand(pattern)
+}
+
+// parse a component of the expanded set.
+// At this point, no pattern may contain "/" in it
+// so we're going to return a 2d array, where each entry is the full
+// pattern, split on '/', and then turned into a regular expression.
+// A regexp is made at the end which joins each array with an
+// escaped /, and another full one which joins each regexp with |.
+//
+// Following the lead of Bash 4.1, note that "**" only has special meaning
+// when it is the *only* thing in a path portion.  Otherwise, any series
+// of * is equivalent to a single *.  Globstar behavior is enabled by
+// default, and can be disabled by setting options.noglobstar.
+Minimatch.prototype.parse = parse
+var SUBPARSE = {}
+function parse (pattern, isSub) {
+  if (pattern.length > 1024 * 64) {
+    throw new TypeError('pattern is too long')
+  }
+
+  var options = this.options
+
+  // shortcuts
+  if (!options.noglobstar && pattern === '**') return GLOBSTAR
+  if (pattern === '') return ''
+
+  var re = ''
+  var hasMagic = !!options.nocase
+  var escaping = false
+  // ? => one single character
+  var patternListStack = []
+  var negativeLists = []
+  var stateChar
+  var inClass = false
+  var reClassStart = -1
+  var classStart = -1
+  // . and .. never match anything that doesn't start with .,
+  // even when options.dot is set.
+  var patternStart = pattern.charAt(0) === '.' ? '' // anything
+  // not (start or / followed by . or .. followed by / or end)
+  : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
+  : '(?!\\.)'
+  var self = this
+
+  function clearStateChar () {
+    if (stateChar) {
+      // we had some state-tracking character
+      // that wasn't consumed by this pass.
+      switch (stateChar) {
+        case '*':
+          re += star
+          hasMagic = true
+        break
+        case '?':
+          re += qmark
+          hasMagic = true
+        break
+        default:
+          re += '\\' + stateChar
+        break
+      }
+      self.debug('clearStateChar %j %j', stateChar, re)
+      stateChar = false
+    }
+  }
+
+  for (var i = 0, len = pattern.length, c
+    ; (i < len) && (c = pattern.charAt(i))
+    ; i++) {
+    this.debug('%s\t%s %s %j', pattern, i, re, c)
+
+    // skip over any that are escaped.
+    if (escaping && reSpecials[c]) {
+      re += '\\' + c
+      escaping = false
+      continue
+    }
+
+    switch (c) {
+      case '/':
+        // completely not allowed, even escaped.
+        // Should already be path-split by now.
+        return false
+
+      case '\\':
+        clearStateChar()
+        escaping = true
+      continue
+
+      // the various stateChar values
+      // for the "extglob" stuff.
+      case '?':
+      case '*':
+      case '+':
+      case '@':
+      case '!':
+        this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
+
+        // all of those are literals inside a class, except that
+        // the glob [!a] means [^a] in regexp
+        if (inClass) {
+          this.debug('  in class')
+          if (c === '!' && i === classStart + 1) c = '^'
+          re += c
+          continue
+        }
+
+        // if we already have a stateChar, then it means
+        // that there was something like ** or +? in there.
+        // Handle the stateChar, then proceed with this one.
+        self.debug('call clearStateChar %j', stateChar)
+        clearStateChar()
+        stateChar = c
+        // if extglob is disabled, then +(asdf|foo) isn't a thing.
+        // just clear the statechar *now*, rather than even diving into
+        // the patternList stuff.
+        if (options.noext) clearStateChar()
+      continue
+
+      case '(':
+        if (inClass) {
+          re += '('
+          continue
+        }
+
+        if (!stateChar) {
+          re += '\\('
+          continue
+        }
+
+        patternListStack.push({
+          type: stateChar,
+          start: i - 1,
+          reStart: re.length,
+          open: plTypes[stateChar].open,
+          close: plTypes[stateChar].close
+        })
+        // negation is (?:(?!js)[^/]*)
+        re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
+        this.debug('plType %j %j', stateChar, re)
+        stateChar = false
+      continue
+
+      case ')':
+        if (inClass || !patternListStack.length) {
+          re += '\\)'
+          continue
+        }
+
+        clearStateChar()
+        hasMagic = true
+        var pl = patternListStack.pop()
+        // negation is (?:(?!js)[^/]*)
+        // The others are (?:<pattern>)<type>
+        re += pl.close
+        if (pl.type === '!') {
+          negativeLists.push(pl)
+        }
+        pl.reEnd = re.length
+      continue
+
+      case '|':
+        if (inClass || !patternListStack.length || escaping) {
+          re += '\\|'
+          escaping = false
+          continue
+        }
+
+        clearStateChar()
+        re += '|'
+      continue
+
+      // these are mostly the same in regexp and glob
+      case '[':
+        // swallow any state-tracking char before the [
+        clearStateChar()
+
+        if (inClass) {
+          re += '\\' + c
+          continue
+        }
+
+        inClass = true
+        classStart = i
+        reClassStart = re.length
+        re += c
+      continue
+
+      case ']':
+        //  a right bracket shall lose its special
+        //  meaning and represent itself in
+        //  a bracket expression if it occurs
+        //  first in the list.  -- POSIX.2 2.8.3.2
+        if (i === classStart + 1 || !inClass) {
+          re += '\\' + c
+          escaping = false
+          continue
+        }
+
+        // handle the case where we left a class open.
+        // "[z-a]" is valid, equivalent to "\[z-a\]"
+        if (inClass) {
+          // split where the last [ was, make sure we don't have
+          // an invalid re. if so, re-walk the contents of the
+          // would-be class to re-translate any characters that
+          // were passed through as-is
+          // TODO: It would probably be faster to determine this
+          // without a try/catch and a new RegExp, but it's tricky
+          // to do safely.  For now, this is safe and works.
+          var cs = pattern.substring(classStart + 1, i)
+          try {
+            RegExp('[' + cs + ']')
+          } catch (er) {
+            // not a valid class!
+            var sp = this.parse(cs, SUBPARSE)
+            re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
+            hasMagic = hasMagic || sp[1]
+            inClass = false
+            continue
+          }
+        }
+
+        // finish up the class.
+        hasMagic = true
+        inClass = false
+        re += c
+      continue
+
+      default:
+        // swallow any state char that wasn't consumed
+        clearStateChar()
+
+        if (escaping) {
+          // no need
+          escaping = false
+        } else if (reSpecials[c]
+          && !(c === '^' && inClass)) {
+          re += '\\'
+        }
+
+        re += c
+
+    } // switch
+  } // for
+
+  // handle the case where we left a class open.
+  // "[abc" is valid, equivalent to "\[abc"
+  if (inClass) {
+    // split where the last [ was, and escape it
+    // this is a huge pita.  We now have to re-walk
+    // the contents of the would-be class to re-translate
+    // any characters that were passed through as-is
+    cs = pattern.substr(classStart + 1)
+    sp = this.parse(cs, SUBPARSE)
+    re = re.substr(0, reClassStart) + '\\[' + sp[0]
+    hasMagic = hasMagic || sp[1]
+  }
+
+  // handle the case where we had a +( thing at the *end*
+  // of the pattern.
+  // each pattern list stack adds 3 chars, and we need to go through
+  // and escape any | chars that were passed through as-is for the regexp.
+  // Go through and escape them, taking care not to double-escape any
+  // | chars that were already escaped.
+  for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
+    var tail = re.slice(pl.reStart + pl.open.length)
+    this.debug('setting tail', re, pl)
+    // maybe some even number of \, then maybe 1 \, followed by a |
+    tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) {
+      if (!$2) {
+        // the | isn't already escaped, so escape it.
+        $2 = '\\'
+      }
+
+      // need to escape all those slashes *again*, without escaping the
+      // one that we need for escaping the | character.  As it works out,
+      // escaping an even number of slashes can be done by simply repeating
+      // it exactly after itself.  That's why this trick works.
+      //
+      // I am sorry that you have to see this.
+      return $1 + $1 + $2 + '|'
+    })
+
+    this.debug('tail=%j\n   %s', tail, tail, pl, re)
+    var t = pl.type === '*' ? star
+      : pl.type === '?' ? qmark
+      : '\\' + pl.type
+
+    hasMagic = true
+    re = re.slice(0, pl.reStart) + t + '\\(' + tail
+  }
+
+  // handle trailing things that only matter at the very end.
+  clearStateChar()
+  if (escaping) {
+    // trailing \\
+    re += '\\\\'
+  }
+
+  // only need to apply the nodot start if the re starts with
+  // something that could conceivably capture a dot
+  var addPatternStart = false
+  switch (re.charAt(0)) {
+    case '.':
+    case '[':
+    case '(': addPatternStart = true
+  }
+
+  // Hack to work around lack of negative lookbehind in JS
+  // A pattern like: *.!(x).!(y|z) needs to ensure that a name
+  // like 'a.xyz.yz' doesn't match.  So, the first negative
+  // lookahead, has to look ALL the way ahead, to the end of
+  // the pattern.
+  for (var n = negativeLists.length - 1; n > -1; n--) {
+    var nl = negativeLists[n]
+
+    var nlBefore = re.slice(0, nl.reStart)
+    var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)
+    var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)
+    var nlAfter = re.slice(nl.reEnd)
+
+    nlLast += nlAfter
+
+    // Handle nested stuff like *(*.js|!(*.json)), where open parens
+    // mean that we should *not* include the ) in the bit that is considered
+    // "after" the negated section.
+    var openParensBefore = nlBefore.split('(').length - 1
+    var cleanAfter = nlAfter
+    for (i = 0; i < openParensBefore; i++) {
+      cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')
+    }
+    nlAfter = cleanAfter
+
+    var dollar = ''
+    if (nlAfter === '' && isSub !== SUBPARSE) {
+      dollar = '$'
+    }
+    var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
+    re = newRe
+  }
+
+  // if the re is not "" at this point, then we need to make sure
+  // it doesn't match against an empty path part.
+  // Otherwise a/* will match a/, which it should not.
+  if (re !== '' && hasMagic) {
+    re = '(?=.)' + re
+  }
+
+  if (addPatternStart) {
+    re = patternStart + re
+  }
+
+  // parsing just a piece of a larger pattern.
+  if (isSub === SUBPARSE) {
+    return [re, hasMagic]
+  }
+
+  // skip the regexp for non-magical patterns
+  // unescape anything in it, though, so that it'll be
+  // an exact match against a file etc.
+  if (!hasMagic) {
+    return globUnescape(pattern)
+  }
+
+  var flags = options.nocase ? 'i' : ''
+  try {
+    var regExp = new RegExp('^' + re + '$', flags)
+  } catch (er) {
+    // If it was an invalid regular expression, then it can't match
+    // anything.  This trick looks for a character after the end of
+    // the string, which is of course impossible, except in multi-line
+    // mode, but it's not a /m regex.
+    return new RegExp('$.')
+  }
+
+  regExp._glob = pattern
+  regExp._src = re
+
+  return regExp
+}
+
+minimatch.makeRe = function (pattern, options) {
+  return new Minimatch(pattern, options || {}).makeRe()
+}
+
+Minimatch.prototype.makeRe = makeRe
+function makeRe () {
+  if (this.regexp || this.regexp === false) return this.regexp
+
+  // at this point, this.set is a 2d array of partial
+  // pattern strings, or "**".
+  //
+  // It's better to use .match().  This function shouldn't
+  // be used, really, but it's pretty convenient sometimes,
+  // when you just want to work with a regex.
+  var set = this.set
+
+  if (!set.length) {
+    this.regexp = false
+    return this.regexp
+  }
+  var options = this.options
+
+  var twoStar = options.noglobstar ? star
+    : options.dot ? twoStarDot
+    : twoStarNoDot
+  var flags = options.nocase ? 'i' : ''
+
+  var re = set.map(function (pattern) {
+    return pattern.map(function (p) {
+      return (p === GLOBSTAR) ? twoStar
+      : (typeof p === 'string') ? regExpEscape(p)
+      : p._src
+    }).join('\\\/')
+  }).join('|')
+
+  // must match entire pattern
+  // ending in a * or ** will make it less strict.
+  re = '^(?:' + re + ')$'
+
+  // can match anything, as long as it's not this.
+  if (this.negate) re = '^(?!' + re + ').*$'
+
+  try {
+    this.regexp = new RegExp(re, flags)
+  } catch (ex) {
+    this.regexp = false
+  }
+  return this.regexp
+}
+
+minimatch.match = function (list, pattern, options) {
+  options = options || {}
+  var mm = new Minimatch(pattern, options)
+  list = list.filter(function (f) {
+    return mm.match(f)
+  })
+  if (mm.options.nonull && !list.length) {
+    list.push(pattern)
+  }
+  return list
+}
+
+Minimatch.prototype.match = match
+function match (f, partial) {
+  this.debug('match', f, this.pattern)
+  // short-circuit in the case of busted things.
+  // comments, etc.
+  if (this.comment) return false
+  if (this.empty) return f === ''
+
+  if (f === '/' && partial) return true
+
+  var options = this.options
+
+  // windows: need to use /, not \
+  if (path.sep !== '/') {
+    f = f.split(path.sep).join('/')
+  }
+
+  // treat the test path as a set of pathparts.
+  f = f.split(slashSplit)
+  this.debug(this.pattern, 'split', f)
+
+  // just ONE of the pattern sets in this.set needs to match
+  // in order for it to be valid.  If negating, then just one
+  // match means that we have failed.
+  // Either way, return on the first hit.
+
+  var set = this.set
+  this.debug(this.pattern, 'set', set)
+
+  // Find the basename of the path by looking for the last non-empty segment
+  var filename
+  var i
+  for (i = f.length - 1; i >= 0; i--) {
+    filename = f[i]
+    if (filename) break
+  }
+
+  for (i = 0; i < set.length; i++) {
+    var pattern = set[i]
+    var file = f
+    if (options.matchBase && pattern.length === 1) {
+      file = [filename]
+    }
+    var hit = this.matchOne(file, pattern, partial)
+    if (hit) {
+      if (options.flipNegate) return true
+      return !this.negate
+    }
+  }
+
+  // didn't get any hits.  this is success if it's a negative
+  // pattern, failure otherwise.
+  if (options.flipNegate) return false
+  return this.negate
+}
+
+// set partial to true to test if, for example,
+// "/a/b" matches the start of "/*/b/*/d"
+// Partial means, if you run out of file before you run
+// out of pattern, then that's fine, as long as all
+// the parts match.
+Minimatch.prototype.matchOne = function (file, pattern, partial) {
+  var options = this.options
+
+  this.debug('matchOne',
+    { 'this': this, file: file, pattern: pattern })
+
+  this.debug('matchOne', file.length, pattern.length)
+
+  for (var fi = 0,
+      pi = 0,
+      fl = file.length,
+      pl = pattern.length
+      ; (fi < fl) && (pi < pl)
+      ; fi++, pi++) {
+    this.debug('matchOne loop')
+    var p = pattern[pi]
+    var f = file[fi]
+
+    this.debug(pattern, p, f)
+
+    // should be impossible.
+    // some invalid regexp stuff in the set.
+    if (p === false) return false
+
+    if (p === GLOBSTAR) {
+      this.debug('GLOBSTAR', [pattern, p, f])
+
+      // "**"
+      // a/**/b/**/c would match the following:
+      // a/b/x/y/z/c
+      // a/x/y/z/b/c
+      // a/b/x/b/x/c
+      // a/b/c
+      // To do this, take the rest of the pattern after
+      // the **, and see if it would match the file remainder.
+      // If so, return success.
+      // If not, the ** "swallows" a segment, and try again.
+      // This is recursively awful.
+      //
+      // a/**/b/**/c matching a/b/x/y/z/c
+      // - a matches a
+      // - doublestar
+      //   - matchOne(b/x/y/z/c, b/**/c)
+      //     - b matches b
+      //     - doublestar
+      //       - matchOne(x/y/z/c, c) -> no
+      //       - matchOne(y/z/c, c) -> no
+      //       - matchOne(z/c, c) -> no
+      //       - matchOne(c, c) yes, hit
+      var fr = fi
+      var pr = pi + 1
+      if (pr === pl) {
+        this.debug('** at the end')
+        // a ** at the end will just swallow the rest.
+        // We have found a match.
+        // however, it will not swallow /.x, unless
+        // options.dot is set.
+        // . and .. are *never* matched by **, for explosively
+        // exponential reasons.
+        for (; fi < fl; fi++) {
+          if (file[fi] === '.' || file[fi] === '..' ||
+            (!options.dot && file[fi].charAt(0) === '.')) return false
+        }
+        return true
+      }
+
+      // ok, let's see if we can swallow whatever we can.
+      while (fr < fl) {
+        var swallowee = file[fr]
+
+        this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
+
+        // XXX remove this slice.  Just pass the start index.
+        if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
+          this.debug('globstar found match!', fr, fl, swallowee)
+          // found a match.
+          return true
+        } else {
+          // can't swallow "." or ".." ever.
+          // can only swallow ".foo" when explicitly asked.
+          if (swallowee === '.' || swallowee === '..' ||
+            (!options.dot && swallowee.charAt(0) === '.')) {
+            this.debug('dot detected!', file, fr, pattern, pr)
+            break
+          }
+
+          // ** swallows a segment, and continue.
+          this.debug('globstar swallow a segment, and continue')
+          fr++
+        }
+      }
+
+      // no match was found.
+      // However, in partial mode, we can't say this is necessarily over.
+      // If there's more *pattern* left, then
+      if (partial) {
+        // ran out of file
+        this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
+        if (fr === fl) return true
+      }
+      return false
+    }
+
+    // something other than **
+    // non-magic patterns just have to match exactly
+    // patterns with magic have been turned into regexps.
+    var hit
+    if (typeof p === 'string') {
+      if (options.nocase) {
+        hit = f.toLowerCase() === p.toLowerCase()
+      } else {
+        hit = f === p
+      }
+      this.debug('string match', p, f, hit)
+    } else {
+      hit = f.match(p)
+      this.debug('pattern match', p, f, hit)
+    }
+
+    if (!hit) return false
+  }
+
+  // Note: ending in / means that we'll get a final ""
+  // at the end of the pattern.  This can only match a
+  // corresponding "" at the end of the file.
+  // If the file ends in /, then it can only match a
+  // a pattern that ends in /, unless the pattern just
+  // doesn't have any more for it. But, a/b/ should *not*
+  // match "a/b/*", even though "" matches against the
+  // [^/]*? pattern, except in partial mode, where it might
+  // simply not be reached yet.
+  // However, a/b/ should still satisfy a/*
+
+  // now either we fell off the end of the pattern, or we're done.
+  if (fi === fl && pi === pl) {
+    // ran out of pattern and filename at the same time.
+    // an exact hit!
+    return true
+  } else if (fi === fl) {
+    // ran out of file, but still had pattern left.
+    // this is ok if we're doing the match as part of
+    // a glob fs traversal.
+    return partial
+  } else if (pi === pl) {
+    // ran out of pattern, still have file left.
+    // this is only acceptable if we're on the very last
+    // empty segment of a file with a trailing slash.
+    // a/* should match a/b/
+    var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')
+    return emptyFileEnd
+  }
+
+  // should be unreachable.
+  throw new Error('wtf?')
+}
+
+// replace stuff like \* with *
+function globUnescape (s) {
+  return s.replace(/\\(.)/g, '$1')
+}
+
+function regExpEscape (s) {
+  return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
+}
diff --git a/d2d_app/node_modules/minimatch/package.json b/d2d_app/node_modules/minimatch/package.json
new file mode 100644 (file)
index 0000000..1e4b4d2
--- /dev/null
@@ -0,0 +1,64 @@
+{
+  "_from": "minimatch@^3.0.4",
+  "_id": "minimatch@3.0.4",
+  "_inBundle": false,
+  "_integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+  "_location": "/minimatch",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "minimatch@^3.0.4",
+    "name": "minimatch",
+    "escapedName": "minimatch",
+    "rawSpec": "^3.0.4",
+    "saveSpec": null,
+    "fetchSpec": "^3.0.4"
+  },
+  "_requiredBy": [
+    "/filelist",
+    "/jake"
+  ],
+  "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+  "_shasum": "5166e286457f03306064be5497e8dbb0c3d32083",
+  "_spec": "minimatch@^3.0.4",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/jake",
+  "author": {
+    "name": "Isaac Z. Schlueter",
+    "email": "i@izs.me",
+    "url": "http://blog.izs.me"
+  },
+  "bugs": {
+    "url": "https://github.com/isaacs/minimatch/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "brace-expansion": "^1.1.7"
+  },
+  "deprecated": false,
+  "description": "a glob matcher in javascript",
+  "devDependencies": {
+    "tap": "^10.3.2"
+  },
+  "engines": {
+    "node": "*"
+  },
+  "files": [
+    "minimatch.js"
+  ],
+  "homepage": "https://github.com/isaacs/minimatch#readme",
+  "license": "ISC",
+  "main": "minimatch.js",
+  "name": "minimatch",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/isaacs/minimatch.git"
+  },
+  "scripts": {
+    "postpublish": "git push origin --all; git push origin --tags",
+    "postversion": "npm publish",
+    "preversion": "npm test",
+    "test": "tap test/*.js --cov"
+  },
+  "version": "3.0.4"
+}
@@ -3,7 +3,7 @@
   "_id": "ms@2.0.0",
   "_inBundle": false,
   "_integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-  "_location": "/send/debug/ms",
+  "_location": "/ms",
   "_phantomChildren": {},
   "_requested": {
     "type": "version",
     "fetchSpec": "2.0.0"
   },
   "_requiredBy": [
-    "/send/debug"
+    "/debug"
   ],
   "_resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
   "_shasum": "5608aeadfc00be6c2901df5f9861788de0d597c8",
   "_spec": "ms@2.0.0",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/send/node_modules/debug",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/debug",
   "bugs": {
     "url": "https://github.com/zeit/ms/issues"
   },
diff --git a/d2d_app/node_modules/on-headers/HISTORY.md b/d2d_app/node_modules/on-headers/HISTORY.md
new file mode 100644 (file)
index 0000000..090598d
--- /dev/null
@@ -0,0 +1,21 @@
+1.0.2 / 2019-02-21
+==================
+
+  * Fix `res.writeHead` patch missing return value
+
+1.0.1 / 2015-09-29
+==================
+
+  * perf: enable strict mode
+
+1.0.0 / 2014-08-10
+==================
+
+  * Honor `res.statusCode` change in `listener`
+  * Move to `jshttp` organization
+  * Prevent `arguments`-related de-opt
+
+0.0.0 / 2014-05-13
+==================
+
+  * Initial implementation
diff --git a/d2d_app/node_modules/on-headers/LICENSE b/d2d_app/node_modules/on-headers/LICENSE
new file mode 100644 (file)
index 0000000..b7dce6c
--- /dev/null
@@ -0,0 +1,22 @@
+(The MIT License)
+
+Copyright (c) 2014 Douglas Christopher Wilson
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+'Software'), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/on-headers/README.md b/d2d_app/node_modules/on-headers/README.md
new file mode 100644 (file)
index 0000000..ae84282
--- /dev/null
@@ -0,0 +1,81 @@
+# on-headers
+
+[![NPM Version][npm-version-image]][npm-url]
+[![NPM Downloads][npm-downloads-image]][npm-url]
+[![Node.js Version][node-version-image]][node-version-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Execute a listener when a response is about to write headers.
+
+## Installation
+
+This is a [Node.js](https://nodejs.org/en/) module available through the
+[npm registry](https://www.npmjs.com/). Installation is done using the
+[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
+
+```sh
+$ npm install on-headers
+```
+
+## API
+
+<!-- eslint-disable no-unused-vars -->
+
+```js
+var onHeaders = require('on-headers')
+```
+
+### onHeaders(res, listener)
+
+This will add the listener `listener` to fire when headers are emitted for `res`.
+The listener is passed the `response` object as it's context (`this`). Headers are
+considered to be emitted only once, right before they are sent to the client.
+
+When this is called multiple times on the same `res`, the `listener`s are fired
+in the reverse order they were added.
+
+## Examples
+
+```js
+var http = require('http')
+var onHeaders = require('on-headers')
+
+http
+  .createServer(onRequest)
+  .listen(3000)
+
+function addPoweredBy () {
+  // set if not set by end of request
+  if (!this.getHeader('X-Powered-By')) {
+    this.setHeader('X-Powered-By', 'Node.js')
+  }
+}
+
+function onRequest (req, res) {
+  onHeaders(res, addPoweredBy)
+
+  res.setHeader('Content-Type', 'text/plain')
+  res.end('hello!')
+}
+```
+
+## Testing
+
+```sh
+$ npm test
+```
+
+## License
+
+[MIT](LICENSE)
+
+[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/on-headers/master
+[coveralls-url]: https://coveralls.io/r/jshttp/on-headers?branch=master
+[node-version-image]: https://badgen.net/npm/node/on-headers
+[node-version-url]: https://nodejs.org/en/download
+[npm-downloads-image]: https://badgen.net/npm/dm/on-headers
+[npm-url]: https://npmjs.org/package/on-headers
+[npm-version-image]: https://badgen.net/npm/v/on-headers
+[travis-image]: https://badgen.net/travis/jshttp/on-headers/master
+[travis-url]: https://travis-ci.org/jshttp/on-headers
diff --git a/d2d_app/node_modules/on-headers/index.js b/d2d_app/node_modules/on-headers/index.js
new file mode 100644 (file)
index 0000000..7db6375
--- /dev/null
@@ -0,0 +1,132 @@
+/*!
+ * on-headers
+ * Copyright(c) 2014 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = onHeaders
+
+/**
+ * Create a replacement writeHead method.
+ *
+ * @param {function} prevWriteHead
+ * @param {function} listener
+ * @private
+ */
+
+function createWriteHead (prevWriteHead, listener) {
+  var fired = false
+
+  // return function with core name and argument list
+  return function writeHead (statusCode) {
+    // set headers from arguments
+    var args = setWriteHeadHeaders.apply(this, arguments)
+
+    // fire listener
+    if (!fired) {
+      fired = true
+      listener.call(this)
+
+      // pass-along an updated status code
+      if (typeof args[0] === 'number' && this.statusCode !== args[0]) {
+        args[0] = this.statusCode
+        args.length = 1
+      }
+    }
+
+    return prevWriteHead.apply(this, args)
+  }
+}
+
+/**
+ * Execute a listener when a response is about to write headers.
+ *
+ * @param {object} res
+ * @return {function} listener
+ * @public
+ */
+
+function onHeaders (res, listener) {
+  if (!res) {
+    throw new TypeError('argument res is required')
+  }
+
+  if (typeof listener !== 'function') {
+    throw new TypeError('argument listener must be a function')
+  }
+
+  res.writeHead = createWriteHead(res.writeHead, listener)
+}
+
+/**
+ * Set headers contained in array on the response object.
+ *
+ * @param {object} res
+ * @param {array} headers
+ * @private
+ */
+
+function setHeadersFromArray (res, headers) {
+  for (var i = 0; i < headers.length; i++) {
+    res.setHeader(headers[i][0], headers[i][1])
+  }
+}
+
+/**
+ * Set headers contained in object on the response object.
+ *
+ * @param {object} res
+ * @param {object} headers
+ * @private
+ */
+
+function setHeadersFromObject (res, headers) {
+  var keys = Object.keys(headers)
+  for (var i = 0; i < keys.length; i++) {
+    var k = keys[i]
+    if (k) res.setHeader(k, headers[k])
+  }
+}
+
+/**
+ * Set headers and other properties on the response object.
+ *
+ * @param {number} statusCode
+ * @private
+ */
+
+function setWriteHeadHeaders (statusCode) {
+  var length = arguments.length
+  var headerIndex = length > 1 && typeof arguments[1] === 'string'
+    ? 2
+    : 1
+
+  var headers = length >= headerIndex + 1
+    ? arguments[headerIndex]
+    : undefined
+
+  this.statusCode = statusCode
+
+  if (Array.isArray(headers)) {
+    // handle array case
+    setHeadersFromArray(this, headers)
+  } else if (headers) {
+    // handle object case
+    setHeadersFromObject(this, headers)
+  }
+
+  // copy leading arguments
+  var args = new Array(Math.min(length, headerIndex))
+  for (var i = 0; i < args.length; i++) {
+    args[i] = arguments[i]
+  }
+
+  return args
+}
diff --git a/d2d_app/node_modules/on-headers/package.json b/d2d_app/node_modules/on-headers/package.json
new file mode 100644 (file)
index 0000000..43c7cb1
--- /dev/null
@@ -0,0 +1,77 @@
+{
+  "_from": "on-headers@~1.0.2",
+  "_id": "on-headers@1.0.2",
+  "_inBundle": false,
+  "_integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+  "_location": "/on-headers",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "on-headers@~1.0.2",
+    "name": "on-headers",
+    "escapedName": "on-headers",
+    "rawSpec": "~1.0.2",
+    "saveSpec": null,
+    "fetchSpec": "~1.0.2"
+  },
+  "_requiredBy": [
+    "/express-session"
+  ],
+  "_resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+  "_shasum": "772b0ae6aaa525c399e489adfad90c403eb3c28f",
+  "_spec": "on-headers@~1.0.2",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/express-session",
+  "author": {
+    "name": "Douglas Christopher Wilson",
+    "email": "doug@somethingdoug.com"
+  },
+  "bugs": {
+    "url": "https://github.com/jshttp/on-headers/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "Execute a listener when a response is about to write headers",
+  "devDependencies": {
+    "eslint": "5.14.1",
+    "eslint-config-standard": "12.0.0",
+    "eslint-plugin-import": "2.16.0",
+    "eslint-plugin-markdown": "1.0.0",
+    "eslint-plugin-node": "8.0.1",
+    "eslint-plugin-promise": "4.0.1",
+    "eslint-plugin-standard": "4.0.0",
+    "istanbul": "0.4.5",
+    "mocha": "6.0.1",
+    "supertest": "3.4.2"
+  },
+  "engines": {
+    "node": ">= 0.8"
+  },
+  "files": [
+    "LICENSE",
+    "HISTORY.md",
+    "README.md",
+    "index.js"
+  ],
+  "homepage": "https://github.com/jshttp/on-headers#readme",
+  "keywords": [
+    "event",
+    "headers",
+    "http",
+    "onheaders"
+  ],
+  "license": "MIT",
+  "name": "on-headers",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/jshttp/on-headers.git"
+  },
+  "scripts": {
+    "lint": "eslint --plugin markdown --ext js,md .",
+    "test": "mocha --reporter spec --bail --check-leaks test/",
+    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
+    "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
+    "version": "node scripts/version-history.js && git add HISTORY.md"
+  },
+  "version": "1.0.2"
+}
     "fetchSpec": "~1.3.3"
   },
   "_requiredBy": [
-    "/express",
-    "/finalhandler",
-    "/serve-static"
+    "/express-session"
   ],
   "_resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
   "_shasum": "9da19e7bee8d12dff0513ed5b76957793bc2e8d4",
   "_spec": "parseurl@~1.3.3",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/express",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/express-session",
   "bugs": {
     "url": "https://github.com/pillarjs/parseurl/issues"
   },
diff --git a/d2d_app/node_modules/random-bytes/HISTORY.md b/d2d_app/node_modules/random-bytes/HISTORY.md
new file mode 100644 (file)
index 0000000..8cabd9d
--- /dev/null
@@ -0,0 +1,4 @@
+1.0.0 / 2016-01-17
+==================
+
+  * Initial release
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2010 Benjamin Thomas, Robert Kieffer
+Copyright (c) 2016 Douglas Christopher Wilson <doug@somethingdoug.com>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/d2d_app/node_modules/random-bytes/README.md b/d2d_app/node_modules/random-bytes/README.md
new file mode 100644 (file)
index 0000000..df5aacc
--- /dev/null
@@ -0,0 +1,77 @@
+# random-bytes
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Node.js Version][node-version-image]][node-version-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+Generate strong pseudo-random bytes.
+
+This module is a simple wrapper around the Node.js core `crypto.randomBytes` API,
+with the following additions:
+
+  * A `Promise` interface for environments with promises.
+  * For Node.js versions that do not wait for the PRNG to be seeded, this module
+    will wait a bit.
+
+## Installation
+
+```sh
+$ npm install random-bytes
+```
+
+## API
+
+```js
+var randomBytes = require('random-bytes')
+```
+
+### randomBytes(size, callback)
+
+Generates strong pseudo-random bytes. The `size` argument is a number indicating
+the number of bytes to generate.
+
+```js
+randomBytes(12, function (error, bytes) {
+  if (error) throw error
+  // do something with the bytes
+})
+```
+
+### randomBytes(size)
+
+Generates strong pseudo-random bytes and return a `Promise`. The `size` argument is
+a number indicating the number of bytes to generate.
+
+**Note**: To use promises in Node.js _prior to 0.12_, promises must be
+"polyfilled" using `global.Promise = require('bluebird')`.
+
+```js
+randomBytes(18).then(function (string) {
+  // do something with the string
+})
+```
+
+### randomBytes.sync(size)
+
+A synchronous version of above.
+
+```js
+var bytes = randomBytes.sync(18)
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/random-bytes.svg
+[npm-url]: https://npmjs.org/package/random-bytes
+[node-version-image]: https://img.shields.io/node/v/random-bytes.svg
+[node-version-url]: http://nodejs.org/download/
+[travis-image]: https://img.shields.io/travis/crypto-utils/random-bytes/master.svg
+[travis-url]: https://travis-ci.org/crypto-utils/random-bytes
+[coveralls-image]: https://img.shields.io/coveralls/crypto-utils/random-bytes/master.svg
+[coveralls-url]: https://coveralls.io/r/crypto-utils/random-bytes?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/random-bytes.svg
+[downloads-url]: https://npmjs.org/package/random-bytes
diff --git a/d2d_app/node_modules/random-bytes/index.js b/d2d_app/node_modules/random-bytes/index.js
new file mode 100644 (file)
index 0000000..9ad930f
--- /dev/null
@@ -0,0 +1,101 @@
+/*!
+ * random-bytes
+ * Copyright(c) 2016 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var crypto = require('crypto')
+
+/**
+ * Module variables.
+ * @private
+ */
+
+var generateAttempts = crypto.randomBytes === crypto.pseudoRandomBytes ? 1 : 3
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = randomBytes
+module.exports.sync = randomBytesSync
+
+/**
+ * Generates strong pseudo-random bytes.
+ *
+ * @param {number} size
+ * @param {function} [callback]
+ * @return {Promise}
+ * @public
+ */
+
+function randomBytes(size, callback) {
+  // validate callback is a function, if provided
+  if (callback !== undefined && typeof callback !== 'function') {
+    throw new TypeError('argument callback must be a function')
+  }
+
+  // require the callback without promises
+  if (!callback && !global.Promise) {
+    throw new TypeError('argument callback is required')
+  }
+
+  if (callback) {
+    // classic callback style
+    return generateRandomBytes(size, generateAttempts, callback)
+  }
+
+  return new Promise(function executor(resolve, reject) {
+    generateRandomBytes(size, generateAttempts, function onRandomBytes(err, str) {
+      if (err) return reject(err)
+      resolve(str)
+    })
+  })
+}
+
+/**
+ * Generates strong pseudo-random bytes sync.
+ *
+ * @param {number} size
+ * @return {Buffer}
+ * @public
+ */
+
+function randomBytesSync(size) {
+  var err = null
+
+  for (var i = 0; i < generateAttempts; i++) {
+    try {
+      return crypto.randomBytes(size)
+    } catch (e) {
+      err = e
+    }
+  }
+
+  throw err
+}
+
+/**
+ * Generates strong pseudo-random bytes.
+ *
+ * @param {number} size
+ * @param {number} attempts
+ * @param {function} callback
+ * @private
+ */
+
+function generateRandomBytes(size, attempts, callback) {
+  crypto.randomBytes(size, function onRandomBytes(err, buf) {
+    if (!err) return callback(null, buf)
+    if (!--attempts) return callback(err)
+    setTimeout(generateRandomBytes.bind(null, size, attempts, callback), 10)
+  })
+}
diff --git a/d2d_app/node_modules/random-bytes/package.json b/d2d_app/node_modules/random-bytes/package.json
new file mode 100644 (file)
index 0000000..2ced492
--- /dev/null
@@ -0,0 +1,71 @@
+{
+  "_from": "random-bytes@~1.0.0",
+  "_id": "random-bytes@1.0.0",
+  "_inBundle": false,
+  "_integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=",
+  "_location": "/random-bytes",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "random-bytes@~1.0.0",
+    "name": "random-bytes",
+    "escapedName": "random-bytes",
+    "rawSpec": "~1.0.0",
+    "saveSpec": null,
+    "fetchSpec": "~1.0.0"
+  },
+  "_requiredBy": [
+    "/uid-safe"
+  ],
+  "_resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
+  "_shasum": "4f68a1dc0ae58bd3fb95848c30324db75d64360b",
+  "_spec": "random-bytes@~1.0.0",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/uid-safe",
+  "bugs": {
+    "url": "https://github.com/crypto-utils/random-bytes/issues"
+  },
+  "bundleDependencies": false,
+  "contributors": [
+    {
+      "name": "Douglas Christopher Wilson",
+      "email": "doug@somethingdoug.com"
+    }
+  ],
+  "deprecated": false,
+  "description": "URL and cookie safe UIDs",
+  "devDependencies": {
+    "bluebird": "3.1.1",
+    "istanbul": "0.4.2",
+    "mocha": "2.3.4",
+    "proxyquire": "1.2.0"
+  },
+  "engines": {
+    "node": ">= 0.8"
+  },
+  "files": [
+    "LICENSE",
+    "HISTORY.md",
+    "README.md",
+    "index.js"
+  ],
+  "homepage": "https://github.com/crypto-utils/random-bytes#readme",
+  "keywords": [
+    "bytes",
+    "generator",
+    "random",
+    "safe"
+  ],
+  "license": "MIT",
+  "name": "random-bytes",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/crypto-utils/random-bytes.git"
+  },
+  "scripts": {
+    "test": "mocha --trace-deprecation --reporter spec --bail --check-leaks test/",
+    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --trace-deprecation --reporter dot --check-leaks test/",
+    "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --trace-deprecation --reporter spec --check-leaks test/"
+  },
+  "version": "1.0.0"
+}
@@ -22,6 +22,8 @@
 npm install safe-buffer
 ```
 
+[Get supported safe-buffer with the Tidelift Subscription](https://tidelift.com/subscription/pkg/npm-safe-buffer?utm_source=npm-safe-buffer&utm_medium=referral&utm_campaign=readme)
+
 ## usage
 
 The goal of this package is to provide a safe replacement for the node.js `Buffer`.
@@ -20,6 +20,8 @@ function SafeBuffer (arg, encodingOrOffset, length) {
   return Buffer(arg, encodingOrOffset, length)
 }
 
+SafeBuffer.prototype = Object.create(Buffer.prototype)
+
 // Copy static methods from Buffer
 copyProps(Buffer, SafeBuffer)
 
@@ -1,45 +1,27 @@
 {
-  "_from": "safe-buffer@5.1.2",
-  "_id": "safe-buffer@5.1.2",
+  "_from": "safe-buffer@5.2.0",
+  "_id": "safe-buffer@5.2.0",
   "_inBundle": false,
-  "_integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+  "_integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
   "_location": "/safe-buffer",
   "_phantomChildren": {},
   "_requested": {
     "type": "version",
     "registry": true,
-    "raw": "safe-buffer@5.1.2",
+    "raw": "safe-buffer@5.2.0",
     "name": "safe-buffer",
     "escapedName": "safe-buffer",
-    "rawSpec": "5.1.2",
+    "rawSpec": "5.2.0",
     "saveSpec": null,
-    "fetchSpec": "5.1.2"
+    "fetchSpec": "5.2.0"
   },
   "_requiredBy": [
-    "/are-we-there-yet/readable-stream",
-    "/are-we-there-yet/string_decoder",
-    "/concat-stream/readable-stream",
-    "/concat-stream/string_decoder",
-    "/content-disposition",
-    "/express",
-    "/memory-fs/readable-stream",
-    "/memory-fs/string_decoder",
-    "/node-libs-browser/readable-stream",
-    "/node-libs-browser/readable-stream/string_decoder",
-    "/readdirp/readable-stream",
-    "/readdirp/string_decoder",
-    "/request",
-    "/stream-browserify/readable-stream",
-    "/stream-browserify/string_decoder",
-    "/stream-http/readable-stream",
-    "/stream-http/string_decoder",
-    "/tunnel-agent",
-    "/websocket-driver"
+    "/express-session"
   ],
-  "_resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-  "_shasum": "991ec69d296e0313747d59bdfd2b745c35f8828d",
-  "_spec": "safe-buffer@5.1.2",
-  "_where": "/home/hyunduk/opensource/external/HappyFunTimes/node_modules/express",
+  "_resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+  "_shasum": "b74daec49b1148f88c64b68d49b1e815c1f2f519",
+  "_spec": "safe-buffer@5.2.0",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/express-session",
   "author": {
     "name": "Feross Aboukhadijeh",
     "email": "feross@feross.org",
@@ -76,5 +58,5 @@
     "test": "standard && tape test/*.js"
   },
   "types": "index.d.ts",
-  "version": "5.1.2"
+  "version": "5.2.0"
 }
diff --git a/d2d_app/node_modules/supports-color/browser.js b/d2d_app/node_modules/supports-color/browser.js
new file mode 100644 (file)
index 0000000..62afa3a
--- /dev/null
@@ -0,0 +1,5 @@
+'use strict';
+module.exports = {
+       stdout: false,
+       stderr: false
+};
diff --git a/d2d_app/node_modules/supports-color/index.js b/d2d_app/node_modules/supports-color/index.js
new file mode 100644 (file)
index 0000000..1704131
--- /dev/null
@@ -0,0 +1,131 @@
+'use strict';
+const os = require('os');
+const hasFlag = require('has-flag');
+
+const env = process.env;
+
+let forceColor;
+if (hasFlag('no-color') ||
+       hasFlag('no-colors') ||
+       hasFlag('color=false')) {
+       forceColor = false;
+} else if (hasFlag('color') ||
+       hasFlag('colors') ||
+       hasFlag('color=true') ||
+       hasFlag('color=always')) {
+       forceColor = true;
+}
+if ('FORCE_COLOR' in env) {
+       forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;
+}
+
+function translateLevel(level) {
+       if (level === 0) {
+               return false;
+       }
+
+       return {
+               level,
+               hasBasic: true,
+               has256: level >= 2,
+               has16m: level >= 3
+       };
+}
+
+function supportsColor(stream) {
+       if (forceColor === false) {
+               return 0;
+       }
+
+       if (hasFlag('color=16m') ||
+               hasFlag('color=full') ||
+               hasFlag('color=truecolor')) {
+               return 3;
+       }
+
+       if (hasFlag('color=256')) {
+               return 2;
+       }
+
+       if (stream && !stream.isTTY && forceColor !== true) {
+               return 0;
+       }
+
+       const min = forceColor ? 1 : 0;
+
+       if (process.platform === 'win32') {
+               // Node.js 7.5.0 is the first version of Node.js to include a patch to
+               // libuv that enables 256 color output on Windows. Anything earlier and it
+               // won't work. However, here we target Node.js 8 at minimum as it is an LTS
+               // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows
+               // release that supports 256 colors. Windows 10 build 14931 is the first release
+               // that supports 16m/TrueColor.
+               const osRelease = os.release().split('.');
+               if (
+                       Number(process.versions.node.split('.')[0]) >= 8 &&
+                       Number(osRelease[0]) >= 10 &&
+                       Number(osRelease[2]) >= 10586
+               ) {
+                       return Number(osRelease[2]) >= 14931 ? 3 : 2;
+               }
+
+               return 1;
+       }
+
+       if ('CI' in env) {
+               if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
+                       return 1;
+               }
+
+               return min;
+       }
+
+       if ('TEAMCITY_VERSION' in env) {
+               return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
+       }
+
+       if (env.COLORTERM === 'truecolor') {
+               return 3;
+       }
+
+       if ('TERM_PROGRAM' in env) {
+               const version = parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
+
+               switch (env.TERM_PROGRAM) {
+                       case 'iTerm.app':
+                               return version >= 3 ? 3 : 2;
+                       case 'Apple_Terminal':
+                               return 2;
+                       // No default
+               }
+       }
+
+       if (/-256(color)?$/i.test(env.TERM)) {
+               return 2;
+       }
+
+       if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
+               return 1;
+       }
+
+       if ('COLORTERM' in env) {
+               return 1;
+       }
+
+       if (env.TERM === 'dumb') {
+               return min;
+       }
+
+       return min;
+}
+
+function getSupportLevel(stream) {
+       const level = supportsColor(stream);
+       return translateLevel(level);
+}
+
+module.exports = {
+       supportsColor: getSupportLevel,
+       stdout: getSupportLevel(process.stdout),
+       stderr: getSupportLevel(process.stderr)
+};
diff --git a/d2d_app/node_modules/supports-color/license b/d2d_app/node_modules/supports-color/license
new file mode 100644 (file)
index 0000000..e7af2f7
--- /dev/null
@@ -0,0 +1,9 @@
+MIT License
+
+Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/supports-color/package.json b/d2d_app/node_modules/supports-color/package.json
new file mode 100644 (file)
index 0000000..b3ead20
--- /dev/null
@@ -0,0 +1,85 @@
+{
+  "_from": "supports-color@^5.3.0",
+  "_id": "supports-color@5.5.0",
+  "_inBundle": false,
+  "_integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+  "_location": "/supports-color",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "supports-color@^5.3.0",
+    "name": "supports-color",
+    "escapedName": "supports-color",
+    "rawSpec": "^5.3.0",
+    "saveSpec": null,
+    "fetchSpec": "^5.3.0"
+  },
+  "_requiredBy": [
+    "/chalk"
+  ],
+  "_resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+  "_shasum": "e2e69a44ac8772f78a1ec0b35b689df6530efc8f",
+  "_spec": "supports-color@^5.3.0",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/chalk",
+  "author": {
+    "name": "Sindre Sorhus",
+    "email": "sindresorhus@gmail.com",
+    "url": "sindresorhus.com"
+  },
+  "browser": "browser.js",
+  "bugs": {
+    "url": "https://github.com/chalk/supports-color/issues"
+  },
+  "bundleDependencies": false,
+  "dependencies": {
+    "has-flag": "^3.0.0"
+  },
+  "deprecated": false,
+  "description": "Detect whether a terminal supports color",
+  "devDependencies": {
+    "ava": "^0.25.0",
+    "import-fresh": "^2.0.0",
+    "xo": "^0.20.0"
+  },
+  "engines": {
+    "node": ">=4"
+  },
+  "files": [
+    "index.js",
+    "browser.js"
+  ],
+  "homepage": "https://github.com/chalk/supports-color#readme",
+  "keywords": [
+    "color",
+    "colour",
+    "colors",
+    "terminal",
+    "console",
+    "cli",
+    "ansi",
+    "styles",
+    "tty",
+    "rgb",
+    "256",
+    "shell",
+    "xterm",
+    "command-line",
+    "support",
+    "supports",
+    "capability",
+    "detect",
+    "truecolor",
+    "16m"
+  ],
+  "license": "MIT",
+  "name": "supports-color",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/chalk/supports-color.git"
+  },
+  "scripts": {
+    "test": "xo && ava"
+  },
+  "version": "5.5.0"
+}
diff --git a/d2d_app/node_modules/supports-color/readme.md b/d2d_app/node_modules/supports-color/readme.md
new file mode 100644 (file)
index 0000000..f6e4019
--- /dev/null
@@ -0,0 +1,66 @@
+# supports-color [![Build Status](https://travis-ci.org/chalk/supports-color.svg?branch=master)](https://travis-ci.org/chalk/supports-color)
+
+> Detect whether a terminal supports color
+
+
+## Install
+
+```
+$ npm install supports-color
+```
+
+
+## Usage
+
+```js
+const supportsColor = require('supports-color');
+
+if (supportsColor.stdout) {
+       console.log('Terminal stdout supports color');
+}
+
+if (supportsColor.stdout.has256) {
+       console.log('Terminal stdout supports 256 colors');
+}
+
+if (supportsColor.stderr.has16m) {
+       console.log('Terminal stderr supports 16 million colors (truecolor)');
+}
+```
+
+
+## API
+
+Returns an `Object` with a `stdout` and `stderr` property for testing either streams. Each property is an `Object`, or `false` if color is not supported.
+
+The `stdout`/`stderr` objects specifies a level of support for color through a `.level` property and a corresponding flag:
+
+- `.level = 1` and `.hasBasic = true`: Basic color support (16 colors)
+- `.level = 2` and `.has256 = true`: 256 color support
+- `.level = 3` and `.has16m = true`: Truecolor support (16 million colors)
+
+
+## Info
+
+It obeys the `--color` and `--no-color` CLI flags.
+
+Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add the environment variable `FORCE_COLOR=1` to forcefully enable color or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks.
+
+Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively.
+
+
+## Related
+
+- [supports-color-cli](https://github.com/chalk/supports-color-cli) - CLI for this module
+- [chalk](https://github.com/chalk/chalk) - Terminal string styling done right
+
+
+## Maintainers
+
+- [Sindre Sorhus](https://github.com/sindresorhus)
+- [Josh Junon](https://github.com/qix-)
+
+
+## License
+
+MIT
diff --git a/d2d_app/node_modules/uid-safe/HISTORY.md b/d2d_app/node_modules/uid-safe/HISTORY.md
new file mode 100644 (file)
index 0000000..3ec249f
--- /dev/null
@@ -0,0 +1,61 @@
+2.1.5 / 2017-08-02
+==================
+
+  * perf: remove only trailing `=`
+
+2.1.4 / 2017-03-02
+==================
+
+  * Remove `base64-url` dependency
+
+2.1.3 / 2016-10-30
+==================
+
+  * deps: base64-url@1.3.3
+
+2.1.2 / 2016-08-15
+==================
+
+  * deps: base64-url@1.3.2
+
+2.1.1 / 2016-05-04
+==================
+
+  * deps: base64-url@1.2.2
+
+2.1.0 / 2016-01-17
+==================
+
+  * Use `random-bytes` for byte source
+
+2.0.0 / 2015-05-08
+==================
+
+  * Use global `Promise` when returning a promise
+
+1.1.0 / 2015-02-01
+==================
+
+  * Use `crypto.randomBytes`, if available
+  * deps: base64-url@1.2.1
+
+1.0.3 / 2015-01-31
+==================
+
+  * Fix error branch that would throw
+  * deps: base64-url@1.2.0
+
+1.0.2 / 2015-01-08
+==================
+
+  * Remove dependency on `mz`
+
+1.0.1 / 2014-06-18
+==================
+
+  * Remove direct `bluebird` dependency
+
+1.0.0 / 2014-06-18
+==================
+
+  * Initial release
diff --git a/d2d_app/node_modules/uid-safe/LICENSE b/d2d_app/node_modules/uid-safe/LICENSE
new file mode 100644 (file)
index 0000000..c4b8a49
--- /dev/null
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
+Copyright (c) 2015-2017 Douglas Christopher Wilson <doug@somethingdoug.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/d2d_app/node_modules/uid-safe/README.md b/d2d_app/node_modules/uid-safe/README.md
new file mode 100644 (file)
index 0000000..fa02be8
--- /dev/null
@@ -0,0 +1,77 @@
+# uid-safe
+
+[![NPM Version][npm-image]][npm-url]
+[![NPM Downloads][downloads-image]][downloads-url]
+[![Node.js Version][node-version-image]][node-version-url]
+[![Build Status][travis-image]][travis-url]
+[![Test Coverage][coveralls-image]][coveralls-url]
+
+URL and cookie safe UIDs
+
+Create cryptographically secure UIDs safe for both cookie and URL usage.
+This is in contrast to modules such as [rand-token](https://www.npmjs.com/package/rand-token)
+and [uid2](https://www.npmjs.com/package/uid2) whose UIDs are actually skewed
+due to the use of `%` and unnecessarily truncate the UID.
+Use this if you could still use UIDs with `-` and `_` in them.
+
+## Installation
+
+```sh
+$ npm install uid-safe
+```
+
+## API
+
+```js
+var uid = require('uid-safe')
+```
+
+### uid(byteLength, callback)
+
+Asynchronously create a UID with a specific byte length. Because `base64`
+encoding is used underneath, this is not the string length. For example,
+to create a UID of length 24, you want a byte length of 18.
+
+```js
+uid(18, function (err, string) {
+  if (err) throw err
+  // do something with the string
+})
+```
+
+### uid(byteLength)
+
+Asynchronously create a UID with a specific byte length and return a
+`Promise`.
+
+**Note**: To use promises in Node.js _prior to 0.12_, promises must be
+"polyfilled" using `global.Promise = require('bluebird')`.
+
+```js
+uid(18).then(function (string) {
+  // do something with the string
+})
+```
+
+### uid.sync(byteLength)
+
+A synchronous version of above.
+
+```js
+var string = uid.sync(18)
+```
+
+## License
+
+[MIT](LICENSE)
+
+[npm-image]: https://img.shields.io/npm/v/uid-safe.svg
+[npm-url]: https://npmjs.org/package/uid-safe
+[node-version-image]: https://img.shields.io/node/v/uid-safe.svg
+[node-version-url]: https://nodejs.org/en/download/
+[travis-image]: https://img.shields.io/travis/crypto-utils/uid-safe/master.svg
+[travis-url]: https://travis-ci.org/crypto-utils/uid-safe
+[coveralls-image]: https://img.shields.io/coveralls/crypto-utils/uid-safe/master.svg
+[coveralls-url]: https://coveralls.io/r/crypto-utils/uid-safe?branch=master
+[downloads-image]: https://img.shields.io/npm/dm/uid-safe.svg
+[downloads-url]: https://npmjs.org/package/uid-safe
diff --git a/d2d_app/node_modules/uid-safe/index.js b/d2d_app/node_modules/uid-safe/index.js
new file mode 100644 (file)
index 0000000..18e8492
--- /dev/null
@@ -0,0 +1,107 @@
+/*!
+ * uid-safe
+ * Copyright(c) 2014 Jonathan Ong
+ * Copyright(c) 2015-2017 Douglas Christopher Wilson
+ * MIT Licensed
+ */
+
+'use strict'
+
+/**
+ * Module dependencies.
+ * @private
+ */
+
+var randomBytes = require('random-bytes')
+
+/**
+ * Module variables.
+ * @private
+ */
+
+var EQUAL_END_REGEXP = /=+$/
+var PLUS_GLOBAL_REGEXP = /\+/g
+var SLASH_GLOBAL_REGEXP = /\//g
+
+/**
+ * Module exports.
+ * @public
+ */
+
+module.exports = uid
+module.exports.sync = uidSync
+
+/**
+ * Create a unique ID.
+ *
+ * @param {number} length
+ * @param {function} [callback]
+ * @return {Promise}
+ * @public
+ */
+
+function uid (length, callback) {
+  // validate callback is a function, if provided
+  if (callback !== undefined && typeof callback !== 'function') {
+    throw new TypeError('argument callback must be a function')
+  }
+
+  // require the callback without promises
+  if (!callback && !global.Promise) {
+    throw new TypeError('argument callback is required')
+  }
+
+  if (callback) {
+    // classic callback style
+    return generateUid(length, callback)
+  }
+
+  return new Promise(function executor (resolve, reject) {
+    generateUid(length, function onUid (err, str) {
+      if (err) return reject(err)
+      resolve(str)
+    })
+  })
+}
+
+/**
+ * Create a unique ID sync.
+ *
+ * @param {number} length
+ * @return {string}
+ * @public
+ */
+
+function uidSync (length) {
+  return toString(randomBytes.sync(length))
+}
+
+/**
+ * Generate a unique ID string.
+ *
+ * @param {number} length
+ * @param {function} callback
+ * @private
+ */
+
+function generateUid (length, callback) {
+  randomBytes(length, function (err, buf) {
+    if (err) return callback(err)
+    callback(null, toString(buf))
+  })
+}
+
+/**
+ * Change a Buffer into a string.
+ *
+ * @param {Buffer} buf
+ * @return {string}
+ * @private
+ */
+
+function toString (buf) {
+  return buf.toString('base64')
+    .replace(EQUAL_END_REGEXP, '')
+    .replace(PLUS_GLOBAL_REGEXP, '-')
+    .replace(SLASH_GLOBAL_REGEXP, '_')
+}
diff --git a/d2d_app/node_modules/uid-safe/package.json b/d2d_app/node_modules/uid-safe/package.json
new file mode 100644 (file)
index 0000000..a27ff28
--- /dev/null
@@ -0,0 +1,85 @@
+{
+  "_from": "uid-safe@~2.1.5",
+  "_id": "uid-safe@2.1.5",
+  "_inBundle": false,
+  "_integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
+  "_location": "/uid-safe",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "range",
+    "registry": true,
+    "raw": "uid-safe@~2.1.5",
+    "name": "uid-safe",
+    "escapedName": "uid-safe",
+    "rawSpec": "~2.1.5",
+    "saveSpec": null,
+    "fetchSpec": "~2.1.5"
+  },
+  "_requiredBy": [
+    "/express-session"
+  ],
+  "_resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
+  "_shasum": "2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a",
+  "_spec": "uid-safe@~2.1.5",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen/node_modules/express-session",
+  "bugs": {
+    "url": "https://github.com/crypto-utils/uid-safe/issues"
+  },
+  "bundleDependencies": false,
+  "contributors": [
+    {
+      "name": "Douglas Christopher Wilson",
+      "email": "doug@somethingdoug.com"
+    },
+    {
+      "name": "Jonathan Ong",
+      "email": "me@jongleberry.com",
+      "url": "http://jongleberry.com"
+    }
+  ],
+  "dependencies": {
+    "random-bytes": "~1.0.0"
+  },
+  "deprecated": false,
+  "description": "URL and cookie safe UIDs",
+  "devDependencies": {
+    "bluebird": "3.5.0",
+    "eslint": "3.19.0",
+    "eslint-config-standard": "10.2.1",
+    "eslint-plugin-import": "2.7.0",
+    "eslint-plugin-node": "5.1.1",
+    "eslint-plugin-promise": "3.5.0",
+    "eslint-plugin-standard": "3.0.1",
+    "istanbul": "0.4.5",
+    "mocha": "2.5.3"
+  },
+  "engines": {
+    "node": ">= 0.8"
+  },
+  "files": [
+    "LICENSE",
+    "HISTORY.md",
+    "README.md",
+    "index.js"
+  ],
+  "homepage": "https://github.com/crypto-utils/uid-safe#readme",
+  "keywords": [
+    "random",
+    "generator",
+    "uid",
+    "safe"
+  ],
+  "license": "MIT",
+  "name": "uid-safe",
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/crypto-utils/uid-safe.git"
+  },
+  "scripts": {
+    "lint": "eslint .",
+    "test": "mocha --trace-deprecation --reporter spec --bail --check-leaks test/",
+    "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --trace-deprecation --reporter dot --check-leaks test/",
+    "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --trace-deprecation --reporter spec --check-leaks test/"
+  },
+  "version": "2.1.5"
+}
diff --git a/d2d_app/node_modules/xmlhttprequest/.jshintrc b/d2d_app/node_modules/xmlhttprequest/.jshintrc
new file mode 100644 (file)
index 0000000..3df2adc
--- /dev/null
@@ -0,0 +1,26 @@
+{
+  "node": true,
+  "browser": false,
+  "esnext": true,
+  "bitwise": false,
+  "camelcase": true,
+  "curly": true,
+  "eqeqeq": true,
+  "eqnull": true,
+  "immed": true,
+  "indent": 2,
+  "latedef": true,
+  "laxbreak": true,
+  "newcap": true,
+  "noarg": true,
+  "quotmark": "double",
+  "regexp": true,
+  "undef": true,
+  "unused": true,
+  "strict": true,
+  "trailing": true,
+  "smarttabs": true,
+  "globals": {
+    "define": false
+  }
+}
diff --git a/d2d_app/node_modules/xmlhttprequest/.npmignore b/d2d_app/node_modules/xmlhttprequest/.npmignore
new file mode 100644 (file)
index 0000000..97b5e9b
--- /dev/null
@@ -0,0 +1,4 @@
+example
+tests
+
+autotest.watchr
diff --git a/d2d_app/node_modules/xmlhttprequest/LICENSE b/d2d_app/node_modules/xmlhttprequest/LICENSE
new file mode 100644 (file)
index 0000000..1c63271
--- /dev/null
@@ -0,0 +1,22 @@
+ Copyright (c) 2010 passive.ly LLC
+
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
diff --git a/d2d_app/node_modules/xmlhttprequest/README.md b/d2d_app/node_modules/xmlhttprequest/README.md
new file mode 100644 (file)
index 0000000..50039f9
--- /dev/null
@@ -0,0 +1,55 @@
+# node-XMLHttpRequest #
+
+node-XMLHttpRequest is a wrapper for the built-in http client to emulate the
+browser XMLHttpRequest object.
+
+This can be used with JS designed for browsers to improve reuse of code and
+allow the use of existing libraries.
+
+Note: This library currently conforms to [XMLHttpRequest 1](http://www.w3.org/TR/XMLHttpRequest/). Version 2.0 will target [XMLHttpRequest Level 2](http://www.w3.org/TR/XMLHttpRequest2/).
+
+## Usage ##
+
+Here's how to include the module in your project and use as the browser-based
+XHR object.
+
+       var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
+       var xhr = new XMLHttpRequest();
+
+Note: use the lowercase string "xmlhttprequest" in your require(). On
+case-sensitive systems (eg Linux) using uppercase letters won't work.
+
+## Versions ##
+
+Prior to 1.4.0 version numbers were arbitrary. From 1.4.0 on they conform to
+the standard major.minor.bugfix. 1.x shouldn't necessarily be considered
+stable just because it's above 0.x.
+
+Since the XMLHttpRequest API is stable this library's API is stable as
+well. Major version numbers indicate significant core code changes.
+Minor versions indicate minor core code changes or better conformity to
+the W3C spec.
+
+## License ##
+
+MIT license. See LICENSE for full details.
+
+## Supports ##
+
+* Async and synchronous requests
+* GET, POST, PUT, and DELETE requests
+* All spec methods (open, send, abort, getRequestHeader,
+  getAllRequestHeaders, event methods)
+* Requests to all domains
+
+## Known Issues / Missing Features ##
+
+For a list of open issues or to report your own visit the [github issues
+page](https://github.com/driverdan/node-XMLHttpRequest/issues).
+
+* Local file access may have unexpected results for non-UTF8 files
+* Synchronous requests don't set headers properly
+* Synchronous requests freeze node while waiting for response (But that's what you want, right? Stick with async!).
+* Some events are missing, such as abort
+* Cookies aren't persisted between requests
+* Missing XML support
diff --git a/d2d_app/node_modules/xmlhttprequest/lib/XMLHttpRequest.js b/d2d_app/node_modules/xmlhttprequest/lib/XMLHttpRequest.js
new file mode 100644 (file)
index 0000000..4893913
--- /dev/null
@@ -0,0 +1,620 @@
+/**
+ * Wrapper for built-in http.js to emulate the browser XMLHttpRequest object.
+ *
+ * This can be used with JS designed for browsers to improve reuse of code and
+ * allow the use of existing libraries.
+ *
+ * Usage: include("XMLHttpRequest.js") and use XMLHttpRequest per W3C specs.
+ *
+ * @author Dan DeFelippi <dan@driverdan.com>
+ * @contributor David Ellis <d.f.ellis@ieee.org>
+ * @license MIT
+ */
+
+var Url = require("url");
+var spawn = require("child_process").spawn;
+var fs = require("fs");
+
+exports.XMLHttpRequest = function() {
+  "use strict";
+
+  /**
+   * Private variables
+   */
+  var self = this;
+  var http = require("http");
+  var https = require("https");
+
+  // Holds http.js objects
+  var request;
+  var response;
+
+  // Request settings
+  var settings = {};
+
+  // Disable header blacklist.
+  // Not part of XHR specs.
+  var disableHeaderCheck = false;
+
+  // Set some default headers
+  var defaultHeaders = {
+    "User-Agent": "node-XMLHttpRequest",
+    "Accept": "*/*",
+  };
+
+  var headers = {};
+  var headersCase = {};
+
+  // These headers are not user setable.
+  // The following are allowed but banned in the spec:
+  // * user-agent
+  var forbiddenRequestHeaders = [
+    "accept-charset",
+    "accept-encoding",
+    "access-control-request-headers",
+    "access-control-request-method",
+    "connection",
+    "content-length",
+    "content-transfer-encoding",
+    "cookie",
+    "cookie2",
+    "date",
+    "expect",
+    "host",
+    "keep-alive",
+    "origin",
+    "referer",
+    "te",
+    "trailer",
+    "transfer-encoding",
+    "upgrade",
+    "via"
+  ];
+
+  // These request methods are not allowed
+  var forbiddenRequestMethods = [
+    "TRACE",
+    "TRACK",
+    "CONNECT"
+  ];
+
+  // Send flag
+  var sendFlag = false;
+  // Error flag, used when errors occur or abort is called
+  var errorFlag = false;
+
+  // Event listeners
+  var listeners = {};
+
+  /**
+   * Constants
+   */
+
+  this.UNSENT = 0;
+  this.OPENED = 1;
+  this.HEADERS_RECEIVED = 2;
+  this.LOADING = 3;
+  this.DONE = 4;
+
+  /**
+   * Public vars
+   */
+
+  // Current state
+  this.readyState = this.UNSENT;
+
+  // default ready state change handler in case one is not set or is set late
+  this.onreadystatechange = null;
+
+  // Result & response
+  this.responseText = "";
+  this.responseXML = "";
+  this.status = null;
+  this.statusText = null;
+  
+  // Whether cross-site Access-Control requests should be made using
+  // credentials such as cookies or authorization headers
+  this.withCredentials = false;
+
+  /**
+   * Private methods
+   */
+
+  /**
+   * Check if the specified header is allowed.
+   *
+   * @param string header Header to validate
+   * @return boolean False if not allowed, otherwise true
+   */
+  var isAllowedHttpHeader = function(header) {
+    return disableHeaderCheck || (header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1);
+  };
+
+  /**
+   * Check if the specified method is allowed.
+   *
+   * @param string method Request method to validate
+   * @return boolean False if not allowed, otherwise true
+   */
+  var isAllowedHttpMethod = function(method) {
+    return (method && forbiddenRequestMethods.indexOf(method) === -1);
+  };
+
+  /**
+   * Public methods
+   */
+
+  /**
+   * Open the connection. Currently supports local server requests.
+   *
+   * @param string method Connection method (eg GET, POST)
+   * @param string url URL for the connection.
+   * @param boolean async Asynchronous connection. Default is true.
+   * @param string user Username for basic authentication (optional)
+   * @param string password Password for basic authentication (optional)
+   */
+  this.open = function(method, url, async, user, password) {
+    this.abort();
+    errorFlag = false;
+
+    // Check for valid request method
+    if (!isAllowedHttpMethod(method)) {
+      throw new Error("SecurityError: Request method not allowed");
+    }
+
+    settings = {
+      "method": method,
+      "url": url.toString(),
+      "async": (typeof async !== "boolean" ? true : async),
+      "user": user || null,
+      "password": password || null
+    };
+
+    setState(this.OPENED);
+  };
+
+  /**
+   * Disables or enables isAllowedHttpHeader() check the request. Enabled by default.
+   * This does not conform to the W3C spec.
+   *
+   * @param boolean state Enable or disable header checking.
+   */
+  this.setDisableHeaderCheck = function(state) {
+    disableHeaderCheck = state;
+  };
+
+  /**
+   * Sets a header for the request or appends the value if one is already set.
+   *
+   * @param string header Header name
+   * @param string value Header value
+   */
+  this.setRequestHeader = function(header, value) {
+    if (this.readyState !== this.OPENED) {
+      throw new Error("INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN");
+    }
+    if (!isAllowedHttpHeader(header)) {
+      console.warn("Refused to set unsafe header \"" + header + "\"");
+      return;
+    }
+    if (sendFlag) {
+      throw new Error("INVALID_STATE_ERR: send flag is true");
+    }
+    header = headersCase[header.toLowerCase()] || header;
+    headersCase[header.toLowerCase()] = header;
+    headers[header] = headers[header] ? headers[header] + ', ' + value : value;
+  };
+
+  /**
+   * Gets a header from the server response.
+   *
+   * @param string header Name of header to get.
+   * @return string Text of the header or null if it doesn't exist.
+   */
+  this.getResponseHeader = function(header) {
+    if (typeof header === "string"
+      && this.readyState > this.OPENED
+      && response
+      && response.headers
+      && response.headers[header.toLowerCase()]
+      && !errorFlag
+    ) {
+      return response.headers[header.toLowerCase()];
+    }
+
+    return null;
+  };
+
+  /**
+   * Gets all the response headers.
+   *
+   * @return string A string with all response headers separated by CR+LF
+   */
+  this.getAllResponseHeaders = function() {
+    if (this.readyState < this.HEADERS_RECEIVED || errorFlag) {
+      return "";
+    }
+    var result = "";
+
+    for (var i in response.headers) {
+      // Cookie headers are excluded
+      if (i !== "set-cookie" && i !== "set-cookie2") {
+        result += i + ": " + response.headers[i] + "\r\n";
+      }
+    }
+    return result.substr(0, result.length - 2);
+  };
+
+  /**
+   * Gets a request header
+   *
+   * @param string name Name of header to get
+   * @return string Returns the request header or empty string if not set
+   */
+  this.getRequestHeader = function(name) {
+    if (typeof name === "string" && headersCase[name.toLowerCase()]) {
+      return headers[headersCase[name.toLowerCase()]];
+    }
+
+    return "";
+  };
+
+  /**
+   * Sends the request to the server.
+   *
+   * @param string data Optional data to send as request body.
+   */
+  this.send = function(data) {
+    if (this.readyState !== this.OPENED) {
+      throw new Error("INVALID_STATE_ERR: connection must be opened before send() is called");
+    }
+
+    if (sendFlag) {
+      throw new Error("INVALID_STATE_ERR: send has already been called");
+    }
+
+    var ssl = false, local = false;
+    var url = Url.parse(settings.url);
+    var host;
+    // Determine the server
+    switch (url.protocol) {
+      case "https:":
+        ssl = true;
+        // SSL & non-SSL both need host, no break here.
+      case "http:":
+        host = url.hostname;
+        break;
+
+      case "file:":
+        local = true;
+        break;
+
+      case undefined:
+      case null:
+      case "":
+        host = "localhost";
+        break;
+
+      default:
+        throw new Error("Protocol not supported.");
+    }
+
+    // Load files off the local filesystem (file://)
+    if (local) {
+      if (settings.method !== "GET") {
+        throw new Error("XMLHttpRequest: Only GET method is supported");
+      }
+
+      if (settings.async) {
+        fs.readFile(url.pathname, "utf8", function(error, data) {
+          if (error) {
+            self.handleError(error);
+          } else {
+            self.status = 200;
+            self.responseText = data;
+            setState(self.DONE);
+          }
+        });
+      } else {
+        try {
+          this.responseText = fs.readFileSync(url.pathname, "utf8");
+          this.status = 200;
+          setState(self.DONE);
+        } catch(e) {
+          this.handleError(e);
+        }
+      }
+
+      return;
+    }
+
+    // Default to port 80. If accessing localhost on another port be sure
+    // to use http://localhost:port/path
+    var port = url.port || (ssl ? 443 : 80);
+    // Add query string if one is used
+    var uri = url.pathname + (url.search ? url.search : "");
+
+    // Set the defaults if they haven't been set
+    for (var name in defaultHeaders) {
+      if (!headersCase[name.toLowerCase()]) {
+        headers[name] = defaultHeaders[name];
+      }
+    }
+
+    // Set the Host header or the server may reject the request
+    headers.Host = host;
+    if (!((ssl && port === 443) || port === 80)) {
+      headers.Host += ":" + url.port;
+    }
+
+    // Set Basic Auth if necessary
+    if (settings.user) {
+      if (typeof settings.password === "undefined") {
+        settings.password = "";
+      }
+      var authBuf = new Buffer(settings.user + ":" + settings.password);
+      headers.Authorization = "Basic " + authBuf.toString("base64");
+    }
+
+    // Set content length header
+    if (settings.method === "GET" || settings.method === "HEAD") {
+      data = null;
+    } else if (data) {
+      headers["Content-Length"] = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data);
+
+      if (!headers["Content-Type"]) {
+        headers["Content-Type"] = "text/plain;charset=UTF-8";
+      }
+    } else if (settings.method === "POST") {
+      // For a post with no data set Content-Length: 0.
+      // This is required by buggy servers that don't meet the specs.
+      headers["Content-Length"] = 0;
+    }
+
+    var options = {
+      host: host,
+      port: port,
+      path: uri,
+      method: settings.method,
+      headers: headers,
+      agent: false,
+      withCredentials: self.withCredentials
+    };
+
+    // Reset error flag
+    errorFlag = false;
+
+    // Handle async requests
+    if (settings.async) {
+      // Use the proper protocol
+      var doRequest = ssl ? https.request : http.request;
+
+      // Request is being sent, set send flag
+      sendFlag = true;
+
+      // As per spec, this is called here for historical reasons.
+      self.dispatchEvent("readystatechange");
+
+      // Handler for the response
+      var responseHandler = function responseHandler(resp) {
+        // Set response var to the response we got back
+        // This is so it remains accessable outside this scope
+        response = resp;
+        // Check for redirect
+        // @TODO Prevent looped redirects
+        if (response.statusCode === 301 || response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) {
+          // Change URL to the redirect location
+          settings.url = response.headers.location;
+          var url = Url.parse(settings.url);
+          // Set host var in case it's used later
+          host = url.hostname;
+          // Options for the new request
+          var newOptions = {
+            hostname: url.hostname,
+            port: url.port,
+            path: url.path,
+            method: response.statusCode === 303 ? "GET" : settings.method,
+            headers: headers,
+            withCredentials: self.withCredentials
+          };
+
+          // Issue the new request
+          request = doRequest(newOptions, responseHandler).on("error", errorHandler);
+          request.end();
+          // @TODO Check if an XHR event needs to be fired here
+          return;
+        }
+
+        response.setEncoding("utf8");
+
+        setState(self.HEADERS_RECEIVED);
+        self.status = response.statusCode;
+
+        response.on("data", function(chunk) {
+          // Make sure there's some data
+          if (chunk) {
+            self.responseText += chunk;
+          }
+          // Don't emit state changes if the connection has been aborted.
+          if (sendFlag) {
+            setState(self.LOADING);
+          }
+        });
+
+        response.on("end", function() {
+          if (sendFlag) {
+            // Discard the end event if the connection has been aborted
+            setState(self.DONE);
+            sendFlag = false;
+          }
+        });
+
+        response.on("error", function(error) {
+          self.handleError(error);
+        });
+      };
+
+      // Error handler for the request
+      var errorHandler = function errorHandler(error) {
+        self.handleError(error);
+      };
+
+      // Create the request
+      request = doRequest(options, responseHandler).on("error", errorHandler);
+
+      // Node 0.4 and later won't accept empty data. Make sure it's needed.
+      if (data) {
+        request.write(data);
+      }
+
+      request.end();
+
+      self.dispatchEvent("loadstart");
+    } else { // Synchronous
+      // Create a temporary file for communication with the other Node process
+      var contentFile = ".node-xmlhttprequest-content-" + process.pid;
+      var syncFile = ".node-xmlhttprequest-sync-" + process.pid;
+      fs.writeFileSync(syncFile, "", "utf8");
+      // The async request the other Node process executes
+      var execString = "var http = require('http'), https = require('https'), fs = require('fs');"
+        + "var doRequest = http" + (ssl ? "s" : "") + ".request;"
+        + "var options = " + JSON.stringify(options) + ";"
+        + "var responseText = '';"
+        + "var req = doRequest(options, function(response) {"
+        + "response.setEncoding('utf8');"
+        + "response.on('data', function(chunk) {"
+        + "  responseText += chunk;"
+        + "});"
+        + "response.on('end', function() {"
+        + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: null, data: {statusCode: response.statusCode, headers: response.headers, text: responseText}}), 'utf8');"
+        + "fs.unlinkSync('" + syncFile + "');"
+        + "});"
+        + "response.on('error', function(error) {"
+        + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');"
+        + "fs.unlinkSync('" + syncFile + "');"
+        + "});"
+        + "}).on('error', function(error) {"
+        + "fs.writeFileSync('" + contentFile + "', JSON.stringify({err: error}), 'utf8');"
+        + "fs.unlinkSync('" + syncFile + "');"
+        + "});"
+        + (data ? "req.write('" + JSON.stringify(data).slice(1,-1).replace(/'/g, "\\'") + "');":"")
+        + "req.end();";
+      // Start the other Node Process, executing this string
+      var syncProc = spawn(process.argv[0], ["-e", execString]);
+      while(fs.existsSync(syncFile)) {
+        // Wait while the sync file is empty
+      }
+      var resp = JSON.parse(fs.readFileSync(contentFile, 'utf8'));
+      // Kill the child process once the file has data
+      syncProc.stdin.end();
+      // Remove the temporary file
+      fs.unlinkSync(contentFile);
+
+      if (resp.err) {
+        self.handleError(resp.err);
+      } else {
+        response = resp.data;
+        self.status = resp.data.statusCode;
+        self.responseText = resp.data.text;
+        setState(self.DONE);
+      }
+    }
+  };
+
+  /**
+   * Called when an error is encountered to deal with it.
+   */
+  this.handleError = function(error) {
+    this.status = 0;
+    this.statusText = error;
+    this.responseText = error.stack;
+    errorFlag = true;
+    setState(this.DONE);
+    this.dispatchEvent('error');
+  };
+
+  /**
+   * Aborts a request.
+   */
+  this.abort = function() {
+    if (request) {
+      request.abort();
+      request = null;
+    }
+
+    headers = defaultHeaders;
+    this.status = 0;
+    this.responseText = "";
+    this.responseXML = "";
+
+    errorFlag = true;
+
+    if (this.readyState !== this.UNSENT
+        && (this.readyState !== this.OPENED || sendFlag)
+        && this.readyState !== this.DONE) {
+      sendFlag = false;
+      setState(this.DONE);
+    }
+    this.readyState = this.UNSENT;
+    this.dispatchEvent('abort');
+  };
+
+  /**
+   * Adds an event listener. Preferred method of binding to events.
+   */
+  this.addEventListener = function(event, callback) {
+    if (!(event in listeners)) {
+      listeners[event] = [];
+    }
+    // Currently allows duplicate callbacks. Should it?
+    listeners[event].push(callback);
+  };
+
+  /**
+   * Remove an event callback that has already been bound.
+   * Only works on the matching funciton, cannot be a copy.
+   */
+  this.removeEventListener = function(event, callback) {
+    if (event in listeners) {
+      // Filter will return a new array with the callback removed
+      listeners[event] = listeners[event].filter(function(ev) {
+        return ev !== callback;
+      });
+    }
+  };
+
+  /**
+   * Dispatch any events, including both "on" methods and events attached using addEventListener.
+   */
+  this.dispatchEvent = function(event) {
+    if (typeof self["on" + event] === "function") {
+      self["on" + event]();
+    }
+    if (event in listeners) {
+      for (var i = 0, len = listeners[event].length; i < len; i++) {
+        listeners[event][i].call(self);
+      }
+    }
+  };
+
+  /**
+   * Changes readyState and calls onreadystatechange.
+   *
+   * @param int state New state
+   */
+  var setState = function(state) {
+    if (state == self.LOADING || self.readyState !== state) {
+      self.readyState = state;
+
+      if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) {
+        self.dispatchEvent("readystatechange");
+      }
+
+      if (self.readyState === self.DONE && !errorFlag) {
+        self.dispatchEvent("load");
+        // @TODO figure out InspectorInstrumentation::didLoadXHR(cookie)
+        self.dispatchEvent("loadend");
+      }
+    }
+  };
+};
diff --git a/d2d_app/node_modules/xmlhttprequest/package.json b/d2d_app/node_modules/xmlhttprequest/package.json
new file mode 100644 (file)
index 0000000..1fb8e8c
--- /dev/null
@@ -0,0 +1,56 @@
+{
+  "_from": "xmlhttprequest",
+  "_id": "xmlhttprequest@1.8.0",
+  "_inBundle": false,
+  "_integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=",
+  "_location": "/xmlhttprequest",
+  "_phantomChildren": {},
+  "_requested": {
+    "type": "tag",
+    "registry": true,
+    "raw": "xmlhttprequest",
+    "name": "xmlhttprequest",
+    "escapedName": "xmlhttprequest",
+    "rawSpec": "",
+    "saveSpec": null,
+    "fetchSpec": "latest"
+  },
+  "_requiredBy": [
+    "#USER",
+    "/"
+  ],
+  "_resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+  "_shasum": "67fe075c5c24fef39f9d65f5f7b7fe75171968fc",
+  "_spec": "xmlhttprequest",
+  "_where": "/home/kenshin.choi/workspace/MDE-Framework/DeviceWebServer/GlobalServiceApp_Tau_VDHomeScreen",
+  "author": {
+    "name": "Dan DeFelippi",
+    "url": "http://driverdan.com"
+  },
+  "bugs": {
+    "url": "http://github.com/driverdan/node-XMLHttpRequest/issues"
+  },
+  "bundleDependencies": false,
+  "deprecated": false,
+  "description": "XMLHttpRequest for Node",
+  "directories": {
+    "lib": "./lib",
+    "example": "./example"
+  },
+  "engines": {
+    "node": ">=0.4.0"
+  },
+  "homepage": "https://github.com/driverdan/node-XMLHttpRequest#readme",
+  "keywords": [
+    "xhr",
+    "ajax"
+  ],
+  "license": "MIT",
+  "main": "./lib/XMLHttpRequest.js",
+  "name": "xmlhttprequest",
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/driverdan/node-XMLHttpRequest.git"
+  },
+  "version": "1.8.0"
+}
diff --git a/d2d_app/package-lock.json b/d2d_app/package-lock.json
new file mode 100644 (file)
index 0000000..15fefd0
--- /dev/null
@@ -0,0 +1,696 @@
+{
+  "requires": true,
+  "lockfileVersion": 1,
+  "dependencies": {
+    "ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "requires": {
+        "color-convert": "^1.9.0"
+      }
+    },
+    "async": {
+      "version": "0.9.2",
+      "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+      "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "requires": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+    },
+    "cookie": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+      "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "depd": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+    },
+    "ejs": {
+      "version": "3.1.6",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz",
+      "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==",
+      "requires": {
+        "jake": "^10.6.1"
+      }
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+    },
+    "express": {
+      "version": "4.17.1",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+      "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+      "requires": {
+        "accepts": "~1.3.7",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.19.0",
+        "content-disposition": "0.5.3",
+        "content-type": "~1.0.4",
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "~1.1.2",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.3",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.5",
+        "qs": "6.7.0",
+        "range-parser": "~1.2.1",
+        "safe-buffer": "5.1.2",
+        "send": "0.17.1",
+        "serve-static": "1.14.1",
+        "setprototypeof": "1.1.1",
+        "statuses": "~1.5.0",
+        "type-is": "~1.6.18",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "accepts": {
+          "version": "1.3.7",
+          "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+          "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+          "requires": {
+            "mime-types": "~2.1.24",
+            "negotiator": "0.6.2"
+          }
+        },
+        "array-flatten": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+          "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+        },
+        "asap": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+          "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+        },
+        "body-parser": {
+          "version": "1.19.0",
+          "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+          "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+          "requires": {
+            "bytes": "3.1.0",
+            "content-type": "~1.0.4",
+            "debug": "2.6.9",
+            "depd": "~1.1.2",
+            "http-errors": "1.7.2",
+            "iconv-lite": "0.4.24",
+            "on-finished": "~2.3.0",
+            "qs": "6.7.0",
+            "raw-body": "2.4.0",
+            "type-is": "~1.6.17"
+          },
+          "dependencies": {
+            "debug": {
+              "version": "2.6.9",
+              "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+              "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+              "requires": {
+                "ms": "2.0.0"
+              }
+            }
+          }
+        },
+        "bytes": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+          "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
+        },
+        "content-disposition": {
+          "version": "0.5.3",
+          "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+          "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+          "requires": {
+            "safe-buffer": "5.1.2"
+          }
+        },
+        "content-type": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+          "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+        },
+        "cookie": {
+          "version": "0.4.0",
+          "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+          "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
+        },
+        "cookie-signature": {
+          "version": "1.0.6",
+          "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+          "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+        },
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "deep-is": {
+          "version": "0.1.3",
+          "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+          "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
+        },
+        "depd": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+          "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+        },
+        "destroy": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+          "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+        },
+        "ee-first": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+          "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+        },
+        "encodeurl": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+          "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+        },
+        "escape-html": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+          "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+        },
+        "etag": {
+          "version": "1.8.1",
+          "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+          "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+        },
+        "fast-levenshtein": {
+          "version": "1.0.7",
+          "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz",
+          "integrity": "sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk="
+        },
+        "finalhandler": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+          "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+          "requires": {
+            "debug": "2.6.9",
+            "encodeurl": "~1.0.2",
+            "escape-html": "~1.0.3",
+            "on-finished": "~2.3.0",
+            "parseurl": "~1.3.3",
+            "statuses": "~1.5.0",
+            "unpipe": "~1.0.0"
+          },
+          "dependencies": {
+            "debug": {
+              "version": "2.6.9",
+              "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+              "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+              "requires": {
+                "ms": "2.0.0"
+              }
+            }
+          }
+        },
+        "forwarded": {
+          "version": "0.1.2",
+          "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+          "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+        },
+        "fresh": {
+          "version": "0.5.2",
+          "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+          "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+        },
+        "http-errors": {
+          "version": "1.7.2",
+          "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+          "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+          "requires": {
+            "depd": "~1.1.2",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.1.1",
+            "statuses": ">= 1.5.0 < 2",
+            "toidentifier": "1.0.0"
+          }
+        },
+        "iconv-lite": {
+          "version": "0.4.24",
+          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+          "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+          "requires": {
+            "safer-buffer": ">= 2.1.2 < 3"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+        },
+        "ipaddr.js": {
+          "version": "1.9.0",
+          "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
+          "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
+        },
+        "levn": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz",
+          "integrity": "sha1-uo0znQykphDjo/FFucr0iAcVUFQ=",
+          "requires": {
+            "prelude-ls": "~1.1.0",
+            "type-check": "~0.3.1"
+          }
+        },
+        "media-typer": {
+          "version": "0.3.0",
+          "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+          "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+        },
+        "merge-descriptors": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+          "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+        },
+        "methods": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+          "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+        },
+        "mime": {
+          "version": "1.2.11",
+          "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
+          "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA="
+        },
+        "mime-db": {
+          "version": "1.43.0",
+          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
+          "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
+        },
+        "mime-types": {
+          "version": "2.1.26",
+          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
+          "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
+          "requires": {
+            "mime-db": "1.43.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        },
+        "negotiator": {
+          "version": "0.6.2",
+          "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+          "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
+        },
+        "on-finished": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+          "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+          "requires": {
+            "ee-first": "1.1.1"
+          }
+        },
+        "optionator": {
+          "version": "0.4.0",
+          "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.4.0.tgz",
+          "integrity": "sha1-55x5Jv99VQ+SxxTfw9oh14d+vqY=",
+          "requires": {
+            "deep-is": "~0.1.2",
+            "fast-levenshtein": "~1.0.0",
+            "levn": "~0.2.5",
+            "prelude-ls": "~1.1.0",
+            "type-check": "~0.3.1",
+            "wordwrap": "~0.0.2"
+          }
+        },
+        "parseurl": {
+          "version": "1.3.3",
+          "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+          "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+        },
+        "path-to-regexp": {
+          "version": "0.1.7",
+          "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+          "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+        },
+        "prelude-ls": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+          "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
+        },
+        "promise": {
+          "version": "7.3.1",
+          "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+          "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+          "requires": {
+            "asap": "~2.0.3"
+          }
+        },
+        "proxy-addr": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
+          "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
+          "requires": {
+            "forwarded": "~0.1.2",
+            "ipaddr.js": "1.9.0"
+          }
+        },
+        "qs": {
+          "version": "6.7.0",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+          "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
+        },
+        "range-parser": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+          "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
+        },
+        "raw-body": {
+          "version": "2.4.0",
+          "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+          "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+          "requires": {
+            "bytes": "3.1.0",
+            "http-errors": "1.7.2",
+            "iconv-lite": "0.4.24",
+            "unpipe": "1.0.0"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        },
+        "safer-buffer": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+          "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+        },
+        "send": {
+          "version": "0.17.1",
+          "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+          "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+          "requires": {
+            "debug": "2.6.9",
+            "depd": "~1.1.2",
+            "destroy": "~1.0.4",
+            "encodeurl": "~1.0.2",
+            "escape-html": "~1.0.3",
+            "etag": "~1.8.1",
+            "fresh": "0.5.2",
+            "http-errors": "~1.7.2",
+            "mime": "1.6.0",
+            "ms": "2.1.1",
+            "on-finished": "~2.3.0",
+            "range-parser": "~1.2.1",
+            "statuses": "~1.5.0"
+          },
+          "dependencies": {
+            "debug": {
+              "version": "2.6.9",
+              "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+              "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+              "requires": {
+                "ms": "2.0.0"
+              },
+              "dependencies": {
+                "ms": {
+                  "version": "2.0.0",
+                  "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+                  "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+                }
+              }
+            },
+            "mime": {
+              "version": "1.6.0",
+              "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+              "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+            },
+            "ms": {
+              "version": "2.1.1",
+              "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+              "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+            }
+          }
+        },
+        "serve-static": {
+          "version": "1.14.1",
+          "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+          "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+          "requires": {
+            "encodeurl": "~1.0.2",
+            "escape-html": "~1.0.3",
+            "parseurl": "~1.3.3",
+            "send": "0.17.1"
+          }
+        },
+        "setprototypeof": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+          "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+        },
+        "statuses": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+          "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+        },
+        "toidentifier": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+          "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
+        },
+        "type-check": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+          "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+          "requires": {
+            "prelude-ls": "~1.1.2"
+          }
+        },
+        "type-is": {
+          "version": "1.6.18",
+          "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+          "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+          "requires": {
+            "media-typer": "0.3.0",
+            "mime-types": "~2.1.24"
+          }
+        },
+        "unpipe": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+          "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+        },
+        "url": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+          "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+          "requires": {
+            "punycode": "1.3.2"
+          },
+          "dependencies": {
+            "punycode": {
+              "version": "1.3.2",
+              "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+              "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
+            }
+          }
+        },
+        "utils-merge": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+          "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+        },
+        "vary": {
+          "version": "1.1.2",
+          "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+          "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+        },
+        "wordwrap": {
+          "version": "0.0.3",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
+        }
+      }
+    },
+    "express-session": {
+      "version": "1.17.1",
+      "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.1.tgz",
+      "integrity": "sha512-UbHwgqjxQZJiWRTMyhvWGvjBQduGCSBDhhZXYenziMFjxst5rMV+aJZ6hKPHZnPyHGsrqRICxtX8jtEbm/z36Q==",
+      "requires": {
+        "cookie": "0.4.0",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~2.0.0",
+        "on-headers": "~1.0.2",
+        "parseurl": "~1.3.3",
+        "safe-buffer": "5.2.0",
+        "uid-safe": "~2.1.5"
+      }
+    },
+    "filelist": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz",
+      "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==",
+      "requires": {
+        "minimatch": "^3.0.4"
+      }
+    },
+    "get-port": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz",
+      "integrity": "sha1-BGntB1Y0ed5u+5hrrwU9zX1OMZM="
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+    },
+    "jake": {
+      "version": "10.8.2",
+      "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
+      "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
+      "requires": {
+        "async": "0.9.x",
+        "chalk": "^2.4.2",
+        "filelist": "^1.0.1",
+        "minimatch": "^3.0.4"
+      }
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+    },
+    "on-headers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+      "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
+    },
+    "parseurl": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+      "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+    },
+    "random-bytes": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
+      "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs="
+    },
+    "safe-buffer": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+      "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
+    },
+    "supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "requires": {
+        "has-flag": "^3.0.0"
+      }
+    },
+    "uid-safe": {
+      "version": "2.1.5",
+      "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
+      "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
+      "requires": {
+        "random-bytes": "~1.0.0"
+      }
+    },
+    "ws": {
+      "version": "5.2.2",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+      "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+      "requires": {
+        "async-limiter": "~1.0.0"
+      },
+      "dependencies": {
+        "async-limiter": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+          "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
+        }
+      }
+    },
+    "xmlhttprequest": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz",
+      "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw="
+    }
+  }
+}
old mode 100644 (file)
new mode 100755 (executable)
index 3db4507..329487b
@@ -4,23 +4,48 @@ var appRouters = [];
 var path = null;
 var currentD2DAppId = null;
 
-module.exports = function(app, port) {
-    var appProxy = express.Router();
+function runApp(appId, port, callback) {
+    function onRunningAppsContext(contexts) {
+        var isRunning = false;
+        for (var i = 0; i < contexts.length; i++) {
+            if (appId === contexts[i].appId) {
+                isRunning = true;
+                break;
+            }
+        }
+
+        if (isRunning && currentD2DAppId === appId) {
+            callback();
+        } else {
+            var appControl = new tizen.ApplicationControl(
+                "http://tizen.org/appcontrol/operation/default", null, null, null,
+                [new tizen.ApplicationControlData(
+                    "http://tizen.org/appcontrol/data/launch_port", [port]
+                )]
+            );
 
+            currentD2DAppId = appId;
+            tizen.application.launchAppControl(appControl, appId, callback);
+        }
+    }
+    tizen.application.getAppsContext(onRunningAppsContext);
+}
+
+module.exports = function(app, port, d2dService) {
+    var appProxy = express.Router();
+    
     appProxy.use('/app', express.json());
     appProxy.post('/', (req, res) => {
+        var action = req.body.action;
         path = req.body.appPkgID ? req.body.appPkgID : path;
         var appId = req.body.appAppID;
+        var pkgId = req.body.appPkgID;
         var name = appId.split(".")[1];
-        var addNew = true;
+        var appRouter = appRouters.filter(function (router) {
+            return router.path === path;
+        })[0];
 
-        for (var i = 0; (i < appRouters.length) && (path !== null); i++) {
-            if (appRouters[i].path == path) {
-                addNew = false;
-                break;
-            }
-        }
-        if (addNew) {
+        if (!appRouter) {
             appRouters.push({
                 path: path,
                 name: name,
@@ -28,34 +53,17 @@ module.exports = function(app, port) {
             });
         }
 
-        function onRunningAppsContext(contexts) {
-            var isRunning = false;
-            for (var i = 0; i < contexts.length; i++) {
-                if (appId === contexts[i].appId) {
-                    isRunning = true;
-                    break;
-                }
-            }
+        console.log('[GlobalWebServer] appProxy.post ', path, action);
 
-            if (isRunning && currentD2DAppId === appId) {
-                res.send({port:port});
-            } else {
-                var appControl = new tizen.ApplicationControl(
-                    "http://tizen.org/appcontrol/operation/default", null, null, null,
-                    [new tizen.ApplicationControlData(
-                        "http://tizen.org/appcontrol/data/launch_port", [port]
-                    )]
-                );
-
-                tizen.application.launchAppControl(appControl, appId, function() {
-                    res.send({port:port});
-                });
-
-                currentD2DAppId = appId;
+        // run app
+        runApp(appId, port, function() {
+            if (action) {
+                // send action to client
+                console.log('[GlobalWebServer] d2dService', d2dService);
+                d2dService.sendMessage(action, JSON.stringify(req.body));
             }
-        }
-
-        tizen.application.getAppsContext(onRunningAppsContext);
+            res.send({port:port});
+        });
     });
 
     appProxy.get('/', (req, res) => {
old mode 100644 (file)
new mode 100755 (executable)
index 56a5c51..4af816b
@@ -3,10 +3,25 @@ var express = require('express');
 class AppRouter {
     constructor(app, path) {
         var appRouter = express.Router();
-        appRouter.use(express.static('/opt/usr/globalapps/' + path + '/res/wgt/client'));
+        appRouter.use(express.static(__dirname + '/../../../../' + path + '/shared/res/client'));
 
         appRouter.get('/', (req, res) => {
-            res.redirect('client.html');
+            console.log("[GlobalWebServer] appRouter.get(/) ", req.baseUrl);
+            var roomData = require('./service').getUrlParam();
+            console.log("[GlobalWebServer] appRouter.get(/) roomData : ", roomData);
+
+            // [WT] Chatting App
+            if (path === 'NAe4rftRic') {
+                if (roomData.indexOf('roomId') != -1) {
+                    res.redirect('chat.html');
+                }
+                else {
+                    res.redirect('client.html');
+                }
+            }
+            else {
+                res.redirect('client.html');
+            }
         });
         return appRouter;
     }
diff --git a/d2d_app/service/jsencrypt.js b/d2d_app/service/jsencrypt.js
new file mode 100644 (file)
index 0000000..de5a14f
--- /dev/null
@@ -0,0 +1,5371 @@
+(function (global, factory) {
+       typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+       typeof define === 'function' && define.amd ? define(['exports'], factory) :
+       (factory((global.JSEncrypt = {})));
+}(this, (function (exports) { 'use strict';
+
+var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+function int2char(n) {
+    return BI_RM.charAt(n);
+}
+//#region BIT_OPERATIONS
+// (public) this & a
+function op_and(x, y) {
+    return x & y;
+}
+// (public) this | a
+function op_or(x, y) {
+    return x | y;
+}
+// (public) this ^ a
+function op_xor(x, y) {
+    return x ^ y;
+}
+// (public) this & ~a
+function op_andnot(x, y) {
+    return x & ~y;
+}
+// return index of lowest 1-bit in x, x < 2^31
+function lbit(x) {
+    if (x == 0) {
+        return -1;
+    }
+    var r = 0;
+    if ((x & 0xffff) == 0) {
+        x >>= 16;
+        r += 16;
+    }
+    if ((x & 0xff) == 0) {
+        x >>= 8;
+        r += 8;
+    }
+    if ((x & 0xf) == 0) {
+        x >>= 4;
+        r += 4;
+    }
+    if ((x & 3) == 0) {
+        x >>= 2;
+        r += 2;
+    }
+    if ((x & 1) == 0) {
+        ++r;
+    }
+    return r;
+}
+// return number of 1 bits in x
+function cbit(x) {
+    var r = 0;
+    while (x != 0) {
+        x &= x - 1;
+        ++r;
+    }
+    return r;
+}
+//#endregion BIT_OPERATIONS
+
+var b64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var b64pad = "=";
+function hex2b64(h) {
+    var i;
+    var c;
+    var ret = "";
+    for (i = 0; i + 3 <= h.length; i += 3) {
+        c = parseInt(h.substring(i, i + 3), 16);
+        ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
+    }
+    if (i + 1 == h.length) {
+        c = parseInt(h.substring(i, i + 1), 16);
+        ret += b64map.charAt(c << 2);
+    }
+    else if (i + 2 == h.length) {
+        c = parseInt(h.substring(i, i + 2), 16);
+        ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
+    }
+    while ((ret.length & 3) > 0) {
+        ret += b64pad;
+    }
+    return ret;
+}
+// convert a base64 string to hex
+function b64tohex(s) {
+    var ret = "";
+    var i;
+    var k = 0; // b64 state, 0-3
+    var slop = 0;
+    for (i = 0; i < s.length; ++i) {
+        if (s.charAt(i) == b64pad) {
+            break;
+        }
+        var v = b64map.indexOf(s.charAt(i));
+        if (v < 0) {
+            continue;
+        }
+        if (k == 0) {
+            ret += int2char(v >> 2);
+            slop = v & 3;
+            k = 1;
+        }
+        else if (k == 1) {
+            ret += int2char((slop << 2) | (v >> 4));
+            slop = v & 0xf;
+            k = 2;
+        }
+        else if (k == 2) {
+            ret += int2char(slop);
+            ret += int2char(v >> 2);
+            slop = v & 3;
+            k = 3;
+        }
+        else {
+            ret += int2char((slop << 2) | (v >> 4));
+            ret += int2char(v & 0xf);
+            k = 0;
+        }
+    }
+    if (k == 1) {
+        ret += int2char(slop << 2);
+    }
+    return ret;
+}
+
+/*! *****************************************************************************
+Copyright (c) Microsoft Corporation. All rights reserved.
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at http://www.apache.org/licenses/LICENSE-2.0
+THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
+WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
+MERCHANTABLITY OR NON-INFRINGEMENT.
+See the Apache Version 2.0 License for specific language governing permissions
+and limitations under the License.
+***************************************************************************** */
+/* global Reflect, Promise */
+
+var extendStatics = function(d, b) {
+    extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return extendStatics(d, b);
+};
+
+function __extends(d, b) {
+    extendStatics(d, b);
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+}
+
+// Hex JavaScript decoder
+// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
+var decoder;
+var Hex = {
+    decode: function (a) {
+        var i;
+        if (decoder === undefined) {
+            var hex = "0123456789ABCDEF";
+            var ignore = " \f\n\r\t\u00A0\u2028\u2029";
+            decoder = {};
+            for (i = 0; i < 16; ++i) {
+                decoder[hex.charAt(i)] = i;
+            }
+            hex = hex.toLowerCase();
+            for (i = 10; i < 16; ++i) {
+                decoder[hex.charAt(i)] = i;
+            }
+            for (i = 0; i < ignore.length; ++i) {
+                decoder[ignore.charAt(i)] = -1;
+            }
+        }
+        var out = [];
+        var bits = 0;
+        var char_count = 0;
+        for (i = 0; i < a.length; ++i) {
+            var c = a.charAt(i);
+            if (c == "=") {
+                break;
+            }
+            c = decoder[c];
+            if (c == -1) {
+                continue;
+            }
+            if (c === undefined) {
+                throw new Error("Illegal character at offset " + i);
+            }
+            bits |= c;
+            if (++char_count >= 2) {
+                out[out.length] = bits;
+                bits = 0;
+                char_count = 0;
+            }
+            else {
+                bits <<= 4;
+            }
+        }
+        if (char_count) {
+            throw new Error("Hex encoding incomplete: 4 bits missing");
+        }
+        return out;
+    }
+};
+
+// Base64 JavaScript decoder
+// Copyright (c) 2008-2013 Lapo Luchini <lapo@lapo.it>
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
+var decoder$1;
+var Base64 = {
+    decode: function (a) {
+        var i;
+        if (decoder$1 === undefined) {
+            var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+            var ignore = "= \f\n\r\t\u00A0\u2028\u2029";
+            decoder$1 = Object.create(null);
+            for (i = 0; i < 64; ++i) {
+                decoder$1[b64.charAt(i)] = i;
+            }
+            for (i = 0; i < ignore.length; ++i) {
+                decoder$1[ignore.charAt(i)] = -1;
+            }
+        }
+        var out = [];
+        var bits = 0;
+        var char_count = 0;
+        for (i = 0; i < a.length; ++i) {
+            var c = a.charAt(i);
+            if (c == "=") {
+                break;
+            }
+            c = decoder$1[c];
+            if (c == -1) {
+                continue;
+            }
+            if (c === undefined) {
+                throw new Error("Illegal character at offset " + i);
+            }
+            bits |= c;
+            if (++char_count >= 4) {
+                out[out.length] = (bits >> 16);
+                out[out.length] = (bits >> 8) & 0xFF;
+                out[out.length] = bits & 0xFF;
+                bits = 0;
+                char_count = 0;
+            }
+            else {
+                bits <<= 6;
+            }
+        }
+        switch (char_count) {
+            case 1:
+                throw new Error("Base64 encoding incomplete: at least 2 bits missing");
+            case 2:
+                out[out.length] = (bits >> 10);
+                break;
+            case 3:
+                out[out.length] = (bits >> 16);
+                out[out.length] = (bits >> 8) & 0xFF;
+                break;
+        }
+        return out;
+    },
+    re: /-----BEGIN [^-]+-----([A-Za-z0-9+\/=\s]+)-----END [^-]+-----|begin-base64[^\n]+\n([A-Za-z0-9+\/=\s]+)====/,
+    unarmor: function (a) {
+        var m = Base64.re.exec(a);
+        if (m) {
+            if (m[1]) {
+                a = m[1];
+            }
+            else if (m[2]) {
+                a = m[2];
+            }
+            else {
+                throw new Error("RegExp out of sync");
+            }
+        }
+        return Base64.decode(a);
+    }
+};
+
+// Big integer base-10 printing library
+// Copyright (c) 2014 Lapo Luchini <lapo@lapo.it>
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+/*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */
+var max = 10000000000000; // biggest integer that can still fit 2^53 when multiplied by 256
+var Int10 = /** @class */ (function () {
+    function Int10(value) {
+        this.buf = [+value || 0];
+    }
+    Int10.prototype.mulAdd = function (m, c) {
+        // assert(m <= 256)
+        var b = this.buf;
+        var l = b.length;
+        var i;
+        var t;
+        for (i = 0; i < l; ++i) {
+            t = b[i] * m + c;
+            if (t < max) {
+                c = 0;
+            }
+            else {
+                c = 0 | (t / max);
+                t -= c * max;
+            }
+            b[i] = t;
+        }
+        if (c > 0) {
+            b[i] = c;
+        }
+    };
+    Int10.prototype.sub = function (c) {
+        // assert(m <= 256)
+        var b = this.buf;
+        var l = b.length;
+        var i;
+        var t;
+        for (i = 0; i < l; ++i) {
+            t = b[i] - c;
+            if (t < 0) {
+                t += max;
+                c = 1;
+            }
+            else {
+                c = 0;
+            }
+            b[i] = t;
+        }
+        while (b[b.length - 1] === 0) {
+            b.pop();
+        }
+    };
+    Int10.prototype.toString = function (base) {
+        if ((base || 10) != 10) {
+            throw new Error("only base 10 is supported");
+        }
+        var b = this.buf;
+        var s = b[b.length - 1].toString();
+        for (var i = b.length - 2; i >= 0; --i) {
+            s += (max + b[i]).toString().substring(1);
+        }
+        return s;
+    };
+    Int10.prototype.valueOf = function () {
+        var b = this.buf;
+        var v = 0;
+        for (var i = b.length - 1; i >= 0; --i) {
+            v = v * max + b[i];
+        }
+        return v;
+    };
+    Int10.prototype.simplify = function () {
+        var b = this.buf;
+        return (b.length == 1) ? b[0] : this;
+    };
+    return Int10;
+}());
+
+// ASN.1 JavaScript decoder
+var ellipsis = "\u2026";
+var reTimeS = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
+var reTimeL = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/;
+function stringCut(str, len) {
+    if (str.length > len) {
+        str = str.substring(0, len) + ellipsis;
+    }
+    return str;
+}
+var Stream = /** @class */ (function () {
+    function Stream(enc, pos) {
+        this.hexDigits = "0123456789ABCDEF";
+        if (enc instanceof Stream) {
+            this.enc = enc.enc;
+            this.pos = enc.pos;
+        }
+        else {
+            // enc should be an array or a binary string
+            this.enc = enc;
+            this.pos = pos;
+        }
+    }
+    Stream.prototype.get = function (pos) {
+        if (pos === undefined) {
+            pos = this.pos++;
+        }
+        if (pos >= this.enc.length) {
+            throw new Error("Requesting byte offset " + pos + " on a stream of length " + this.enc.length);
+        }
+        return ("string" === typeof this.enc) ? this.enc.charCodeAt(pos) : this.enc[pos];
+    };
+    Stream.prototype.hexByte = function (b) {
+        return this.hexDigits.charAt((b >> 4) & 0xF) + this.hexDigits.charAt(b & 0xF);
+    };
+    Stream.prototype.hexDump = function (start, end, raw) {
+        var s = "";
+        for (var i = start; i < end; ++i) {
+            s += this.hexByte(this.get(i));
+            if (raw !== true) {
+                switch (i & 0xF) {
+                    case 0x7:
+                        s += "  ";
+                        break;
+                    case 0xF:
+                        s += "\n";
+                        break;
+                    default:
+                        s += " ";
+                }
+            }
+        }
+        return s;
+    };
+    Stream.prototype.isASCII = function (start, end) {
+        for (var i = start; i < end; ++i) {
+            var c = this.get(i);
+            if (c < 32 || c > 176) {
+                return false;
+            }
+        }
+        return true;
+    };
+    Stream.prototype.parseStringISO = function (start, end) {
+        var s = "";
+        for (var i = start; i < end; ++i) {
+            s += String.fromCharCode(this.get(i));
+        }
+        return s;
+    };
+    Stream.prototype.parseStringUTF = function (start, end) {
+        var s = "";
+        for (var i = start; i < end;) {
+            var c = this.get(i++);
+            if (c < 128) {
+                s += String.fromCharCode(c);
+            }
+            else if ((c > 191) && (c < 224)) {
+                s += String.fromCharCode(((c & 0x1F) << 6) | (this.get(i++) & 0x3F));
+            }
+            else {
+                s += String.fromCharCode(((c & 0x0F) << 12) | ((this.get(i++) & 0x3F) << 6) | (this.get(i++) & 0x3F));
+            }
+        }
+        return s;
+    };
+    Stream.prototype.parseStringBMP = function (start, end) {
+        var str = "";
+        var hi;
+        var lo;
+        for (var i = start; i < end;) {
+            hi = this.get(i++);
+            lo = this.get(i++);
+            str += String.fromCharCode((hi << 8) | lo);
+        }
+        return str;
+    };
+    Stream.prototype.parseTime = function (start, end, shortYear) {
+        var s = this.parseStringISO(start, end);
+        var m = (shortYear ? reTimeS : reTimeL).exec(s);
+        if (!m) {
+            return "Unrecognized time: " + s;
+        }
+        if (shortYear) {
+            // to avoid querying the timer, use the fixed range [1970, 2069]
+            // it will conform with ITU X.400 [-10, +40] sliding window until 2030
+            m[1] = +m[1];
+            m[1] += (+m[1] < 70) ? 2000 : 1900;
+        }
+        s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4];
+        if (m[5]) {
+            s += ":" + m[5];
+            if (m[6]) {
+                s += ":" + m[6];
+                if (m[7]) {
+                    s += "." + m[7];
+                }
+            }
+        }
+        if (m[8]) {
+            s += " UTC";
+            if (m[8] != "Z") {
+                s += m[8];
+                if (m[9]) {
+                    s += ":" + m[9];
+                }
+            }
+        }
+        return s;
+    };
+    Stream.prototype.parseInteger = function (start, end) {
+        var v = this.get(start);
+        var neg = (v > 127);
+        var pad = neg ? 255 : 0;
+        var len;
+        var s = "";
+        // skip unuseful bits (not allowed in DER)
+        while (v == pad && ++start < end) {
+            v = this.get(start);
+        }
+        len = end - start;
+        if (len === 0) {
+            return neg ? -1 : 0;
+        }
+        // show bit length of huge integers
+        if (len > 4) {
+            s = v;
+            len <<= 3;
+            while (((+s ^ pad) & 0x80) == 0) {
+                s = +s << 1;
+                --len;
+            }
+            s = "(" + len + " bit)\n";
+        }
+        // decode the integer
+        if (neg) {
+            v = v - 256;
+        }
+        var n = new Int10(v);
+        for (var i = start + 1; i < end; ++i) {
+            n.mulAdd(256, this.get(i));
+        }
+        return s + n.toString();
+    };
+    Stream.prototype.parseBitString = function (start, end, maxLength) {
+        var unusedBit = this.get(start);
+        var lenBit = ((end - start - 1) << 3) - unusedBit;
+        var intro = "(" + lenBit + " bit)\n";
+        var s = "";
+        for (var i = start + 1; i < end; ++i) {
+            var b = this.get(i);
+            var skip = (i == end - 1) ? unusedBit : 0;
+            for (var j = 7; j >= skip; --j) {
+                s += (b >> j) & 1 ? "1" : "0";
+            }
+            if (s.length > maxLength) {
+                return intro + stringCut(s, maxLength);
+            }
+        }
+        return intro + s;
+    };
+    Stream.prototype.parseOctetString = function (start, end, maxLength) {
+        if (this.isASCII(start, end)) {
+            return stringCut(this.parseStringISO(start, end), maxLength);
+        }
+        var len = end - start;
+        var s = "(" + len + " byte)\n";
+        maxLength /= 2; // we work in bytes
+        if (len > maxLength) {
+            end = start + maxLength;
+        }
+        for (var i = start; i < end; ++i) {
+            s += this.hexByte(this.get(i));
+        }
+        if (len > maxLength) {
+            s += ellipsis;
+        }
+        return s;
+    };
+    Stream.prototype.parseOID = function (start, end, maxLength) {
+        var s = "";
+        var n = new Int10();
+        var bits = 0;
+        for (var i = start; i < end; ++i) {
+            var v = this.get(i);
+            n.mulAdd(128, v & 0x7F);
+            bits += 7;
+            if (!(v & 0x80)) { // finished
+                if (s === "") {
+                    n = n.simplify();
+                    if (n instanceof Int10) {
+                        n.sub(80);
+                        s = "2." + n.toString();
+                    }
+                    else {
+                        var m = n < 80 ? n < 40 ? 0 : 1 : 2;
+                        s = m + "." + (n - m * 40);
+                    }
+                }
+                else {
+                    s += "." + n.toString();
+                }
+                if (s.length > maxLength) {
+                    return stringCut(s, maxLength);
+                }
+                n = new Int10();
+                bits = 0;
+            }
+        }
+        if (bits > 0) {
+            s += ".incomplete";
+        }
+        return s;
+    };
+    return Stream;
+}());
+var ASN1 = /** @class */ (function () {
+    function ASN1(stream, header, length, tag, sub) {
+        if (!(tag instanceof ASN1Tag)) {
+            throw new Error("Invalid tag value.");
+        }
+        this.stream = stream;
+        this.header = header;
+        this.length = length;
+        this.tag = tag;
+        this.sub = sub;
+    }
+    ASN1.prototype.typeName = function () {
+        switch (this.tag.tagClass) {
+            case 0: // universal
+                switch (this.tag.tagNumber) {
+                    case 0x00:
+                        return "EOC";
+                    case 0x01:
+                        return "BOOLEAN";
+                    case 0x02:
+                        return "INTEGER";
+                    case 0x03:
+                        return "BIT_STRING";
+                    case 0x04:
+                        return "OCTET_STRING";
+                    case 0x05:
+                        return "NULL";
+                    case 0x06:
+                        return "OBJECT_IDENTIFIER";
+                    case 0x07:
+                        return "ObjectDescriptor";
+                    case 0x08:
+                        return "EXTERNAL";
+                    case 0x09:
+                        return "REAL";
+                    case 0x0A:
+                        return "ENUMERATED";
+                    case 0x0B:
+                        return "EMBEDDED_PDV";
+                    case 0x0C:
+                        return "UTF8String";
+                    case 0x10:
+                        return "SEQUENCE";
+                    case 0x11:
+                        return "SET";
+                    case 0x12:
+                        return "NumericString";
+                    case 0x13:
+                        return "PrintableString"; // ASCII subset
+                    case 0x14:
+                        return "TeletexString"; // aka T61String
+                    case 0x15:
+                        return "VideotexString";
+                    case 0x16:
+                        return "IA5String"; // ASCII
+                    case 0x17:
+                        return "UTCTime";
+                    case 0x18:
+                        return "GeneralizedTime";
+                    case 0x19:
+                        return "GraphicString";
+                    case 0x1A:
+                        return "VisibleString"; // ASCII subset
+                    case 0x1B:
+                        return "GeneralString";
+                    case 0x1C:
+                        return "UniversalString";
+                    case 0x1E:
+                        return "BMPString";
+                }
+                return "Universal_" + this.tag.tagNumber.toString();
+            case 1:
+                return "Application_" + this.tag.tagNumber.toString();
+            case 2:
+                return "[" + this.tag.tagNumber.toString() + "]"; // Context
+            case 3:
+                return "Private_" + this.tag.tagNumber.toString();
+        }
+    };
+    ASN1.prototype.content = function (maxLength) {
+        if (this.tag === undefined) {
+            return null;
+        }
+        if (maxLength === undefined) {
+            maxLength = Infinity;
+        }
+        var content = this.posContent();
+        var len = Math.abs(this.length);
+        if (!this.tag.isUniversal()) {
+            if (this.sub !== null) {
+                return "(" + this.sub.length + " elem)";
+            }
+            return this.stream.parseOctetString(content, content + len, maxLength);
+        }
+        switch (this.tag.tagNumber) {
+            case 0x01: // BOOLEAN
+                return (this.stream.get(content) === 0) ? "false" : "true";
+            case 0x02: // INTEGER
+                return this.stream.parseInteger(content, content + len);
+            case 0x03: // BIT_STRING
+                return this.sub ? "(" + this.sub.length + " elem)" :
+                    this.stream.parseBitString(content, content + len, maxLength);
+            case 0x04: // OCTET_STRING
+                return this.sub ? "(" + this.sub.length + " elem)" :
+                    this.stream.parseOctetString(content, content + len, maxLength);
+            // case 0x05: // NULL
+            case 0x06: // OBJECT_IDENTIFIER
+                return this.stream.parseOID(content, content + len, maxLength);
+            // case 0x07: // ObjectDescriptor
+            // case 0x08: // EXTERNAL
+            // case 0x09: // REAL
+            // case 0x0A: // ENUMERATED
+            // case 0x0B: // EMBEDDED_PDV
+            case 0x10: // SEQUENCE
+            case 0x11: // SET
+                if (this.sub !== null) {
+                    return "(" + this.sub.length + " elem)";
+                }
+                else {
+                    return "(no elem)";
+                }
+            case 0x0C: // UTF8String
+                return stringCut(this.stream.parseStringUTF(content, content + len), maxLength);
+            case 0x12: // NumericString
+            case 0x13: // PrintableString
+            case 0x14: // TeletexString
+            case 0x15: // VideotexString
+            case 0x16: // IA5String
+            // case 0x19: // GraphicString
+            case 0x1A: // VisibleString
+                // case 0x1B: // GeneralString
+                // case 0x1C: // UniversalString
+                return stringCut(this.stream.parseStringISO(content, content + len), maxLength);
+            case 0x1E: // BMPString
+                return stringCut(this.stream.parseStringBMP(content, content + len), maxLength);
+            case 0x17: // UTCTime
+            case 0x18: // GeneralizedTime
+                return this.stream.parseTime(content, content + len, (this.tag.tagNumber == 0x17));
+        }
+        return null;
+    };
+    ASN1.prototype.toString = function () {
+        return this.typeName() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? "null" : this.sub.length) + "]";
+    };
+    ASN1.prototype.toPrettyString = function (indent) {
+        if (indent === undefined) {
+            indent = "";
+        }
+        var s = indent + this.typeName() + " @" + this.stream.pos;
+        if (this.length >= 0) {
+            s += "+";
+        }
+        s += this.length;
+        if (this.tag.tagConstructed) {
+            s += " (constructed)";
+        }
+        else if ((this.tag.isUniversal() && ((this.tag.tagNumber == 0x03) || (this.tag.tagNumber == 0x04))) && (this.sub !== null)) {
+            s += " (encapsulates)";
+        }
+        s += "\n";
+        if (this.sub !== null) {
+            indent += "  ";
+            for (var i = 0, max = this.sub.length; i < max; ++i) {
+                s += this.sub[i].toPrettyString(indent);
+            }
+        }
+        return s;
+    };
+    ASN1.prototype.posStart = function () {
+        return this.stream.pos;
+    };
+    ASN1.prototype.posContent = function () {
+        return this.stream.pos + this.header;
+    };
+    ASN1.prototype.posEnd = function () {
+        return this.stream.pos + this.header + Math.abs(this.length);
+    };
+    ASN1.prototype.toHexString = function () {
+        return this.stream.hexDump(this.posStart(), this.posEnd(), true);
+    };
+    ASN1.decodeLength = function (stream) {
+        var buf = stream.get();
+        var len = buf & 0x7F;
+        if (len == buf) {
+            return len;
+        }
+        // no reason to use Int10, as it would be a huge buffer anyways
+        if (len > 6) {
+            throw new Error("Length over 48 bits not supported at position " + (stream.pos - 1));
+        }
+        if (len === 0) {
+            return null;
+        } // undefined
+        buf = 0;
+        for (var i = 0; i < len; ++i) {
+            buf = (buf * 256) + stream.get();
+        }
+        return buf;
+    };
+    /**
+     * Retrieve the hexadecimal value (as a string) of the current ASN.1 element
+     * @returns {string}
+     * @public
+     */
+    ASN1.prototype.getHexStringValue = function () {
+        var hexString = this.toHexString();
+        var offset = this.header * 2;
+        var length = this.length * 2;
+        return hexString.substr(offset, length);
+    };
+    ASN1.decode = function (str) {
+        var stream;
+        if (!(str instanceof Stream)) {
+            stream = new Stream(str, 0);
+        }
+        else {
+            stream = str;
+        }
+        var streamStart = new Stream(stream);
+        var tag = new ASN1Tag(stream);
+        var len = ASN1.decodeLength(stream);
+        var start = stream.pos;
+        var header = start - streamStart.pos;
+        var sub = null;
+        var getSub = function () {
+            var ret = [];
+            if (len !== null) {
+                // definite length
+                var end = start + len;
+                while (stream.pos < end) {
+                    ret[ret.length] = ASN1.decode(stream);
+                }
+                if (stream.pos != end) {
+                    throw new Error("Content size is not correct for container starting at offset " + start);
+                }
+            }
+            else {
+                // undefined length
+                try {
+                    for (;;) {
+                        var s = ASN1.decode(stream);
+                        if (s.tag.isEOC()) {
+                            break;
+                        }
+                        ret[ret.length] = s;
+                    }
+                    len = start - stream.pos; // undefined lengths are represented as negative values
+                }
+                catch (e) {
+                    throw new Error("Exception while decoding undefined length content: " + e);
+                }
+            }
+            return ret;
+        };
+        if (tag.tagConstructed) {
+            // must have valid content
+            sub = getSub();
+        }
+        else if (tag.isUniversal() && ((tag.tagNumber == 0x03) || (tag.tagNumber == 0x04))) {
+            // sometimes BitString and OctetString are used to encapsulate ASN.1
+            try {
+                if (tag.tagNumber == 0x03) {
+                    if (stream.get() != 0) {
+                        throw new Error("BIT STRINGs with unused bits cannot encapsulate.");
+                    }
+                }
+                sub = getSub();
+                for (var i = 0; i < sub.length; ++i) {
+                    if (sub[i].tag.isEOC()) {
+                        throw new Error("EOC is not supposed to be actual content.");
+                    }
+                }
+            }
+            catch (e) {
+                // but silently ignore when they don't
+                sub = null;
+            }
+        }
+        if (sub === null) {
+            if (len === null) {
+                throw new Error("We can't skip over an invalid tag with undefined length at offset " + start);
+            }
+            stream.pos = start + Math.abs(len);
+        }
+        return new ASN1(streamStart, header, len, tag, sub);
+    };
+    return ASN1;
+}());
+var ASN1Tag = /** @class */ (function () {
+    function ASN1Tag(stream) {
+        var buf = stream.get();
+        this.tagClass = buf >> 6;
+        this.tagConstructed = ((buf & 0x20) !== 0);
+        this.tagNumber = buf & 0x1F;
+        if (this.tagNumber == 0x1F) { // long tag
+            var n = new Int10();
+            do {
+                buf = stream.get();
+                n.mulAdd(128, buf & 0x7F);
+            } while (buf & 0x80);
+            this.tagNumber = n.simplify();
+        }
+    }
+    ASN1Tag.prototype.isUniversal = function () {
+        return this.tagClass === 0x00;
+    };
+    ASN1Tag.prototype.isEOC = function () {
+        return this.tagClass === 0x00 && this.tagNumber === 0x00;
+    };
+    return ASN1Tag;
+}());
+
+// Copyright (c) 2005  Tom Wu
+// Bits per digit
+var dbits;
+// JavaScript engine analysis
+var canary = 0xdeadbeefcafe;
+var j_lm = ((canary & 0xffffff) == 0xefcafe);
+//#region
+var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
+var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
+//#endregion
+// (public) Constructor
+var BigInteger = /** @class */ (function () {
+    function BigInteger(a, b, c) {
+        if (a != null) {
+            if ("number" == typeof a) {
+                this.fromNumber(a, b, c);
+            }
+            else if (b == null && "string" != typeof a) {
+                this.fromString(a, 256);
+            }
+            else {
+                this.fromString(a, b);
+            }
+        }
+    }
+    //#region PUBLIC
+    // BigInteger.prototype.toString = bnToString;
+    // (public) return string representation in given radix
+    BigInteger.prototype.toString = function (b) {
+        if (this.s < 0) {
+            return "-" + this.negate().toString(b);
+        }
+        var k;
+        if (b == 16) {
+            k = 4;
+        }
+        else if (b == 8) {
+            k = 3;
+        }
+        else if (b == 2) {
+            k = 1;
+        }
+        else if (b == 32) {
+            k = 5;
+        }
+        else if (b == 4) {
+            k = 2;
+        }
+        else {
+            return this.toRadix(b);
+        }
+        var km = (1 << k) - 1;
+        var d;
+        var m = false;
+        var r = "";
+        var i = this.t;
+        var p = this.DB - (i * this.DB) % k;
+        if (i-- > 0) {
+            if (p < this.DB && (d = this[i] >> p) > 0) {
+                m = true;
+                r = int2char(d);
+            }
+            while (i >= 0) {
+                if (p < k) {
+                    d = (this[i] & ((1 << p) - 1)) << (k - p);
+                    d |= this[--i] >> (p += this.DB - k);
+                }
+                else {
+                    d = (this[i] >> (p -= k)) & km;
+                    if (p <= 0) {
+                        p += this.DB;
+                        --i;
+                    }
+                }
+                if (d > 0) {
+                    m = true;
+                }
+                if (m) {
+                    r += int2char(d);
+                }
+            }
+        }
+        return m ? r : "0";
+    };
+    // BigInteger.prototype.negate = bnNegate;
+    // (public) -this
+    BigInteger.prototype.negate = function () {
+        var r = nbi();
+        BigInteger.ZERO.subTo(this, r);
+        return r;
+    };
+    // BigInteger.prototype.abs = bnAbs;
+    // (public) |this|
+    BigInteger.prototype.abs = function () {
+        return (this.s < 0) ? this.negate() : this;
+    };
+    // BigInteger.prototype.compareTo = bnCompareTo;
+    // (public) return + if this > a, - if this < a, 0 if equal
+    BigInteger.prototype.compareTo = function (a) {
+        var r = this.s - a.s;
+        if (r != 0) {
+            return r;
+        }
+        var i = this.t;
+        r = i - a.t;
+        if (r != 0) {
+            return (this.s < 0) ? -r : r;
+        }
+        while (--i >= 0) {
+            if ((r = this[i] - a[i]) != 0) {
+                return r;
+            }
+        }
+        return 0;
+    };
+    // BigInteger.prototype.bitLength = bnBitLength;
+    // (public) return the number of bits in "this"
+    BigInteger.prototype.bitLength = function () {
+        if (this.t <= 0) {
+            return 0;
+        }
+        return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
+    };
+    // BigInteger.prototype.mod = bnMod;
+    // (public) this mod a
+    BigInteger.prototype.mod = function (a) {
+        var r = nbi();
+        this.abs().divRemTo(a, null, r);
+        if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) {
+            a.subTo(r, r);
+        }
+        return r;
+    };
+    // BigInteger.prototype.modPowInt = bnModPowInt;
+    // (public) this^e % m, 0 <= e < 2^32
+    BigInteger.prototype.modPowInt = function (e, m) {
+        var z;
+        if (e < 256 || m.isEven()) {
+            z = new Classic(m);
+        }
+        else {
+            z = new Montgomery(m);
+        }
+        return this.exp(e, z);
+    };
+    // BigInteger.prototype.clone = bnClone;
+    // (public)
+    BigInteger.prototype.clone = function () {
+        var r = nbi();
+        this.copyTo(r);
+        return r;
+    };
+    // BigInteger.prototype.intValue = bnIntValue;
+    // (public) return value as integer
+    BigInteger.prototype.intValue = function () {
+        if (this.s < 0) {
+            if (this.t == 1) {
+                return this[0] - this.DV;
+            }
+            else if (this.t == 0) {
+                return -1;
+            }
+        }
+        else if (this.t == 1) {
+            return this[0];
+        }
+        else if (this.t == 0) {
+            return 0;
+        }
+        // assumes 16 < DB < 32
+        return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0];
+    };
+    // BigInteger.prototype.byteValue = bnByteValue;
+    // (public) return value as byte
+    BigInteger.prototype.byteValue = function () {
+        return (this.t == 0) ? this.s : (this[0] << 24) >> 24;
+    };
+    // BigInteger.prototype.shortValue = bnShortValue;
+    // (public) return value as short (assumes DB>=16)
+    BigInteger.prototype.shortValue = function () {
+        return (this.t == 0) ? this.s : (this[0] << 16) >> 16;
+    };
+    // BigInteger.prototype.signum = bnSigNum;
+    // (public) 0 if this == 0, 1 if this > 0
+    BigInteger.prototype.signum = function () {
+        if (this.s < 0) {
+            return -1;
+        }
+        else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) {
+            return 0;
+        }
+        else {
+            return 1;
+        }
+    };
+    // BigInteger.prototype.toByteArray = bnToByteArray;
+    // (public) convert to bigendian byte array
+    BigInteger.prototype.toByteArray = function () {
+        var i = this.t;
+        var r = [];
+        r[0] = this.s;
+        var p = this.DB - (i * this.DB) % 8;
+        var d;
+        var k = 0;
+        if (i-- > 0) {
+            if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p) {
+                r[k++] = d | (this.s << (this.DB - p));
+            }
+            while (i >= 0) {
+                if (p < 8) {
+                    d = (this[i] & ((1 << p) - 1)) << (8 - p);
+                    d |= this[--i] >> (p += this.DB - 8);
+                }
+                else {
+                    d = (this[i] >> (p -= 8)) & 0xff;
+                    if (p <= 0) {
+                        p += this.DB;
+                        --i;
+                    }
+                }
+                if ((d & 0x80) != 0) {
+                    d |= -256;
+                }
+                if (k == 0 && (this.s & 0x80) != (d & 0x80)) {
+                    ++k;
+                }
+                if (k > 0 || d != this.s) {
+                    r[k++] = d;
+                }
+            }
+        }
+        return r;
+    };
+    // BigInteger.prototype.equals = bnEquals;
+    BigInteger.prototype.equals = function (a) {
+        return (this.compareTo(a) == 0);
+    };
+    // BigInteger.prototype.min = bnMin;
+    BigInteger.prototype.min = function (a) {
+        return (this.compareTo(a) < 0) ? this : a;
+    };
+    // BigInteger.prototype.max = bnMax;
+    BigInteger.prototype.max = function (a) {
+        return (this.compareTo(a) > 0) ? this : a;
+    };
+    // BigInteger.prototype.and = bnAnd;
+    BigInteger.prototype.and = function (a) {
+        var r = nbi();
+        this.bitwiseTo(a, op_and, r);
+        return r;
+    };
+    // BigInteger.prototype.or = bnOr;
+    BigInteger.prototype.or = function (a) {
+        var r = nbi();
+        this.bitwiseTo(a, op_or, r);
+        return r;
+    };
+    // BigInteger.prototype.xor = bnXor;
+    BigInteger.prototype.xor = function (a) {
+        var r = nbi();
+        this.bitwiseTo(a, op_xor, r);
+        return r;
+    };
+    // BigInteger.prototype.andNot = bnAndNot;
+    BigInteger.prototype.andNot = function (a) {
+        var r = nbi();
+        this.bitwiseTo(a, op_andnot, r);
+        return r;
+    };
+    // BigInteger.prototype.not = bnNot;
+    // (public) ~this
+    BigInteger.prototype.not = function () {
+        var r = nbi();
+        for (var i = 0; i < this.t; ++i) {
+            r[i] = this.DM & ~this[i];
+        }
+        r.t = this.t;
+        r.s = ~this.s;
+        return r;
+    };
+    // BigInteger.prototype.shiftLeft = bnShiftLeft;
+    // (public) this << n
+    BigInteger.prototype.shiftLeft = function (n) {
+        var r = nbi();
+        if (n < 0) {
+            this.rShiftTo(-n, r);
+        }
+        else {
+            this.lShiftTo(n, r);
+        }
+        return r;
+    };
+    // BigInteger.prototype.shiftRight = bnShiftRight;
+    // (public) this >> n
+    BigInteger.prototype.shiftRight = function (n) {
+        var r = nbi();
+        if (n < 0) {
+            this.lShiftTo(-n, r);
+        }
+        else {
+            this.rShiftTo(n, r);
+        }
+        return r;
+    };
+    // BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
+    // (public) returns index of lowest 1-bit (or -1 if none)
+    BigInteger.prototype.getLowestSetBit = function () {
+        for (var i = 0; i < this.t; ++i) {
+            if (this[i] != 0) {
+                return i * this.DB + lbit(this[i]);
+            }
+        }
+        if (this.s < 0) {
+            return this.t * this.DB;
+        }
+        return -1;
+    };
+    // BigInteger.prototype.bitCount = bnBitCount;
+    // (public) return number of set bits
+    BigInteger.prototype.bitCount = function () {
+        var r = 0;
+        var x = this.s & this.DM;
+        for (var i = 0; i < this.t; ++i) {
+            r += cbit(this[i] ^ x);
+        }
+        return r;
+    };
+    // BigInteger.prototype.testBit = bnTestBit;
+    // (public) true iff nth bit is set
+    BigInteger.prototype.testBit = function (n) {
+        var j = Math.floor(n / this.DB);
+        if (j >= this.t) {
+            return (this.s != 0);
+        }
+        return ((this[j] & (1 << (n % this.DB))) != 0);
+    };
+    // BigInteger.prototype.setBit = bnSetBit;
+    // (public) this | (1<<n)
+    BigInteger.prototype.setBit = function (n) {
+        return this.changeBit(n, op_or);
+    };
+    // BigInteger.prototype.clearBit = bnClearBit;
+    // (public) this & ~(1<<n)
+    BigInteger.prototype.clearBit = function (n) {
+        return this.changeBit(n, op_andnot);
+    };
+    // BigInteger.prototype.flipBit = bnFlipBit;
+    // (public) this ^ (1<<n)
+    BigInteger.prototype.flipBit = function (n) {
+        return this.changeBit(n, op_xor);
+    };
+    // BigInteger.prototype.add = bnAdd;
+    // (public) this + a
+    BigInteger.prototype.add = function (a) {
+        var r = nbi();
+        this.addTo(a, r);
+        return r;
+    };
+    // BigInteger.prototype.subtract = bnSubtract;
+    // (public) this - a
+    BigInteger.prototype.subtract = function (a) {
+        var r = nbi();
+        this.subTo(a, r);
+        return r;
+    };
+    // BigInteger.prototype.multiply = bnMultiply;
+    // (public) this * a
+    BigInteger.prototype.multiply = function (a) {
+        var r = nbi();
+        this.multiplyTo(a, r);
+        return r;
+    };
+    // BigInteger.prototype.divide = bnDivide;
+    // (public) this / a
+    BigInteger.prototype.divide = function (a) {
+        var r = nbi();
+        this.divRemTo(a, r, null);
+        return r;
+    };
+    // BigInteger.prototype.remainder = bnRemainder;
+    // (public) this % a
+    BigInteger.prototype.remainder = function (a) {
+        var r = nbi();
+        this.divRemTo(a, null, r);
+        return r;
+    };
+    // BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
+    // (public) [this/a,this%a]
+    BigInteger.prototype.divideAndRemainder = function (a) {
+        var q = nbi();
+        var r = nbi();
+        this.divRemTo(a, q, r);
+        return [q, r];
+    };
+    // BigInteger.prototype.modPow = bnModPow;
+    // (public) this^e % m (HAC 14.85)
+    BigInteger.prototype.modPow = function (e, m) {
+        var i = e.bitLength();
+        var k;
+        var r = nbv(1);
+        var z;
+        if (i <= 0) {
+            return r;
+        }
+        else if (i < 18) {
+            k = 1;
+        }
+        else if (i < 48) {
+            k = 3;
+        }
+        else if (i < 144) {
+            k = 4;
+        }
+        else if (i < 768) {
+            k = 5;
+        }
+        else {
+            k = 6;
+        }
+        if (i < 8) {
+            z = new Classic(m);
+        }
+        else if (m.isEven()) {
+            z = new Barrett(m);
+        }
+        else {
+            z = new Montgomery(m);
+        }
+        // precomputation
+        var g = [];
+        var n = 3;
+        var k1 = k - 1;
+        var km = (1 << k) - 1;
+        g[1] = z.convert(this);
+        if (k > 1) {
+            var g2 = nbi();
+            z.sqrTo(g[1], g2);
+            while (n <= km) {
+                g[n] = nbi();
+                z.mulTo(g2, g[n - 2], g[n]);
+                n += 2;
+            }
+        }
+        var j = e.t - 1;
+        var w;
+        var is1 = true;
+        var r2 = nbi();
+        var t;
+        i = nbits(e[j]) - 1;
+        while (j >= 0) {
+            if (i >= k1) {
+                w = (e[j] >> (i - k1)) & km;
+            }
+            else {
+                w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
+                if (j > 0) {
+                    w |= e[j - 1] >> (this.DB + i - k1);
+                }
+            }
+            n = k;
+            while ((w & 1) == 0) {
+                w >>= 1;
+                --n;
+            }
+            if ((i -= n) < 0) {
+                i += this.DB;
+                --j;
+            }
+            if (is1) { // ret == 1, don't bother squaring or multiplying it
+                g[w].copyTo(r);
+                is1 = false;
+            }
+            else {
+                while (n > 1) {
+                    z.sqrTo(r, r2);
+                    z.sqrTo(r2, r);
+                    n -= 2;
+                }
+                if (n > 0) {
+                    z.sqrTo(r, r2);
+                }
+                else {
+                    t = r;
+                    r = r2;
+                    r2 = t;
+                }
+                z.mulTo(r2, g[w], r);
+            }
+            while (j >= 0 && (e[j] & (1 << i)) == 0) {
+                z.sqrTo(r, r2);
+                t = r;
+                r = r2;
+                r2 = t;
+                if (--i < 0) {
+                    i = this.DB - 1;
+                    --j;
+                }
+            }
+        }
+        return z.revert(r);
+    };
+    // BigInteger.prototype.modInverse = bnModInverse;
+    // (public) 1/this % m (HAC 14.61)
+    BigInteger.prototype.modInverse = function (m) {
+        var ac = m.isEven();
+        if ((this.isEven() && ac) || m.signum() == 0) {
+            return BigInteger.ZERO;
+        }
+        var u = m.clone();
+        var v = this.clone();
+        var a = nbv(1);
+        var b = nbv(0);
+        var c = nbv(0);
+        var d = nbv(1);
+        while (u.signum() != 0) {
+            while (u.isEven()) {
+                u.rShiftTo(1, u);
+                if (ac) {
+                    if (!a.isEven() || !b.isEven()) {
+                        a.addTo(this, a);
+                        b.subTo(m, b);
+                    }
+                    a.rShiftTo(1, a);
+                }
+                else if (!b.isEven()) {
+                    b.subTo(m, b);
+                }
+                b.rShiftTo(1, b);
+            }
+            while (v.isEven()) {
+                v.rShiftTo(1, v);
+                if (ac) {
+                    if (!c.isEven() || !d.isEven()) {
+                        c.addTo(this, c);
+                        d.subTo(m, d);
+                    }
+                    c.rShiftTo(1, c);
+                }
+                else if (!d.isEven()) {
+                    d.subTo(m, d);
+                }
+                d.rShiftTo(1, d);
+            }
+            if (u.compareTo(v) >= 0) {
+                u.subTo(v, u);
+                if (ac) {
+                    a.subTo(c, a);
+                }
+                b.subTo(d, b);
+            }
+            else {
+                v.subTo(u, v);
+                if (ac) {
+                    c.subTo(a, c);
+                }
+                d.subTo(b, d);
+            }
+        }
+        if (v.compareTo(BigInteger.ONE) != 0) {
+            return BigInteger.ZERO;
+        }
+        if (d.compareTo(m) >= 0) {
+            return d.subtract(m);
+        }
+        if (d.signum() < 0) {
+            d.addTo(m, d);
+        }
+        else {
+            return d;
+        }
+        if (d.signum() < 0) {
+            return d.add(m);
+        }
+        else {
+            return d;
+        }
+    };
+    // BigInteger.prototype.pow = bnPow;
+    // (public) this^e
+    BigInteger.prototype.pow = function (e) {
+        return this.exp(e, new NullExp());
+    };
+    // BigInteger.prototype.gcd = bnGCD;
+    // (public) gcd(this,a) (HAC 14.54)
+    BigInteger.prototype.gcd = function (a) {
+        var x = (this.s < 0) ? this.negate() : this.clone();
+        var y = (a.s < 0) ? a.negate() : a.clone();
+        if (x.compareTo(y) < 0) {
+            var t = x;
+            x = y;
+            y = t;
+        }
+        var i = x.getLowestSetBit();
+        var g = y.getLowestSetBit();
+        if (g < 0) {
+            return x;
+        }
+        if (i < g) {
+            g = i;
+        }
+        if (g > 0) {
+            x.rShiftTo(g, x);
+            y.rShiftTo(g, y);
+        }
+        while (x.signum() > 0) {
+            if ((i = x.getLowestSetBit()) > 0) {
+                x.rShiftTo(i, x);
+            }
+            if ((i = y.getLowestSetBit()) > 0) {
+                y.rShiftTo(i, y);
+            }
+            if (x.compareTo(y) >= 0) {
+                x.subTo(y, x);
+                x.rShiftTo(1, x);
+            }
+            else {
+                y.subTo(x, y);
+                y.rShiftTo(1, y);
+            }
+        }
+        if (g > 0) {
+            y.lShiftTo(g, y);
+        }
+        return y;
+    };
+    // BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
+    // (public) test primality with certainty >= 1-.5^t
+    BigInteger.prototype.isProbablePrime = function (t) {
+        var i;
+        var x = this.abs();
+        if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
+            for (i = 0; i < lowprimes.length; ++i) {
+                if (x[0] == lowprimes[i]) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        if (x.isEven()) {
+            return false;
+        }
+        i = 1;
+        while (i < lowprimes.length) {
+            var m = lowprimes[i];
+            var j = i + 1;
+            while (j < lowprimes.length && m < lplim) {
+                m *= lowprimes[j++];
+            }
+            m = x.modInt(m);
+            while (i < j) {
+                if (m % lowprimes[i++] == 0) {
+                    return false;
+                }
+            }
+        }
+        return x.millerRabin(t);
+    };
+    //#endregion PUBLIC
+    //#region PROTECTED
+    // BigInteger.prototype.copyTo = bnpCopyTo;
+    // (protected) copy this to r
+    BigInteger.prototype.copyTo = function (r) {
+        for (var i = this.t - 1; i >= 0; --i) {
+            r[i] = this[i];
+        }
+        r.t = this.t;
+        r.s = this.s;
+    };
+    // BigInteger.prototype.fromInt = bnpFromInt;
+    // (protected) set from integer value x, -DV <= x < DV
+    BigInteger.prototype.fromInt = function (x) {
+        this.t = 1;
+        this.s = (x < 0) ? -1 : 0;
+        if (x > 0) {
+            this[0] = x;
+        }
+        else if (x < -1) {
+            this[0] = x + this.DV;
+        }
+        else {
+            this.t = 0;
+        }
+    };
+    // BigInteger.prototype.fromString = bnpFromString;
+    // (protected) set from string and radix
+    BigInteger.prototype.fromString = function (s, b) {
+        var k;
+        if (b == 16) {
+            k = 4;
+        }
+        else if (b == 8) {
+            k = 3;
+        }
+        else if (b == 256) {
+            k = 8;
+            /* byte array */
+        }
+        else if (b == 2) {
+            k = 1;
+        }
+        else if (b == 32) {
+            k = 5;
+        }
+        else if (b == 4) {
+            k = 2;
+        }
+        else {
+            this.fromRadix(s, b);
+            return;
+        }
+        this.t = 0;
+        this.s = 0;
+        var i = s.length;
+        var mi = false;
+        var sh = 0;
+        while (--i >= 0) {
+            var x = (k == 8) ? (+s[i]) & 0xff : intAt(s, i);
+            if (x < 0) {
+                if (s.charAt(i) == "-") {
+                    mi = true;
+                }
+                continue;
+            }
+            mi = false;
+            if (sh == 0) {
+                this[this.t++] = x;
+            }
+            else if (sh + k > this.DB) {
+                this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
+                this[this.t++] = (x >> (this.DB - sh));
+            }
+            else {
+                this[this.t - 1] |= x << sh;
+            }
+            sh += k;
+            if (sh >= this.DB) {
+                sh -= this.DB;
+            }
+        }
+        if (k == 8 && ((+s[0]) & 0x80) != 0) {
+            this.s = -1;
+            if (sh > 0) {
+                this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
+            }
+        }
+        this.clamp();
+        if (mi) {
+            BigInteger.ZERO.subTo(this, this);
+        }
+    };
+    // BigInteger.prototype.clamp = bnpClamp;
+    // (protected) clamp off excess high words
+    BigInteger.prototype.clamp = function () {
+        var c = this.s & this.DM;
+        while (this.t > 0 && this[this.t - 1] == c) {
+            --this.t;
+        }
+    };
+    // BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
+    // (protected) r = this << n*DB
+    BigInteger.prototype.dlShiftTo = function (n, r) {
+        var i;
+        for (i = this.t - 1; i >= 0; --i) {
+            r[i + n] = this[i];
+        }
+        for (i = n - 1; i >= 0; --i) {
+            r[i] = 0;
+        }
+        r.t = this.t + n;
+        r.s = this.s;
+    };
+    // BigInteger.prototype.drShiftTo = bnpDRShiftTo;
+    // (protected) r = this >> n*DB
+    BigInteger.prototype.drShiftTo = function (n, r) {
+        for (var i = n; i < this.t; ++i) {
+            r[i - n] = this[i];
+        }
+        r.t = Math.max(this.t - n, 0);
+        r.s = this.s;
+    };
+    // BigInteger.prototype.lShiftTo = bnpLShiftTo;
+    // (protected) r = this << n
+    BigInteger.prototype.lShiftTo = function (n, r) {
+        var bs = n % this.DB;
+        var cbs = this.DB - bs;
+        var bm = (1 << cbs) - 1;
+        var ds = Math.floor(n / this.DB);
+        var c = (this.s << bs) & this.DM;
+        for (var i = this.t - 1; i >= 0; --i) {
+            r[i + ds + 1] = (this[i] >> cbs) | c;
+            c = (this[i] & bm) << bs;
+        }
+        for (var i = ds - 1; i >= 0; --i) {
+            r[i] = 0;
+        }
+        r[ds] = c;
+        r.t = this.t + ds + 1;
+        r.s = this.s;
+        r.clamp();
+    };
+    // BigInteger.prototype.rShiftTo = bnpRShiftTo;
+    // (protected) r = this >> n
+    BigInteger.prototype.rShiftTo = function (n, r) {
+        r.s = this.s;
+        var ds = Math.floor(n / this.DB);
+        if (ds >= this.t) {
+            r.t = 0;
+            return;
+        }
+        var bs = n % this.DB;
+        var cbs = this.DB - bs;
+        var bm = (1 << bs) - 1;
+        r[0] = this[ds] >> bs;
+        for (var i = ds + 1; i < this.t; ++i) {
+            r[i - ds - 1] |= (this[i] & bm) << cbs;
+            r[i - ds] = this[i] >> bs;
+        }
+        if (bs > 0) {
+            r[this.t - ds - 1] |= (this.s & bm) << cbs;
+        }
+        r.t = this.t - ds;
+        r.clamp();
+    };
+    // BigInteger.prototype.subTo = bnpSubTo;
+    // (protected) r = this - a
+    BigInteger.prototype.subTo = function (a, r) {
+        var i = 0;
+        var c = 0;
+        var m = Math.min(a.t, this.t);
+        while (i < m) {
+            c += this[i] - a[i];
+            r[i++] = c & this.DM;
+            c >>= this.DB;
+        }
+        if (a.t < this.t) {
+            c -= a.s;
+            while (i < this.t) {
+                c += this[i];
+                r[i++] = c & this.DM;
+                c >>= this.DB;
+            }
+            c += this.s;
+        }
+        else {
+            c += this.s;
+            while (i < a.t) {
+                c -= a[i];
+                r[i++] = c & this.DM;
+                c >>= this.DB;
+            }
+            c -= a.s;
+        }
+        r.s = (c < 0) ? -1 : 0;
+        if (c < -1) {
+            r[i++] = this.DV + c;
+        }
+        else if (c > 0) {
+            r[i++] = c;
+        }
+        r.t = i;
+        r.clamp();
+    };
+    // BigInteger.prototype.multiplyTo = bnpMultiplyTo;
+    // (protected) r = this * a, r != this,a (HAC 14.12)
+    // "this" should be the larger one if appropriate.
+    BigInteger.prototype.multiplyTo = function (a, r) {
+        var x = this.abs();
+        var y = a.abs();
+        var i = x.t;
+        r.t = i + y.t;
+        while (--i >= 0) {
+            r[i] = 0;
+        }
+        for (i = 0; i < y.t; ++i) {
+            r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
+        }
+        r.s = 0;
+        r.clamp();
+        if (this.s != a.s) {
+            BigInteger.ZERO.subTo(r, r);
+        }
+    };
+    // BigInteger.prototype.squareTo = bnpSquareTo;
+    // (protected) r = this^2, r != this (HAC 14.16)
+    BigInteger.prototype.squareTo = function (r) {
+        var x = this.abs();
+        var i = r.t = 2 * x.t;
+        while (--i >= 0) {
+            r[i] = 0;
+        }
+        for (i = 0; i < x.t - 1; ++i) {
+            var c = x.am(i, x[i], r, 2 * i, 0, 1);
+            if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
+                r[i + x.t] -= x.DV;
+                r[i + x.t + 1] = 1;
+            }
+        }
+        if (r.t > 0) {
+            r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
+        }
+        r.s = 0;
+        r.clamp();
+    };
+    // BigInteger.prototype.divRemTo = bnpDivRemTo;
+    // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+    // r != q, this != m.  q or r may be null.
+    BigInteger.prototype.divRemTo = function (m, q, r) {
+        var pm = m.abs();
+        if (pm.t <= 0) {
+            return;
+        }
+        var pt = this.abs();
+        if (pt.t < pm.t) {
+            if (q != null) {
+                q.fromInt(0);
+            }
+            if (r != null) {
+                this.copyTo(r);
+            }
+            return;
+        }
+        if (r == null) {
+            r = nbi();
+        }
+        var y = nbi();
+        var ts = this.s;
+        var ms = m.s;
+        var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
+        if (nsh > 0) {
+            pm.lShiftTo(nsh, y);
+            pt.lShiftTo(nsh, r);
+        }
+        else {
+            pm.copyTo(y);
+            pt.copyTo(r);
+        }
+        var ys = y.t;
+        var y0 = y[ys - 1];
+        if (y0 == 0) {
+            return;
+        }
+        var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
+        var d1 = this.FV / yt;
+        var d2 = (1 << this.F1) / yt;
+        var e = 1 << this.F2;
+        var i = r.t;
+        var j = i - ys;
+        var t = (q == null) ? nbi() : q;
+        y.dlShiftTo(j, t);
+        if (r.compareTo(t) >= 0) {
+            r[r.t++] = 1;
+            r.subTo(t, r);
+        }
+        BigInteger.ONE.dlShiftTo(ys, t);
+        t.subTo(y, y); // "negative" y so we can replace sub with am later
+        while (y.t < ys) {
+            y[y.t++] = 0;
+        }
+        while (--j >= 0) {
+            // Estimate quotient digit
+            var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
+            if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { // Try it out
+                y.dlShiftTo(j, t);
+                r.subTo(t, r);
+                while (r[i] < --qd) {
+                    r.subTo(t, r);
+                }
+            }
+        }
+        if (q != null) {
+            r.drShiftTo(ys, q);
+            if (ts != ms) {
+                BigInteger.ZERO.subTo(q, q);
+            }
+        }
+        r.t = ys;
+        r.clamp();
+        if (nsh > 0) {
+            r.rShiftTo(nsh, r);
+        } // Denormalize remainder
+        if (ts < 0) {
+            BigInteger.ZERO.subTo(r, r);
+        }
+    };
+    // BigInteger.prototype.invDigit = bnpInvDigit;
+    // (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+    // justification:
+    //         xy == 1 (mod m)
+    //         xy =  1+km
+    //   xy(2-xy) = (1+km)(1-km)
+    // x[y(2-xy)] = 1-k^2m^2
+    // x[y(2-xy)] == 1 (mod m^2)
+    // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+    // should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+    // JS multiply "overflows" differently from C/C++, so care is needed here.
+    BigInteger.prototype.invDigit = function () {
+        if (this.t < 1) {
+            return 0;
+        }
+        var x = this[0];
+        if ((x & 1) == 0) {
+            return 0;
+        }
+        var y = x & 3; // y == 1/x mod 2^2
+        y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
+        y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
+        y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
+        // last step - calculate inverse mod DV directly;
+        // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+        y = (y * (2 - x * y % this.DV)) % this.DV; // y == 1/x mod 2^dbits
+        // we really want the negative inverse, and -DV < y < DV
+        return (y > 0) ? this.DV - y : -y;
+    };
+    // BigInteger.prototype.isEven = bnpIsEven;
+    // (protected) true iff this is even
+    BigInteger.prototype.isEven = function () {
+        return ((this.t > 0) ? (this[0] & 1) : this.s) == 0;
+    };
+    // BigInteger.prototype.exp = bnpExp;
+    // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+    BigInteger.prototype.exp = function (e, z) {
+        if (e > 0xffffffff || e < 1) {
+            return BigInteger.ONE;
+        }
+        var r = nbi();
+        var r2 = nbi();
+        var g = z.convert(this);
+        var i = nbits(e) - 1;
+        g.copyTo(r);
+        while (--i >= 0) {
+            z.sqrTo(r, r2);
+            if ((e & (1 << i)) > 0) {
+                z.mulTo(r2, g, r);
+            }
+            else {
+                var t = r;
+                r = r2;
+                r2 = t;
+            }
+        }
+        return z.revert(r);
+    };
+    // BigInteger.prototype.chunkSize = bnpChunkSize;
+    // (protected) return x s.t. r^x < DV
+    BigInteger.prototype.chunkSize = function (r) {
+        return Math.floor(Math.LN2 * this.DB / Math.log(r));
+    };
+    // BigInteger.prototype.toRadix = bnpToRadix;
+    // (protected) convert to radix string
+    BigInteger.prototype.toRadix = function (b) {
+        if (b == null) {
+            b = 10;
+        }
+        if (this.signum() == 0 || b < 2 || b > 36) {
+            return "0";
+        }
+        var cs = this.chunkSize(b);
+        var a = Math.pow(b, cs);
+        var d = nbv(a);
+        var y = nbi();
+        var z = nbi();
+        var r = "";
+        this.divRemTo(d, y, z);
+        while (y.signum() > 0) {
+            r = (a + z.intValue()).toString(b).substr(1) + r;
+            y.divRemTo(d, y, z);
+        }
+        return z.intValue().toString(b) + r;
+    };
+    // BigInteger.prototype.fromRadix = bnpFromRadix;
+    // (protected) convert from radix string
+    BigInteger.prototype.fromRadix = function (s, b) {
+        this.fromInt(0);
+        if (b == null) {
+            b = 10;
+        }
+        var cs = this.chunkSize(b);
+        var d = Math.pow(b, cs);
+        var mi = false;
+        var j = 0;
+        var w = 0;
+        for (var i = 0; i < s.length; ++i) {
+            var x = intAt(s, i);
+            if (x < 0) {
+                if (s.charAt(i) == "-" && this.signum() == 0) {
+                    mi = true;
+                }
+                continue;
+            }
+            w = b * w + x;
+            if (++j >= cs) {
+                this.dMultiply(d);
+                this.dAddOffset(w, 0);
+                j = 0;
+                w = 0;
+            }
+        }
+        if (j > 0) {
+            this.dMultiply(Math.pow(b, j));
+            this.dAddOffset(w, 0);
+        }
+        if (mi) {
+            BigInteger.ZERO.subTo(this, this);
+        }
+    };
+    // BigInteger.prototype.fromNumber = bnpFromNumber;
+    // (protected) alternate constructor
+    BigInteger.prototype.fromNumber = function (a, b, c) {
+        if ("number" == typeof b) {
+            // new BigInteger(int,int,RNG)
+            if (a < 2) {
+                this.fromInt(1);
+            }
+            else {
+                this.fromNumber(a, c);
+                if (!this.testBit(a - 1)) {
+                    // force MSB set
+                    this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
+                }
+                if (this.isEven()) {
+                    this.dAddOffset(1, 0);
+                } // force odd
+                while (!this.isProbablePrime(b)) {
+                    this.dAddOffset(2, 0);
+                    if (this.bitLength() > a) {
+                        this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
+                    }
+                }
+            }
+        }
+        else {
+            // new BigInteger(int,RNG)
+            var x = [];
+            var t = a & 7;
+            x.length = (a >> 3) + 1;
+            b.nextBytes(x);
+            if (t > 0) {
+                x[0] &= ((1 << t) - 1);
+            }
+            else {
+                x[0] = 0;
+            }
+            this.fromString(x, 256);
+        }
+    };
+    // BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
+    // (protected) r = this op a (bitwise)
+    BigInteger.prototype.bitwiseTo = function (a, op, r) {
+        var i;
+        var f;
+        var m = Math.min(a.t, this.t);
+        for (i = 0; i < m; ++i) {
+            r[i] = op(this[i], a[i]);
+        }
+        if (a.t < this.t) {
+            f = a.s & this.DM;
+            for (i = m; i < this.t; ++i) {
+                r[i] = op(this[i], f);
+            }
+            r.t = this.t;
+        }
+        else {
+            f = this.s & this.DM;
+            for (i = m; i < a.t; ++i) {
+                r[i] = op(f, a[i]);
+            }
+            r.t = a.t;
+        }
+        r.s = op(this.s, a.s);
+        r.clamp();
+    };
+    // BigInteger.prototype.changeBit = bnpChangeBit;
+    // (protected) this op (1<<n)
+    BigInteger.prototype.changeBit = function (n, op) {
+        var r = BigInteger.ONE.shiftLeft(n);
+        this.bitwiseTo(r, op, r);
+        return r;
+    };
+    // BigInteger.prototype.addTo = bnpAddTo;
+    // (protected) r = this + a
+    BigInteger.prototype.addTo = function (a, r) {
+        var i = 0;
+        var c = 0;
+        var m = Math.min(a.t, this.t);
+        while (i < m) {
+            c += this[i] + a[i];
+            r[i++] = c & this.DM;
+            c >>= this.DB;
+        }
+        if (a.t < this.t) {
+            c += a.s;
+            while (i < this.t) {
+                c += this[i];
+                r[i++] = c & this.DM;
+                c >>= this.DB;
+            }
+            c += this.s;
+        }
+        else {
+            c += this.s;
+            while (i < a.t) {
+                c += a[i];
+                r[i++] = c & this.DM;
+                c >>= this.DB;
+            }
+            c += a.s;
+        }
+        r.s = (c < 0) ? -1 : 0;
+        if (c > 0) {
+            r[i++] = c;
+        }
+        else if (c < -1) {
+            r[i++] = this.DV + c;
+        }
+        r.t = i;
+        r.clamp();
+    };
+    // BigInteger.prototype.dMultiply = bnpDMultiply;
+    // (protected) this *= n, this >= 0, 1 < n < DV
+    BigInteger.prototype.dMultiply = function (n) {
+        this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
+        ++this.t;
+        this.clamp();
+    };
+    // BigInteger.prototype.dAddOffset = bnpDAddOffset;
+    // (protected) this += n << w words, this >= 0
+    BigInteger.prototype.dAddOffset = function (n, w) {
+        if (n == 0) {
+            return;
+        }
+        while (this.t <= w) {
+            this[this.t++] = 0;
+        }
+        this[w] += n;
+        while (this[w] >= this.DV) {
+            this[w] -= this.DV;
+            if (++w >= this.t) {
+                this[this.t++] = 0;
+            }
+            ++this[w];
+        }
+    };
+    // BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
+    // (protected) r = lower n words of "this * a", a.t <= n
+    // "this" should be the larger one if appropriate.
+    BigInteger.prototype.multiplyLowerTo = function (a, n, r) {
+        var i = Math.min(this.t + a.t, n);
+        r.s = 0; // assumes a,this >= 0
+        r.t = i;
+        while (i > 0) {
+            r[--i] = 0;
+        }
+        for (var j = r.t - this.t; i < j; ++i) {
+            r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
+        }
+        for (var j = Math.min(a.t, n); i < j; ++i) {
+            this.am(0, a[i], r, i, 0, n - i);
+        }
+        r.clamp();
+    };
+    // BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
+    // (protected) r = "this * a" without lower n words, n > 0
+    // "this" should be the larger one if appropriate.
+    BigInteger.prototype.multiplyUpperTo = function (a, n, r) {
+        --n;
+        var i = r.t = this.t + a.t - n;
+        r.s = 0; // assumes a,this >= 0
+        while (--i >= 0) {
+            r[i] = 0;
+        }
+        for (i = Math.max(n - this.t, 0); i < a.t; ++i) {
+            r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
+        }
+        r.clamp();
+        r.drShiftTo(1, r);
+    };
+    // BigInteger.prototype.modInt = bnpModInt;
+    // (protected) this % n, n < 2^26
+    BigInteger.prototype.modInt = function (n) {
+        if (n <= 0) {
+            return 0;
+        }
+        var d = this.DV % n;
+        var r = (this.s < 0) ? n - 1 : 0;
+        if (this.t > 0) {
+            if (d == 0) {
+                r = this[0] % n;
+            }
+            else {
+                for (var i = this.t - 1; i >= 0; --i) {
+                    r = (d * r + this[i]) % n;
+                }
+            }
+        }
+        return r;
+    };
+    // BigInteger.prototype.millerRabin = bnpMillerRabin;
+    // (protected) true if probably prime (HAC 4.24, Miller-Rabin)
+    BigInteger.prototype.millerRabin = function (t) {
+        var n1 = this.subtract(BigInteger.ONE);
+        var k = n1.getLowestSetBit();
+        if (k <= 0) {
+            return false;
+        }
+        var r = n1.shiftRight(k);
+        t = (t + 1) >> 1;
+        if (t > lowprimes.length) {
+            t = lowprimes.length;
+        }
+        var a = nbi();
+        for (var i = 0; i < t; ++i) {
+            // Pick bases at random, instead of starting at 2
+            a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
+            var y = a.modPow(r, this);
+            if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
+                var j = 1;
+                while (j++ < k && y.compareTo(n1) != 0) {
+                    y = y.modPowInt(2, this);
+                    if (y.compareTo(BigInteger.ONE) == 0) {
+                        return false;
+                    }
+                }
+                if (y.compareTo(n1) != 0) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    };
+    // BigInteger.prototype.square = bnSquare;
+    // (public) this^2
+    BigInteger.prototype.square = function () {
+        var r = nbi();
+        this.squareTo(r);
+        return r;
+    };
+    //#region ASYNC
+    // Public API method
+    BigInteger.prototype.gcda = function (a, callback) {
+        var x = (this.s < 0) ? this.negate() : this.clone();
+        var y = (a.s < 0) ? a.negate() : a.clone();
+        if (x.compareTo(y) < 0) {
+            var t = x;
+            x = y;
+            y = t;
+        }
+        var i = x.getLowestSetBit();
+        var g = y.getLowestSetBit();
+        if (g < 0) {
+            callback(x);
+            return;
+        }
+        if (i < g) {
+            g = i;
+        }
+        if (g > 0) {
+            x.rShiftTo(g, x);
+            y.rShiftTo(g, y);
+        }
+        // Workhorse of the algorithm, gets called 200 - 800 times per 512 bit keygen.
+        var gcda1 = function () {
+            if ((i = x.getLowestSetBit()) > 0) {
+                x.rShiftTo(i, x);
+            }
+            if ((i = y.getLowestSetBit()) > 0) {
+                y.rShiftTo(i, y);
+            }
+            if (x.compareTo(y) >= 0) {
+                x.subTo(y, x);
+                x.rShiftTo(1, x);
+            }
+            else {
+                y.subTo(x, y);
+                y.rShiftTo(1, y);
+            }
+            if (!(x.signum() > 0)) {
+                if (g > 0) {
+                    y.lShiftTo(g, y);
+                }
+                setTimeout(function () { callback(y); }, 0); // escape
+            }
+            else {
+                setTimeout(gcda1, 0);
+            }
+        };
+        setTimeout(gcda1, 10);
+    };
+    // (protected) alternate constructor
+    BigInteger.prototype.fromNumberAsync = function (a, b, c, callback) {
+        if ("number" == typeof b) {
+            if (a < 2) {
+                this.fromInt(1);
+            }
+            else {
+                this.fromNumber(a, c);
+                if (!this.testBit(a - 1)) {
+                    this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
+                }
+                if (this.isEven()) {
+                    this.dAddOffset(1, 0);
+                }
+                var bnp_1 = this;
+                var bnpfn1_1 = function () {
+                    bnp_1.dAddOffset(2, 0);
+                    if (bnp_1.bitLength() > a) {
+                        bnp_1.subTo(BigInteger.ONE.shiftLeft(a - 1), bnp_1);
+                    }
+                    if (bnp_1.isProbablePrime(b)) {
+                        setTimeout(function () { callback(); }, 0); // escape
+                    }
+                    else {
+                        setTimeout(bnpfn1_1, 0);
+                    }
+                };
+                setTimeout(bnpfn1_1, 0);
+            }
+        }
+        else {
+            var x = [];
+            var t = a & 7;
+            x.length = (a >> 3) + 1;
+            b.nextBytes(x);
+            if (t > 0) {
+                x[0] &= ((1 << t) - 1);
+            }
+            else {
+                x[0] = 0;
+            }
+            this.fromString(x, 256);
+        }
+    };
+    return BigInteger;
+}());
+//#region REDUCERS
+//#region NullExp
+var NullExp = /** @class */ (function () {
+    function NullExp() {
+    }
+    // NullExp.prototype.convert = nNop;
+    NullExp.prototype.convert = function (x) {
+        return x;
+    };
+    // NullExp.prototype.revert = nNop;
+    NullExp.prototype.revert = function (x) {
+        return x;
+    };
+    // NullExp.prototype.mulTo = nMulTo;
+    NullExp.prototype.mulTo = function (x, y, r) {
+        x.multiplyTo(y, r);
+    };
+    // NullExp.prototype.sqrTo = nSqrTo;
+    NullExp.prototype.sqrTo = function (x, r) {
+        x.squareTo(r);
+    };
+    return NullExp;
+}());
+// Modular reduction using "classic" algorithm
+var Classic = /** @class */ (function () {
+    function Classic(m) {
+        this.m = m;
+    }
+    // Classic.prototype.convert = cConvert;
+    Classic.prototype.convert = function (x) {
+        if (x.s < 0 || x.compareTo(this.m) >= 0) {
+            return x.mod(this.m);
+        }
+        else {
+            return x;
+        }
+    };
+    // Classic.prototype.revert = cRevert;
+    Classic.prototype.revert = function (x) {
+        return x;
+    };
+    // Classic.prototype.reduce = cReduce;
+    Classic.prototype.reduce = function (x) {
+        x.divRemTo(this.m, null, x);
+    };
+    // Classic.prototype.mulTo = cMulTo;
+    Classic.prototype.mulTo = function (x, y, r) {
+        x.multiplyTo(y, r);
+        this.reduce(r);
+    };
+    // Classic.prototype.sqrTo = cSqrTo;
+    Classic.prototype.sqrTo = function (x, r) {
+        x.squareTo(r);
+        this.reduce(r);
+    };
+    return Classic;
+}());
+//#endregion
+//#region Montgomery
+// Montgomery reduction
+var Montgomery = /** @class */ (function () {
+    function Montgomery(m) {
+        this.m = m;
+        this.mp = m.invDigit();
+        this.mpl = this.mp & 0x7fff;
+        this.mph = this.mp >> 15;
+        this.um = (1 << (m.DB - 15)) - 1;
+        this.mt2 = 2 * m.t;
+    }
+    // Montgomery.prototype.convert = montConvert;
+    // xR mod m
+    Montgomery.prototype.convert = function (x) {
+        var r = nbi();
+        x.abs().dlShiftTo(this.m.t, r);
+        r.divRemTo(this.m, null, r);
+        if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) {
+            this.m.subTo(r, r);
+        }
+        return r;
+    };
+    // Montgomery.prototype.revert = montRevert;
+    // x/R mod m
+    Montgomery.prototype.revert = function (x) {
+        var r = nbi();
+        x.copyTo(r);
+        this.reduce(r);
+        return r;
+    };
+    // Montgomery.prototype.reduce = montReduce;
+    // x = x/R mod m (HAC 14.32)
+    Montgomery.prototype.reduce = function (x) {
+        while (x.t <= this.mt2) {
+            // pad x so am has enough room later
+            x[x.t++] = 0;
+        }
+        for (var i = 0; i < this.m.t; ++i) {
+            // faster way of calculating u0 = x[i]*mp mod DV
+            var j = x[i] & 0x7fff;
+            var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
+            // use am to combine the multiply-shift-add into one call
+            j = i + this.m.t;
+            x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
+            // propagate carry
+            while (x[j] >= x.DV) {
+                x[j] -= x.DV;
+                x[++j]++;
+            }
+        }
+        x.clamp();
+        x.drShiftTo(this.m.t, x);
+        if (x.compareTo(this.m) >= 0) {
+            x.subTo(this.m, x);
+        }
+    };
+    // Montgomery.prototype.mulTo = montMulTo;
+    // r = "xy/R mod m"; x,y != r
+    Montgomery.prototype.mulTo = function (x, y, r) {
+        x.multiplyTo(y, r);
+        this.reduce(r);
+    };
+    // Montgomery.prototype.sqrTo = montSqrTo;
+    // r = "x^2/R mod m"; x != r
+    Montgomery.prototype.sqrTo = function (x, r) {
+        x.squareTo(r);
+        this.reduce(r);
+    };
+    return Montgomery;
+}());
+//#endregion Montgomery
+//#region Barrett
+// Barrett modular reduction
+var Barrett = /** @class */ (function () {
+    function Barrett(m) {
+        this.m = m;
+        // setup Barrett
+        this.r2 = nbi();
+        this.q3 = nbi();
+        BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
+        this.mu = this.r2.divide(m);
+    }
+    // Barrett.prototype.convert = barrettConvert;
+    Barrett.prototype.convert = function (x) {
+        if (x.s < 0 || x.t > 2 * this.m.t) {
+            return x.mod(this.m);
+        }
+        else if (x.compareTo(this.m) < 0) {
+            return x;
+        }
+        else {
+            var r = nbi();
+            x.copyTo(r);
+            this.reduce(r);
+            return r;
+        }
+    };
+    // Barrett.prototype.revert = barrettRevert;
+    Barrett.prototype.revert = function (x) {
+        return x;
+    };
+    // Barrett.prototype.reduce = barrettReduce;
+    // x = x mod m (HAC 14.42)
+    Barrett.prototype.reduce = function (x) {
+        x.drShiftTo(this.m.t - 1, this.r2);
+        if (x.t > this.m.t + 1) {
+            x.t = this.m.t + 1;
+            x.clamp();
+        }
+        this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
+        this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
+        while (x.compareTo(this.r2) < 0) {
+            x.dAddOffset(1, this.m.t + 1);
+        }
+        x.subTo(this.r2, x);
+        while (x.compareTo(this.m) >= 0) {
+            x.subTo(this.m, x);
+        }
+    };
+    // Barrett.prototype.mulTo = barrettMulTo;
+    // r = x*y mod m; x,y != r
+    Barrett.prototype.mulTo = function (x, y, r) {
+        x.multiplyTo(y, r);
+        this.reduce(r);
+    };
+    // Barrett.prototype.sqrTo = barrettSqrTo;
+    // r = x^2 mod m; x != r
+    Barrett.prototype.sqrTo = function (x, r) {
+        x.squareTo(r);
+        this.reduce(r);
+    };
+    return Barrett;
+}());
+//#endregion
+//#endregion REDUCERS
+// return new, unset BigInteger
+function nbi() { return new BigInteger(null); }
+function parseBigInt(str, r) {
+    return new BigInteger(str, r);
+}
+// am: Compute w_j += (x*this_i), propagate carries,
+// c is initial carry, returns final carry.
+// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+// We need to select the fastest one that works in this environment.
+// am1: use a single mult and divide to get the high bits,
+// max digit bits should be 26 because
+// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+function am1(i, x, w, j, c, n) {
+    while (--n >= 0) {
+        var v = x * this[i++] + w[j] + c;
+        c = Math.floor(v / 0x4000000);
+        w[j++] = v & 0x3ffffff;
+    }
+    return c;
+}
+// am2 avoids a big mult-and-extract completely.
+// Max digit bits should be <= 30 because we do bitwise ops
+// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+function am2(i, x, w, j, c, n) {
+    var xl = x & 0x7fff;
+    var xh = x >> 15;
+    while (--n >= 0) {
+        var l = this[i] & 0x7fff;
+        var h = this[i++] >> 15;
+        var m = xh * l + h * xl;
+        l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
+        c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
+        w[j++] = l & 0x3fffffff;
+    }
+    return c;
+}
+// Alternately, set max digit bits to 28 since some
+// browsers slow down when dealing with 32-bit numbers.
+function am3(i, x, w, j, c, n) {
+    var xl = x & 0x3fff;
+    var xh = x >> 14;
+    while (--n >= 0) {
+        var l = this[i] & 0x3fff;
+        var h = this[i++] >> 14;
+        var m = xh * l + h * xl;
+        l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
+        c = (l >> 28) + (m >> 14) + xh * h;
+        w[j++] = l & 0xfffffff;
+    }
+    return c;
+}
+// if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+//     BigInteger.prototype.am = am2;
+//     dbits = 30;
+// }
+// else if (j_lm && (navigator.appName != "Netscape")) {
+//     BigInteger.prototype.am = am1;
+//     dbits = 26;
+// }
+// else { // Mozilla/Netscape seems to prefer am3
+//     BigInteger.prototype.am = am3;
+//     dbits = 28;
+// }
+BigInteger.prototype.am = am1;
+dbits = 26;
+
+BigInteger.prototype.DB = dbits;
+BigInteger.prototype.DM = ((1 << dbits) - 1);
+BigInteger.prototype.DV = (1 << dbits);
+var BI_FP = 52;
+BigInteger.prototype.FV = Math.pow(2, BI_FP);
+BigInteger.prototype.F1 = BI_FP - dbits;
+BigInteger.prototype.F2 = 2 * dbits - BI_FP;
+// Digit conversions
+var BI_RC = [];
+var rr;
+var vv;
+rr = "0".charCodeAt(0);
+for (vv = 0; vv <= 9; ++vv) {
+    BI_RC[rr++] = vv;
+}
+rr = "a".charCodeAt(0);
+for (vv = 10; vv < 36; ++vv) {
+    BI_RC[rr++] = vv;
+}
+rr = "A".charCodeAt(0);
+for (vv = 10; vv < 36; ++vv) {
+    BI_RC[rr++] = vv;
+}
+function intAt(s, i) {
+    var c = BI_RC[s.charCodeAt(i)];
+    return (c == null) ? -1 : c;
+}
+// return bigint initialized to value
+function nbv(i) {
+    var r = nbi();
+    r.fromInt(i);
+    return r;
+}
+// returns bit length of the integer x
+function nbits(x) {
+    var r = 1;
+    var t;
+    if ((t = x >>> 16) != 0) {
+        x = t;
+        r += 16;
+    }
+    if ((t = x >> 8) != 0) {
+        x = t;
+        r += 8;
+    }
+    if ((t = x >> 4) != 0) {
+        x = t;
+        r += 4;
+    }
+    if ((t = x >> 2) != 0) {
+        x = t;
+        r += 2;
+    }
+    if ((t = x >> 1) != 0) {
+        x = t;
+        r += 1;
+    }
+    return r;
+}
+// "constants"
+BigInteger.ZERO = nbv(0);
+BigInteger.ONE = nbv(1);
+
+// prng4.js - uses Arcfour as a PRNG
+var Arcfour = /** @class */ (function () {
+    function Arcfour() {
+        this.i = 0;
+        this.j = 0;
+        this.S = [];
+    }
+    // Arcfour.prototype.init = ARC4init;
+    // Initialize arcfour context from key, an array of ints, each from [0..255]
+    Arcfour.prototype.init = function (key) {
+        var i;
+        var j;
+        var t;
+        for (i = 0; i < 256; ++i) {
+            this.S[i] = i;
+        }
+        j = 0;
+        for (i = 0; i < 256; ++i) {
+            j = (j + this.S[i] + key[i % key.length]) & 255;
+            t = this.S[i];
+            this.S[i] = this.S[j];
+            this.S[j] = t;
+        }
+        this.i = 0;
+        this.j = 0;
+    };
+    // Arcfour.prototype.next = ARC4next;
+    Arcfour.prototype.next = function () {
+        var t;
+        this.i = (this.i + 1) & 255;
+        this.j = (this.j + this.S[this.i]) & 255;
+        t = this.S[this.i];
+        this.S[this.i] = this.S[this.j];
+        this.S[this.j] = t;
+        return this.S[(t + this.S[this.i]) & 255];
+    };
+    return Arcfour;
+}());
+// Plug in your RNG constructor here
+function prng_newstate() {
+    return new Arcfour();
+}
+// Pool size must be a multiple of 4 and greater than 32.
+// An array of bytes the size of the pool will be passed to init()
+var rng_psize = 256;
+
+// Random number generator - requires a PRNG backend, e.g. prng4.js
+var rng_state;
+var rng_pool = null;
+var rng_pptr;
+// Initialize the pool with junk if needed.
+if (rng_pool == null) {
+    rng_pool = [];
+    rng_pptr = 0;
+    var t = void 0;
+    if (window.crypto && window.crypto.getRandomValues) {
+        // Extract entropy (2048 bits) from RNG if available
+        var z = new Uint32Array(256);
+        window.crypto.getRandomValues(z);
+        for (t = 0; t < z.length; ++t) {
+            rng_pool[rng_pptr++] = z[t] & 255;
+        }
+    }
+    // Use mouse events for entropy, if we do not have enough entropy by the time
+    // we need it, entropy will be generated by Math.random.
+    var onMouseMoveListener_1 = function (ev) {
+        this.count = this.count || 0;
+        if (this.count >= 256 || rng_pptr >= rng_psize) {
+            if (window.removeEventListener) {
+                window.removeEventListener("mousemove", onMouseMoveListener_1, false);
+            }
+            else if (window.detachEvent) {
+                window.detachEvent("onmousemove", onMouseMoveListener_1);
+            }
+            return;
+        }
+        try {
+            var mouseCoordinates = ev.x + ev.y;
+            rng_pool[rng_pptr++] = mouseCoordinates & 255;
+            this.count += 1;
+        }
+        catch (e) {
+            // Sometimes Firefox will deny permission to access event properties for some reason. Ignore.
+        }
+    };
+    if (window.addEventListener) {
+        window.addEventListener("mousemove", onMouseMoveListener_1, false);
+    }
+    else if (window.attachEvent) {
+        window.attachEvent("onmousemove", onMouseMoveListener_1);
+    }
+}
+function rng_get_byte() {
+    if (rng_state == null) {
+        rng_state = prng_newstate();
+        // At this point, we may not have collected enough entropy.  If not, fall back to Math.random
+        while (rng_pptr < rng_psize) {
+            var random = Math.floor(65536 * Math.random());
+            rng_pool[rng_pptr++] = random & 255;
+        }
+        rng_state.init(rng_pool);
+        for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) {
+            rng_pool[rng_pptr] = 0;
+        }
+        rng_pptr = 0;
+    }
+    // TODO: allow reseeding after first request
+    return rng_state.next();
+}
+var SecureRandom = /** @class */ (function () {
+    function SecureRandom() {
+    }
+    SecureRandom.prototype.nextBytes = function (ba) {
+        for (var i = 0; i < ba.length; ++i) {
+            ba[i] = rng_get_byte();
+        }
+    };
+    return SecureRandom;
+}());
+
+// Depends on jsbn.js and rng.js
+// function linebrk(s,n) {
+//   var ret = "";
+//   var i = 0;
+//   while(i + n < s.length) {
+//     ret += s.substring(i,i+n) + "\n";
+//     i += n;
+//   }
+//   return ret + s.substring(i,s.length);
+// }
+// function byte2Hex(b) {
+//   if(b < 0x10)
+//     return "0" + b.toString(16);
+//   else
+//     return b.toString(16);
+// }
+function pkcs1pad1(s, n) {
+    if (n < s.length + 22) {
+        console.error("Message too long for RSA");
+        return null;
+    }
+    var len = n - s.length - 6;
+    var filler = "";
+    for (var f = 0; f < len; f += 2) {
+        filler += "ff";
+    }
+    var m = "0001" + filler + "00" + s;
+    return parseBigInt(m, 16);
+}
+// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
+function pkcs1pad2(s, n) {
+    if (n < s.length + 11) { // TODO: fix for utf-8
+        console.error("Message too long for RSA");
+        return null;
+    }
+    var ba = [];
+    var i = s.length - 1;
+    while (i >= 0 && n > 0) {
+        var c = s.charCodeAt(i--);
+        if (c < 128) { // encode using utf-8
+            ba[--n] = c;
+        }
+        else if ((c > 127) && (c < 2048)) {
+            ba[--n] = (c & 63) | 128;
+            ba[--n] = (c >> 6) | 192;
+        }
+        else {
+            ba[--n] = (c & 63) | 128;
+            ba[--n] = ((c >> 6) & 63) | 128;
+            ba[--n] = (c >> 12) | 224;
+        }
+    }
+    ba[--n] = 0;
+    var rng = new SecureRandom();
+    var x = [];
+    while (n > 2) { // random non-zero pad
+        x[0] = 0;
+        while (x[0] == 0) {
+            rng.nextBytes(x);
+        }
+        ba[--n] = x[0];
+    }
+    ba[--n] = 2;
+    ba[--n] = 0;
+    return new BigInteger(ba);
+}
+// "empty" RSA key constructor
+var RSAKey = /** @class */ (function () {
+    function RSAKey() {
+        this.n = null;
+        this.e = 0;
+        this.d = null;
+        this.p = null;
+        this.q = null;
+        this.dmp1 = null;
+        this.dmq1 = null;
+        this.coeff = null;
+    }
+    //#region PROTECTED
+    // protected
+    // RSAKey.prototype.doPublic = RSADoPublic;
+    // Perform raw public operation on "x": return x^e (mod n)
+    RSAKey.prototype.doPublic = function (x) {
+        return x.modPowInt(this.e, this.n);
+    };
+    // RSAKey.prototype.doPrivate = RSADoPrivate;
+    // Perform raw private operation on "x": return x^d (mod n)
+    RSAKey.prototype.doPrivate = function (x) {
+        if (this.p == null || this.q == null) {
+            return x.modPow(this.d, this.n);
+        }
+        // TODO: re-calculate any missing CRT params
+        var xp = x.mod(this.p).modPow(this.dmp1, this.p);
+        var xq = x.mod(this.q).modPow(this.dmq1, this.q);
+        while (xp.compareTo(xq) < 0) {
+            xp = xp.add(this.p);
+        }
+        return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
+    };
+    //#endregion PROTECTED
+    //#region PUBLIC
+    // RSAKey.prototype.setPublic = RSASetPublic;
+    // Set the public key fields N and e from hex strings
+    RSAKey.prototype.setPublic = function (N, E) {
+        if (N != null && E != null && N.length > 0 && E.length > 0) {
+            this.n = parseBigInt(N, 16);
+            this.e = parseInt(E, 16);
+        }
+        else {
+            console.error("Invalid RSA public key");
+        }
+    };
+    // RSAKey.prototype.encrypt = RSAEncrypt;
+    // Return the PKCS#1 RSA encryption of "text" as an even-length hex string
+    RSAKey.prototype.encrypt = function (text) {
+        var m = pkcs1pad2(text, (this.n.bitLength() + 7) >> 3);
+        if (m == null) {
+            return null;
+        }
+        var c = this.doPublic(m);
+        if (c == null) {
+            return null;
+        }
+        var h = c.toString(16);
+        if ((h.length & 1) == 0) {
+            return h;
+        }
+        else {
+            return "0" + h;
+        }
+    };
+    // RSAKey.prototype.setPrivate = RSASetPrivate;
+    // Set the private key fields N, e, and d from hex strings
+    RSAKey.prototype.setPrivate = function (N, E, D) {
+        if (N != null && E != null && N.length > 0 && E.length > 0) {
+            this.n = parseBigInt(N, 16);
+            this.e = parseInt(E, 16);
+            this.d = parseBigInt(D, 16);
+        }
+        else {
+            console.error("Invalid RSA private key");
+        }
+    };
+    // RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
+    // Set the private key fields N, e, d and CRT params from hex strings
+    RSAKey.prototype.setPrivateEx = function (N, E, D, P, Q, DP, DQ, C) {
+        if (N != null && E != null && N.length > 0 && E.length > 0) {
+            this.n = parseBigInt(N, 16);
+            this.e = parseInt(E, 16);
+            this.d = parseBigInt(D, 16);
+            this.p = parseBigInt(P, 16);
+            this.q = parseBigInt(Q, 16);
+            this.dmp1 = parseBigInt(DP, 16);
+            this.dmq1 = parseBigInt(DQ, 16);
+            this.coeff = parseBigInt(C, 16);
+        }
+        else {
+            console.error("Invalid RSA private key");
+        }
+    };
+    // RSAKey.prototype.generate = RSAGenerate;
+    // Generate a new random private key B bits long, using public expt E
+    RSAKey.prototype.generate = function (B, E) {
+        var rng = new SecureRandom();
+        var qs = B >> 1;
+        this.e = parseInt(E, 16);
+        var ee = new BigInteger(E, 16);
+        for (;;) {
+            for (;;) {
+                this.p = new BigInteger(B - qs, 1, rng);
+                if (this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) {
+                    break;
+                }
+            }
+            for (;;) {
+                this.q = new BigInteger(qs, 1, rng);
+                if (this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) {
+                    break;
+                }
+            }
+            if (this.p.compareTo(this.q) <= 0) {
+                var t = this.p;
+                this.p = this.q;
+                this.q = t;
+            }
+            var p1 = this.p.subtract(BigInteger.ONE);
+            var q1 = this.q.subtract(BigInteger.ONE);
+            var phi = p1.multiply(q1);
+            if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
+                this.n = this.p.multiply(this.q);
+                this.d = ee.modInverse(phi);
+                this.dmp1 = this.d.mod(p1);
+                this.dmq1 = this.d.mod(q1);
+                this.coeff = this.q.modInverse(this.p);
+                break;
+            }
+        }
+    };
+    // RSAKey.prototype.decrypt = RSADecrypt;
+    // Return the PKCS#1 RSA decryption of "ctext".
+    // "ctext" is an even-length hex string and the output is a plain string.
+    RSAKey.prototype.decrypt = function (ctext) {
+        var c = parseBigInt(ctext, 16);
+        var m = this.doPrivate(c);
+        if (m == null) {
+            return null;
+        }
+        return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3);
+    };
+    // Generate a new random private key B bits long, using public expt E
+    RSAKey.prototype.generateAsync = function (B, E, callback) {
+        var rng = new SecureRandom();
+        var qs = B >> 1;
+        this.e = parseInt(E, 16);
+        var ee = new BigInteger(E, 16);
+        var rsa = this;
+        // These functions have non-descript names because they were originally for(;;) loops.
+        // I don't know about cryptography to give them better names than loop1-4.
+        var loop1 = function () {
+            var loop4 = function () {
+                if (rsa.p.compareTo(rsa.q) <= 0) {
+                    var t = rsa.p;
+                    rsa.p = rsa.q;
+                    rsa.q = t;
+                }
+                var p1 = rsa.p.subtract(BigInteger.ONE);
+                var q1 = rsa.q.subtract(BigInteger.ONE);
+                var phi = p1.multiply(q1);
+                if (phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
+                    rsa.n = rsa.p.multiply(rsa.q);
+                    rsa.d = ee.modInverse(phi);
+                    rsa.dmp1 = rsa.d.mod(p1);
+                    rsa.dmq1 = rsa.d.mod(q1);
+                    rsa.coeff = rsa.q.modInverse(rsa.p);
+                    setTimeout(function () { callback(); }, 0); // escape
+                }
+                else {
+                    setTimeout(loop1, 0);
+                }
+            };
+            var loop3 = function () {
+                rsa.q = nbi();
+                rsa.q.fromNumberAsync(qs, 1, rng, function () {
+                    rsa.q.subtract(BigInteger.ONE).gcda(ee, function (r) {
+                        if (r.compareTo(BigInteger.ONE) == 0 && rsa.q.isProbablePrime(10)) {
+                            setTimeout(loop4, 0);
+                        }
+                        else {
+                            setTimeout(loop3, 0);
+                        }
+                    });
+                });
+            };
+            var loop2 = function () {
+                rsa.p = nbi();
+                rsa.p.fromNumberAsync(B - qs, 1, rng, function () {
+                    rsa.p.subtract(BigInteger.ONE).gcda(ee, function (r) {
+                        if (r.compareTo(BigInteger.ONE) == 0 && rsa.p.isProbablePrime(10)) {
+                            setTimeout(loop3, 0);
+                        }
+                        else {
+                            setTimeout(loop2, 0);
+                        }
+                    });
+                });
+            };
+            setTimeout(loop2, 0);
+        };
+        setTimeout(loop1, 0);
+    };
+    RSAKey.prototype.sign = function (text, digestMethod, digestName) {
+        var header = getDigestHeader(digestName);
+        var digest = header + digestMethod(text).toString();
+        var m = pkcs1pad1(digest, this.n.bitLength() / 4);
+        if (m == null) {
+            return null;
+        }
+        var c = this.doPrivate(m);
+        if (c == null) {
+            return null;
+        }
+        var h = c.toString(16);
+        if ((h.length & 1) == 0) {
+            return h;
+        }
+        else {
+            return "0" + h;
+        }
+    };
+    RSAKey.prototype.verify = function (text, signature, digestMethod) {
+        var c = parseBigInt(signature, 16);
+        var m = this.doPublic(c);
+        if (m == null) {
+            return null;
+        }
+        var unpadded = m.toString(16).replace(/^1f+00/, "");
+        var digest = removeDigestHeader(unpadded);
+        return digest == digestMethod(text).toString();
+    };
+    return RSAKey;
+}());
+// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
+function pkcs1unpad2(d, n) {
+    var b = d.toByteArray();
+    var i = 0;
+    while (i < b.length && b[i] == 0) {
+        ++i;
+    }
+    if (b.length - i != n - 1 || b[i] != 2) {
+        return null;
+    }
+    ++i;
+    while (b[i] != 0) {
+        if (++i >= b.length) {
+            return null;
+        }
+    }
+    var ret = "";
+    while (++i < b.length) {
+        var c = b[i] & 255;
+        if (c < 128) { // utf-8 decode
+            ret += String.fromCharCode(c);
+        }
+        else if ((c > 191) && (c < 224)) {
+            ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63));
+            ++i;
+        }
+        else {
+            ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63));
+            i += 2;
+        }
+    }
+    return ret;
+}
+// https://tools.ietf.org/html/rfc3447#page-43
+var DIGEST_HEADERS = {
+    md2: "3020300c06082a864886f70d020205000410",
+    md5: "3020300c06082a864886f70d020505000410",
+    sha1: "3021300906052b0e03021a05000414",
+    sha224: "302d300d06096086480165030402040500041c",
+    sha256: "3031300d060960864801650304020105000420",
+    sha384: "3041300d060960864801650304020205000430",
+    sha512: "3051300d060960864801650304020305000440",
+    ripemd160: "3021300906052b2403020105000414",
+};
+function getDigestHeader(name) {
+    return DIGEST_HEADERS[name] || "";
+}
+function removeDigestHeader(str) {
+    for (var name_1 in DIGEST_HEADERS) {
+        if (DIGEST_HEADERS.hasOwnProperty(name_1)) {
+            var header = DIGEST_HEADERS[name_1];
+            var len = header.length;
+            if (str.substr(0, len) == header) {
+                return str.substr(len);
+            }
+        }
+    }
+    return str;
+}
+// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
+// function RSAEncryptB64(text) {
+//  var h = this.encrypt(text);
+//  if(h) return hex2b64(h); else return null;
+// }
+// public
+// RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
+
+/*!
+Copyright (c) 2011, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.html
+version: 2.9.0
+*/
+var YAHOO = {};
+YAHOO.lang = {
+    /**
+     * Utility to set up the prototype, constructor and superclass properties to
+     * support an inheritance strategy that can chain constructors and methods.
+     * Static members will not be inherited.
+     *
+     * @method extend
+     * @static
+     * @param {Function} subc   the object to modify
+     * @param {Function} superc the object to inherit
+     * @param {Object} overrides  additional properties/methods to add to the
+     *                              subclass prototype.  These will override the
+     *                              matching items obtained from the superclass
+     *                              if present.
+     */
+    extend: function(subc, superc, overrides) {
+        if (! superc || ! subc) {
+            throw new Error("YAHOO.lang.extend failed, please check that " +
+                "all dependencies are included.");
+        }
+
+        var F = function() {};
+        F.prototype = superc.prototype;
+        subc.prototype = new F();
+        subc.prototype.constructor = subc;
+        subc.superclass = superc.prototype;
+
+        if (superc.prototype.constructor == Object.prototype.constructor) {
+            superc.prototype.constructor = superc;
+        }
+
+        if (overrides) {
+            var i;
+            for (i in overrides) {
+                subc.prototype[i] = overrides[i];
+            }
+
+            /*
+             * IE will not enumerate native functions in a derived object even if the
+             * function was overridden.  This is a workaround for specific functions
+             * we care about on the Object prototype.
+             * @property _IEEnumFix
+             * @param {Function} r  the object to receive the augmentation
+             * @param {Function} s  the object that supplies the properties to augment
+             * @static
+             * @private
+             */
+            var _IEEnumFix = function() {},
+                ADD = ["toString", "valueOf"];
+            try {
+                if (/MSIE/.test(navigator.userAgent)) {
+                    _IEEnumFix = function(r, s) {
+                        for (i = 0; i < ADD.length; i = i + 1) {
+                            var fname = ADD[i], f = s[fname];
+                            if (typeof f === 'function' && f != Object.prototype[fname]) {
+                                r[fname] = f;
+                            }
+                        }
+                    };
+                }
+            } catch (ex) {}            _IEEnumFix(subc.prototype, overrides);
+        }
+    }
+};
+
+/* asn1-1.0.13.js (c) 2013-2017 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+
+/**
+ * @fileOverview
+ * @name asn1-1.0.js
+ * @author Kenji Urushima kenji.urushima@gmail.com
+ * @version asn1 1.0.13 (2017-Jun-02)
+ * @since jsrsasign 2.1
+ * @license <a href="https://kjur.github.io/jsrsasign/license/">MIT License</a>
+ */
+
+/**
+ * kjur's class library name space
+ * <p>
+ * This name space provides following name spaces:
+ * <ul>
+ * <li>{@link KJUR.asn1} - ASN.1 primitive hexadecimal encoder</li>
+ * <li>{@link KJUR.asn1.x509} - ASN.1 structure for X.509 certificate and CRL</li>
+ * <li>{@link KJUR.crypto} - Java Cryptographic Extension(JCE) style MessageDigest/Signature
+ * class and utilities</li>
+ * </ul>
+ * </p>
+ * NOTE: Please ignore method summary and document of this namespace. This caused by a bug of jsdoc2.
+ * @name KJUR
+ * @namespace kjur's class library name space
+ */
+var KJUR = {};
+
+/**
+ * kjur's ASN.1 class library name space
+ * <p>
+ * This is ITU-T X.690 ASN.1 DER encoder class library and
+ * class structure and methods is very similar to
+ * org.bouncycastle.asn1 package of
+ * well known BouncyCaslte Cryptography Library.
+ * <h4>PROVIDING ASN.1 PRIMITIVES</h4>
+ * Here are ASN.1 DER primitive classes.
+ * <ul>
+ * <li>0x01 {@link KJUR.asn1.DERBoolean}</li>
+ * <li>0x02 {@link KJUR.asn1.DERInteger}</li>
+ * <li>0x03 {@link KJUR.asn1.DERBitString}</li>
+ * <li>0x04 {@link KJUR.asn1.DEROctetString}</li>
+ * <li>0x05 {@link KJUR.asn1.DERNull}</li>
+ * <li>0x06 {@link KJUR.asn1.DERObjectIdentifier}</li>
+ * <li>0x0a {@link KJUR.asn1.DEREnumerated}</li>
+ * <li>0x0c {@link KJUR.asn1.DERUTF8String}</li>
+ * <li>0x12 {@link KJUR.asn1.DERNumericString}</li>
+ * <li>0x13 {@link KJUR.asn1.DERPrintableString}</li>
+ * <li>0x14 {@link KJUR.asn1.DERTeletexString}</li>
+ * <li>0x16 {@link KJUR.asn1.DERIA5String}</li>
+ * <li>0x17 {@link KJUR.asn1.DERUTCTime}</li>
+ * <li>0x18 {@link KJUR.asn1.DERGeneralizedTime}</li>
+ * <li>0x30 {@link KJUR.asn1.DERSequence}</li>
+ * <li>0x31 {@link KJUR.asn1.DERSet}</li>
+ * </ul>
+ * <h4>OTHER ASN.1 CLASSES</h4>
+ * <ul>
+ * <li>{@link KJUR.asn1.ASN1Object}</li>
+ * <li>{@link KJUR.asn1.DERAbstractString}</li>
+ * <li>{@link KJUR.asn1.DERAbstractTime}</li>
+ * <li>{@link KJUR.asn1.DERAbstractStructured}</li>
+ * <li>{@link KJUR.asn1.DERTaggedObject}</li>
+ * </ul>
+ * <h4>SUB NAME SPACES</h4>
+ * <ul>
+ * <li>{@link KJUR.asn1.cades} - CAdES long term signature format</li>
+ * <li>{@link KJUR.asn1.cms} - Cryptographic Message Syntax</li>
+ * <li>{@link KJUR.asn1.csr} - Certificate Signing Request (CSR/PKCS#10)</li>
+ * <li>{@link KJUR.asn1.tsp} - RFC 3161 Timestamping Protocol Format</li>
+ * <li>{@link KJUR.asn1.x509} - RFC 5280 X.509 certificate and CRL</li>
+ * </ul>
+ * </p>
+ * NOTE: Please ignore method summary and document of this namespace.
+ * This caused by a bug of jsdoc2.
+ * @name KJUR.asn1
+ * @namespace
+ */
+if (typeof KJUR.asn1 == "undefined" || !KJUR.asn1) KJUR.asn1 = {};
+
+/**
+ * ASN1 utilities class
+ * @name KJUR.asn1.ASN1Util
+ * @class ASN1 utilities class
+ * @since asn1 1.0.2
+ */
+KJUR.asn1.ASN1Util = new function() {
+    this.integerToByteHex = function(i) {
+        var h = i.toString(16);
+        if ((h.length % 2) == 1) h = '0' + h;
+        return h;
+    };
+    this.bigIntToMinTwosComplementsHex = function(bigIntegerValue) {
+        var h = bigIntegerValue.toString(16);
+        if (h.substr(0, 1) != '-') {
+            if (h.length % 2 == 1) {
+                h = '0' + h;
+            } else {
+                if (! h.match(/^[0-7]/)) {
+                    h = '00' + h;
+                }
+            }
+        } else {
+            var hPos = h.substr(1);
+            var xorLen = hPos.length;
+            if (xorLen % 2 == 1) {
+                xorLen += 1;
+            } else {
+                if (! h.match(/^[0-7]/)) {
+                    xorLen += 2;
+                }
+            }
+            var hMask = '';
+            for (var i = 0; i < xorLen; i++) {
+                hMask += 'f';
+            }
+            var biMask = new BigInteger(hMask, 16);
+            var biNeg = biMask.xor(bigIntegerValue).add(BigInteger.ONE);
+            h = biNeg.toString(16).replace(/^-/, '');
+        }
+        return h;
+    };
+    /**
+     * get PEM string from hexadecimal data and header string
+     * @name getPEMStringFromHex
+     * @memberOf KJUR.asn1.ASN1Util
+     * @function
+     * @param {String} dataHex hexadecimal string of PEM body
+     * @param {String} pemHeader PEM header string (ex. 'RSA PRIVATE KEY')
+     * @return {String} PEM formatted string of input data
+     * @description
+     * This method converts a hexadecimal string to a PEM string with
+     * a specified header. Its line break will be CRLF("\r\n").
+     * @example
+     * var pem  = KJUR.asn1.ASN1Util.getPEMStringFromHex('616161', 'RSA PRIVATE KEY');
+     * // value of pem will be:
+     * -----BEGIN PRIVATE KEY-----
+     * YWFh
+     * -----END PRIVATE KEY-----
+     */
+    this.getPEMStringFromHex = function(dataHex, pemHeader) {
+        return hextopem(dataHex, pemHeader);
+    };
+
+    /**
+     * generate ASN1Object specifed by JSON parameters
+     * @name newObject
+     * @memberOf KJUR.asn1.ASN1Util
+     * @function
+     * @param {Array} param JSON parameter to generate ASN1Object
+     * @return {KJUR.asn1.ASN1Object} generated object
+     * @since asn1 1.0.3
+     * @description
+     * generate any ASN1Object specified by JSON param
+     * including ASN.1 primitive or structured.
+     * Generally 'param' can be described as follows:
+     * <blockquote>
+     * {TYPE-OF-ASNOBJ: ASN1OBJ-PARAMETER}
+     * </blockquote>
+     * 'TYPE-OF-ASN1OBJ' can be one of following symbols:
+     * <ul>
+     * <li>'bool' - DERBoolean</li>
+     * <li>'int' - DERInteger</li>
+     * <li>'bitstr' - DERBitString</li>
+     * <li>'octstr' - DEROctetString</li>
+     * <li>'null' - DERNull</li>
+     * <li>'oid' - DERObjectIdentifier</li>
+     * <li>'enum' - DEREnumerated</li>
+     * <li>'utf8str' - DERUTF8String</li>
+     * <li>'numstr' - DERNumericString</li>
+     * <li>'prnstr' - DERPrintableString</li>
+     * <li>'telstr' - DERTeletexString</li>
+     * <li>'ia5str' - DERIA5String</li>
+     * <li>'utctime' - DERUTCTime</li>
+     * <li>'gentime' - DERGeneralizedTime</li>
+     * <li>'seq' - DERSequence</li>
+     * <li>'set' - DERSet</li>
+     * <li>'tag' - DERTaggedObject</li>
+     * </ul>
+     * @example
+     * newObject({'prnstr': 'aaa'});
+     * newObject({'seq': [{'int': 3}, {'prnstr': 'aaa'}]})
+     * // ASN.1 Tagged Object
+     * newObject({'tag': {'tag': 'a1',
+     *                    'explicit': true,
+     *                    'obj': {'seq': [{'int': 3}, {'prnstr': 'aaa'}]}}});
+     * // more simple representation of ASN.1 Tagged Object
+     * newObject({'tag': ['a1',
+     *                    true,
+     *                    {'seq': [
+     *                      {'int': 3},
+     *                      {'prnstr': 'aaa'}]}
+     *                   ]});
+     */
+    this.newObject = function(param) {
+        var _KJUR = KJUR,
+            _KJUR_asn1 = _KJUR.asn1,
+            _DERBoolean = _KJUR_asn1.DERBoolean,
+            _DERInteger = _KJUR_asn1.DERInteger,
+            _DERBitString = _KJUR_asn1.DERBitString,
+            _DEROctetString = _KJUR_asn1.DEROctetString,
+            _DERNull = _KJUR_asn1.DERNull,
+            _DERObjectIdentifier = _KJUR_asn1.DERObjectIdentifier,
+            _DEREnumerated = _KJUR_asn1.DEREnumerated,
+            _DERUTF8String = _KJUR_asn1.DERUTF8String,
+            _DERNumericString = _KJUR_asn1.DERNumericString,
+            _DERPrintableString = _KJUR_asn1.DERPrintableString,
+            _DERTeletexString = _KJUR_asn1.DERTeletexString,
+            _DERIA5String = _KJUR_asn1.DERIA5String,
+            _DERUTCTime = _KJUR_asn1.DERUTCTime,
+            _DERGeneralizedTime = _KJUR_asn1.DERGeneralizedTime,
+            _DERSequence = _KJUR_asn1.DERSequence,
+            _DERSet = _KJUR_asn1.DERSet,
+            _DERTaggedObject = _KJUR_asn1.DERTaggedObject,
+            _newObject = _KJUR_asn1.ASN1Util.newObject;
+
+        var keys = Object.keys(param);
+        if (keys.length != 1)
+            throw "key of param shall be only one.";
+        var key = keys[0];
+
+        if (":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:".indexOf(":" + key + ":") == -1)
+            throw "undefined key: " + key;
+
+        if (key == "bool")    return new _DERBoolean(param[key]);
+        if (key == "int")     return new _DERInteger(param[key]);
+        if (key == "bitstr")  return new _DERBitString(param[key]);
+        if (key == "octstr")  return new _DEROctetString(param[key]);
+        if (key == "null")    return new _DERNull(param[key]);
+        if (key == "oid")     return new _DERObjectIdentifier(param[key]);
+        if (key == "enum")    return new _DEREnumerated(param[key]);
+        if (key == "utf8str") return new _DERUTF8String(param[key]);
+        if (key == "numstr")  return new _DERNumericString(param[key]);
+        if (key == "prnstr")  return new _DERPrintableString(param[key]);
+        if (key == "telstr")  return new _DERTeletexString(param[key]);
+        if (key == "ia5str")  return new _DERIA5String(param[key]);
+        if (key == "utctime") return new _DERUTCTime(param[key]);
+        if (key == "gentime") return new _DERGeneralizedTime(param[key]);
+
+        if (key == "seq") {
+            var paramList = param[key];
+            var a = [];
+            for (var i = 0; i < paramList.length; i++) {
+                var asn1Obj = _newObject(paramList[i]);
+                a.push(asn1Obj);
+            }
+            return new _DERSequence({'array': a});
+        }
+
+        if (key == "set") {
+            var paramList = param[key];
+            var a = [];
+            for (var i = 0; i < paramList.length; i++) {
+                var asn1Obj = _newObject(paramList[i]);
+                a.push(asn1Obj);
+            }
+            return new _DERSet({'array': a});
+        }
+
+        if (key == "tag") {
+            var tagParam = param[key];
+            if (Object.prototype.toString.call(tagParam) === '[object Array]' &&
+                tagParam.length == 3) {
+                var obj = _newObject(tagParam[2]);
+                return new _DERTaggedObject({tag: tagParam[0],
+                    explicit: tagParam[1],
+                    obj: obj});
+            } else {
+                var newParam = {};
+                if (tagParam.explicit !== undefined)
+                    newParam.explicit = tagParam.explicit;
+                if (tagParam.tag !== undefined)
+                    newParam.tag = tagParam.tag;
+                if (tagParam.obj === undefined)
+                    throw "obj shall be specified for 'tag'.";
+                newParam.obj = _newObject(tagParam.obj);
+                return new _DERTaggedObject(newParam);
+            }
+        }
+    };
+
+    /**
+     * get encoded hexadecimal string of ASN1Object specifed by JSON parameters
+     * @name jsonToASN1HEX
+     * @memberOf KJUR.asn1.ASN1Util
+     * @function
+     * @param {Array} param JSON parameter to generate ASN1Object
+     * @return hexadecimal string of ASN1Object
+     * @since asn1 1.0.4
+     * @description
+     * As for ASN.1 object representation of JSON object,
+     * please see {@link newObject}.
+     * @example
+     * jsonToASN1HEX({'prnstr': 'aaa'});
+     */
+    this.jsonToASN1HEX = function(param) {
+        var asn1Obj = this.newObject(param);
+        return asn1Obj.getEncodedHex();
+    };
+};
+
+/**
+ * get dot noted oid number string from hexadecimal value of OID
+ * @name oidHexToInt
+ * @memberOf KJUR.asn1.ASN1Util
+ * @function
+ * @param {String} hex hexadecimal value of object identifier
+ * @return {String} dot noted string of object identifier
+ * @since jsrsasign 4.8.3 asn1 1.0.7
+ * @description
+ * This static method converts from hexadecimal string representation of
+ * ASN.1 value of object identifier to oid number string.
+ * @example
+ * KJUR.asn1.ASN1Util.oidHexToInt('550406') &rarr; "2.5.4.6"
+ */
+KJUR.asn1.ASN1Util.oidHexToInt = function(hex) {
+    var s = "";
+    var i01 = parseInt(hex.substr(0, 2), 16);
+    var i0 = Math.floor(i01 / 40);
+    var i1 = i01 % 40;
+    var s = i0 + "." + i1;
+
+    var binbuf = "";
+    for (var i = 2; i < hex.length; i += 2) {
+        var value = parseInt(hex.substr(i, 2), 16);
+        var bin = ("00000000" + value.toString(2)).slice(- 8);
+        binbuf = binbuf + bin.substr(1, 7);
+        if (bin.substr(0, 1) == "0") {
+            var bi = new BigInteger(binbuf, 2);
+            s = s + "." + bi.toString(10);
+            binbuf = "";
+        }
+    }
+    return s;
+};
+
+/**
+ * get hexadecimal value of object identifier from dot noted oid value
+ * @name oidIntToHex
+ * @memberOf KJUR.asn1.ASN1Util
+ * @function
+ * @param {String} oidString dot noted string of object identifier
+ * @return {String} hexadecimal value of object identifier
+ * @since jsrsasign 4.8.3 asn1 1.0.7
+ * @description
+ * This static method converts from object identifier value string.
+ * to hexadecimal string representation of it.
+ * @example
+ * KJUR.asn1.ASN1Util.oidIntToHex("2.5.4.6") &rarr; "550406"
+ */
+KJUR.asn1.ASN1Util.oidIntToHex = function(oidString) {
+    var itox = function(i) {
+        var h = i.toString(16);
+        if (h.length == 1) h = '0' + h;
+        return h;
+    };
+
+    var roidtox = function(roid) {
+        var h = '';
+        var bi = new BigInteger(roid, 10);
+        var b = bi.toString(2);
+        var padLen = 7 - b.length % 7;
+        if (padLen == 7) padLen = 0;
+        var bPad = '';
+        for (var i = 0; i < padLen; i++) bPad += '0';
+        b = bPad + b;
+        for (var i = 0; i < b.length - 1; i += 7) {
+            var b8 = b.substr(i, 7);
+            if (i != b.length - 7) b8 = '1' + b8;
+            h += itox(parseInt(b8, 2));
+        }
+        return h;
+    };
+
+    if (! oidString.match(/^[0-9.]+$/)) {
+        throw "malformed oid string: " + oidString;
+    }
+    var h = '';
+    var a = oidString.split('.');
+    var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
+    h += itox(i0);
+    a.splice(0, 2);
+    for (var i = 0; i < a.length; i++) {
+        h += roidtox(a[i]);
+    }
+    return h;
+};
+
+
+// ********************************************************************
+//  Abstract ASN.1 Classes
+// ********************************************************************
+
+// ********************************************************************
+
+/**
+ * base class for ASN.1 DER encoder object
+ * @name KJUR.asn1.ASN1Object
+ * @class base class for ASN.1 DER encoder object
+ * @property {Boolean} isModified flag whether internal data was changed
+ * @property {String} hTLV hexadecimal string of ASN.1 TLV
+ * @property {String} hT hexadecimal string of ASN.1 TLV tag(T)
+ * @property {String} hL hexadecimal string of ASN.1 TLV length(L)
+ * @property {String} hV hexadecimal string of ASN.1 TLV value(V)
+ * @description
+ */
+KJUR.asn1.ASN1Object = function() {
+    var hV = '';
+
+    /**
+     * get hexadecimal ASN.1 TLV length(L) bytes from TLV value(V)
+     * @name getLengthHexFromValue
+     * @memberOf KJUR.asn1.ASN1Object#
+     * @function
+     * @return {String} hexadecimal string of ASN.1 TLV length(L)
+     */
+    this.getLengthHexFromValue = function() {
+        if (typeof this.hV == "undefined" || this.hV == null) {
+            throw "this.hV is null or undefined.";
+        }
+        if (this.hV.length % 2 == 1) {
+            throw "value hex must be even length: n=" + hV.length + ",v=" + this.hV;
+        }
+        var n = this.hV.length / 2;
+        var hN = n.toString(16);
+        if (hN.length % 2 == 1) {
+            hN = "0" + hN;
+        }
+        if (n < 128) {
+            return hN;
+        } else {
+            var hNlen = hN.length / 2;
+            if (hNlen > 15) {
+                throw "ASN.1 length too long to represent by 8x: n = " + n.toString(16);
+            }
+            var head = 128 + hNlen;
+            return head.toString(16) + hN;
+        }
+    };
+
+    /**
+     * get hexadecimal string of ASN.1 TLV bytes
+     * @name getEncodedHex
+     * @memberOf KJUR.asn1.ASN1Object#
+     * @function
+     * @return {String} hexadecimal string of ASN.1 TLV
+     */
+    this.getEncodedHex = function() {
+        if (this.hTLV == null || this.isModified) {
+            this.hV = this.getFreshValueHex();
+            this.hL = this.getLengthHexFromValue();
+            this.hTLV = this.hT + this.hL + this.hV;
+            this.isModified = false;
+            //alert("first time: " + this.hTLV);
+        }
+        return this.hTLV;
+    };
+
+    /**
+     * get hexadecimal string of ASN.1 TLV value(V) bytes
+     * @name getValueHex
+     * @memberOf KJUR.asn1.ASN1Object#
+     * @function
+     * @return {String} hexadecimal string of ASN.1 TLV value(V) bytes
+     */
+    this.getValueHex = function() {
+        this.getEncodedHex();
+        return this.hV;
+    };
+
+    this.getFreshValueHex = function() {
+        return '';
+    };
+};
+
+// == BEGIN DERAbstractString ================================================
+/**
+ * base class for ASN.1 DER string classes
+ * @name KJUR.asn1.DERAbstractString
+ * @class base class for ASN.1 DER string classes
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @property {String} s internal string of value
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>str - specify initial ASN.1 value(V) by a string</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ */
+KJUR.asn1.DERAbstractString = function(params) {
+    KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
+
+    /**
+     * get string value of this string object
+     * @name getString
+     * @memberOf KJUR.asn1.DERAbstractString#
+     * @function
+     * @return {String} string value of this string object
+     */
+    this.getString = function() {
+        return this.s;
+    };
+
+    /**
+     * set value by a string
+     * @name setString
+     * @memberOf KJUR.asn1.DERAbstractString#
+     * @function
+     * @param {String} newS value by a string to set
+     */
+    this.setString = function(newS) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = newS;
+        this.hV = stohex(this.s);
+    };
+
+    /**
+     * set value by a hexadecimal string
+     * @name setStringHex
+     * @memberOf KJUR.asn1.DERAbstractString#
+     * @function
+     * @param {String} newHexString value by a hexadecimal string to set
+     */
+    this.setStringHex = function(newHexString) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = null;
+        this.hV = newHexString;
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params == "string") {
+            this.setString(params);
+        } else if (typeof params['str'] != "undefined") {
+            this.setString(params['str']);
+        } else if (typeof params['hex'] != "undefined") {
+            this.setStringHex(params['hex']);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERAbstractString, KJUR.asn1.ASN1Object);
+// == END   DERAbstractString ================================================
+
+// == BEGIN DERAbstractTime ==================================================
+/**
+ * base class for ASN.1 DER Generalized/UTCTime class
+ * @name KJUR.asn1.DERAbstractTime
+ * @class base class for ASN.1 DER Generalized/UTCTime class
+ * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * @see KJUR.asn1.ASN1Object - superclass
+ */
+KJUR.asn1.DERAbstractTime = function(params) {
+    KJUR.asn1.DERAbstractTime.superclass.constructor.call(this);
+
+    // --- PRIVATE METHODS --------------------
+    this.localDateToUTC = function(d) {
+        utc = d.getTime() + (d.getTimezoneOffset() * 60000);
+        var utcDate = new Date(utc);
+        return utcDate;
+    };
+
+    /*
+     * format date string by Data object
+     * @name formatDate
+     * @memberOf KJUR.asn1.AbstractTime;
+     * @param {Date} dateObject
+     * @param {string} type 'utc' or 'gen'
+     * @param {boolean} withMillis flag for with millisections or not
+     * @description
+     * 'withMillis' flag is supported from asn1 1.0.6.
+     */
+    this.formatDate = function(dateObject, type, withMillis) {
+        var pad = this.zeroPadding;
+        var d = this.localDateToUTC(dateObject);
+        var year = String(d.getFullYear());
+        if (type == 'utc') year = year.substr(2, 2);
+        var month = pad(String(d.getMonth() + 1), 2);
+        var day = pad(String(d.getDate()), 2);
+        var hour = pad(String(d.getHours()), 2);
+        var min = pad(String(d.getMinutes()), 2);
+        var sec = pad(String(d.getSeconds()), 2);
+        var s = year + month + day + hour + min + sec;
+        if (withMillis === true) {
+            var millis = d.getMilliseconds();
+            if (millis != 0) {
+                var sMillis = pad(String(millis), 3);
+                sMillis = sMillis.replace(/[0]+$/, "");
+                s = s + "." + sMillis;
+            }
+        }
+        return s + "Z";
+    };
+
+    this.zeroPadding = function(s, len) {
+        if (s.length >= len) return s;
+        return new Array(len - s.length + 1).join('0') + s;
+    };
+
+    // --- PUBLIC METHODS --------------------
+    /**
+     * get string value of this string object
+     * @name getString
+     * @memberOf KJUR.asn1.DERAbstractTime#
+     * @function
+     * @return {String} string value of this time object
+     */
+    this.getString = function() {
+        return this.s;
+    };
+
+    /**
+     * set value by a string
+     * @name setString
+     * @memberOf KJUR.asn1.DERAbstractTime#
+     * @function
+     * @param {String} newS value by a string to set such like "130430235959Z"
+     */
+    this.setString = function(newS) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = newS;
+        this.hV = stohex(newS);
+    };
+
+    /**
+     * set value by a Date object
+     * @name setByDateValue
+     * @memberOf KJUR.asn1.DERAbstractTime#
+     * @function
+     * @param {Integer} year year of date (ex. 2013)
+     * @param {Integer} month month of date between 1 and 12 (ex. 12)
+     * @param {Integer} day day of month
+     * @param {Integer} hour hours of date
+     * @param {Integer} min minutes of date
+     * @param {Integer} sec seconds of date
+     */
+    this.setByDateValue = function(year, month, day, hour, min, sec) {
+        var dateObject = new Date(Date.UTC(year, month - 1, day, hour, min, sec, 0));
+        this.setByDate(dateObject);
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+};
+YAHOO.lang.extend(KJUR.asn1.DERAbstractTime, KJUR.asn1.ASN1Object);
+// == END   DERAbstractTime ==================================================
+
+// == BEGIN DERAbstractStructured ============================================
+/**
+ * base class for ASN.1 DER structured class
+ * @name KJUR.asn1.DERAbstractStructured
+ * @class base class for ASN.1 DER structured class
+ * @property {Array} asn1Array internal array of ASN1Object
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * @see KJUR.asn1.ASN1Object - superclass
+ */
+KJUR.asn1.DERAbstractStructured = function(params) {
+    KJUR.asn1.DERAbstractString.superclass.constructor.call(this);
+
+    /**
+     * set value by array of ASN1Object
+     * @name setByASN1ObjectArray
+     * @memberOf KJUR.asn1.DERAbstractStructured#
+     * @function
+     * @param {array} asn1ObjectArray array of ASN1Object to set
+     */
+    this.setByASN1ObjectArray = function(asn1ObjectArray) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.asn1Array = asn1ObjectArray;
+    };
+
+    /**
+     * append an ASN1Object to internal array
+     * @name appendASN1Object
+     * @memberOf KJUR.asn1.DERAbstractStructured#
+     * @function
+     * @param {ASN1Object} asn1Object to add
+     */
+    this.appendASN1Object = function(asn1Object) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.asn1Array.push(asn1Object);
+    };
+
+    this.asn1Array = new Array();
+    if (typeof params != "undefined") {
+        if (typeof params['array'] != "undefined") {
+            this.asn1Array = params['array'];
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERAbstractStructured, KJUR.asn1.ASN1Object);
+
+
+// ********************************************************************
+//  ASN.1 Object Classes
+// ********************************************************************
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Boolean
+ * @name KJUR.asn1.DERBoolean
+ * @class class for ASN.1 DER Boolean
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * @see KJUR.asn1.ASN1Object - superclass
+ */
+KJUR.asn1.DERBoolean = function() {
+    KJUR.asn1.DERBoolean.superclass.constructor.call(this);
+    this.hT = "01";
+    this.hTLV = "0101ff";
+};
+YAHOO.lang.extend(KJUR.asn1.DERBoolean, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Integer
+ * @name KJUR.asn1.DERInteger
+ * @class class for ASN.1 DER Integer
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>int - specify initial ASN.1 value(V) by integer value</li>
+ * <li>bigint - specify initial ASN.1 value(V) by BigInteger object</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ */
+KJUR.asn1.DERInteger = function(params) {
+    KJUR.asn1.DERInteger.superclass.constructor.call(this);
+    this.hT = "02";
+
+    /**
+     * set value by Tom Wu's BigInteger object
+     * @name setByBigInteger
+     * @memberOf KJUR.asn1.DERInteger#
+     * @function
+     * @param {BigInteger} bigIntegerValue to set
+     */
+    this.setByBigInteger = function(bigIntegerValue) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
+    };
+
+    /**
+     * set value by integer value
+     * @name setByInteger
+     * @memberOf KJUR.asn1.DERInteger
+     * @function
+     * @param {Integer} integer value to set
+     */
+    this.setByInteger = function(intValue) {
+        var bi = new BigInteger(String(intValue), 10);
+        this.setByBigInteger(bi);
+    };
+
+    /**
+     * set value by integer value
+     * @name setValueHex
+     * @memberOf KJUR.asn1.DERInteger#
+     * @function
+     * @param {String} hexadecimal string of integer value
+     * @description
+     * <br/>
+     * NOTE: Value shall be represented by minimum octet length of
+     * two's complement representation.
+     * @example
+     * new KJUR.asn1.DERInteger(123);
+     * new KJUR.asn1.DERInteger({'int': 123});
+     * new KJUR.asn1.DERInteger({'hex': '1fad'});
+     */
+    this.setValueHex = function(newHexString) {
+        this.hV = newHexString;
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params['bigint'] != "undefined") {
+            this.setByBigInteger(params['bigint']);
+        } else if (typeof params['int'] != "undefined") {
+            this.setByInteger(params['int']);
+        } else if (typeof params == "number") {
+            this.setByInteger(params);
+        } else if (typeof params['hex'] != "undefined") {
+            this.setValueHex(params['hex']);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERInteger, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER encoded BitString primitive
+ * @name KJUR.asn1.DERBitString
+ * @class class for ASN.1 DER encoded BitString primitive
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>bin - specify binary string (ex. '10111')</li>
+ * <li>array - specify array of boolean (ex. [true,false,true,true])</li>
+ * <li>hex - specify hexadecimal string of ASN.1 value(V) including unused bits</li>
+ * <li>obj - specify {@link KJUR.asn1.ASN1Util.newObject}
+ * argument for "BitString encapsulates" structure.</li>
+ * </ul>
+ * NOTE1: 'params' can be omitted.<br/>
+ * NOTE2: 'obj' parameter have been supported since
+ * asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).<br/>
+ * @example
+ * // default constructor
+ * o = new KJUR.asn1.DERBitString();
+ * // initialize with binary string
+ * o = new KJUR.asn1.DERBitString({bin: "1011"});
+ * // initialize with boolean array
+ * o = new KJUR.asn1.DERBitString({array: [true,false,true,true]});
+ * // initialize with hexadecimal string (04 is unused bits)
+ * o = new KJUR.asn1.DEROctetString({hex: "04bac0"});
+ * // initialize with ASN1Util.newObject argument for encapsulated
+ * o = new KJUR.asn1.DERBitString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
+ * // above generates a ASN.1 data like this:
+ * // BIT STRING, encapsulates {
+ * //   SEQUENCE {
+ * //     INTEGER 3
+ * //     PrintableString 'aaa'
+ * //     }
+ * //   }
+ */
+KJUR.asn1.DERBitString = function(params) {
+    if (params !== undefined && typeof params.obj !== "undefined") {
+        var o = KJUR.asn1.ASN1Util.newObject(params.obj);
+        params.hex = "00" + o.getEncodedHex();
+    }
+    KJUR.asn1.DERBitString.superclass.constructor.call(this);
+    this.hT = "03";
+
+    /**
+     * set ASN.1 value(V) by a hexadecimal string including unused bits
+     * @name setHexValueIncludingUnusedBits
+     * @memberOf KJUR.asn1.DERBitString#
+     * @function
+     * @param {String} newHexStringIncludingUnusedBits
+     */
+    this.setHexValueIncludingUnusedBits = function(newHexStringIncludingUnusedBits) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = newHexStringIncludingUnusedBits;
+    };
+
+    /**
+     * set ASN.1 value(V) by unused bit and hexadecimal string of value
+     * @name setUnusedBitsAndHexValue
+     * @memberOf KJUR.asn1.DERBitString#
+     * @function
+     * @param {Integer} unusedBits
+     * @param {String} hValue
+     */
+    this.setUnusedBitsAndHexValue = function(unusedBits, hValue) {
+        if (unusedBits < 0 || 7 < unusedBits) {
+            throw "unused bits shall be from 0 to 7: u = " + unusedBits;
+        }
+        var hUnusedBits = "0" + unusedBits;
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = hUnusedBits + hValue;
+    };
+
+    /**
+     * set ASN.1 DER BitString by binary string<br/>
+     * @name setByBinaryString
+     * @memberOf KJUR.asn1.DERBitString#
+     * @function
+     * @param {String} binaryString binary value string (i.e. '10111')
+     * @description
+     * Its unused bits will be calculated automatically by length of
+     * 'binaryValue'. <br/>
+     * NOTE: Trailing zeros '0' will be ignored.
+     * @example
+     * o = new KJUR.asn1.DERBitString();
+     * o.setByBooleanArray("01011");
+     */
+    this.setByBinaryString = function(binaryString) {
+        binaryString = binaryString.replace(/0+$/, '');
+        var unusedBits = 8 - binaryString.length % 8;
+        if (unusedBits == 8) unusedBits = 0;
+        for (var i = 0; i <= unusedBits; i++) {
+            binaryString += '0';
+        }
+        var h = '';
+        for (var i = 0; i < binaryString.length - 1; i += 8) {
+            var b = binaryString.substr(i, 8);
+            var x = parseInt(b, 2).toString(16);
+            if (x.length == 1) x = '0' + x;
+            h += x;
+        }
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = '0' + unusedBits + h;
+    };
+
+    /**
+     * set ASN.1 TLV value(V) by an array of boolean<br/>
+     * @name setByBooleanArray
+     * @memberOf KJUR.asn1.DERBitString#
+     * @function
+     * @param {array} booleanArray array of boolean (ex. [true, false, true])
+     * @description
+     * NOTE: Trailing falses will be ignored in the ASN.1 DER Object.
+     * @example
+     * o = new KJUR.asn1.DERBitString();
+     * o.setByBooleanArray([false, true, false, true, true]);
+     */
+    this.setByBooleanArray = function(booleanArray) {
+        var s = '';
+        for (var i = 0; i < booleanArray.length; i++) {
+            if (booleanArray[i] == true) {
+                s += '1';
+            } else {
+                s += '0';
+            }
+        }
+        this.setByBinaryString(s);
+    };
+
+    /**
+     * generate an array of falses with specified length<br/>
+     * @name newFalseArray
+     * @memberOf KJUR.asn1.DERBitString
+     * @function
+     * @param {Integer} nLength length of array to generate
+     * @return {array} array of boolean falses
+     * @description
+     * This static method may be useful to initialize boolean array.
+     * @example
+     * o = new KJUR.asn1.DERBitString();
+     * o.newFalseArray(3) &rarr; [false, false, false]
+     */
+    this.newFalseArray = function(nLength) {
+        var a = new Array(nLength);
+        for (var i = 0; i < nLength; i++) {
+            a[i] = false;
+        }
+        return a;
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params == "string" && params.toLowerCase().match(/^[0-9a-f]+$/)) {
+            this.setHexValueIncludingUnusedBits(params);
+        } else if (typeof params['hex'] != "undefined") {
+            this.setHexValueIncludingUnusedBits(params['hex']);
+        } else if (typeof params['bin'] != "undefined") {
+            this.setByBinaryString(params['bin']);
+        } else if (typeof params['array'] != "undefined") {
+            this.setByBooleanArray(params['array']);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERBitString, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER OctetString<br/>
+ * @name KJUR.asn1.DEROctetString
+ * @class class for ASN.1 DER OctetString
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * This class provides ASN.1 OctetString simple type.<br/>
+ * Supported "params" attributes are:
+ * <ul>
+ * <li>str - to set a string as a value</li>
+ * <li>hex - to set a hexadecimal string as a value</li>
+ * <li>obj - to set a encapsulated ASN.1 value by JSON object
+ * which is defined in {@link KJUR.asn1.ASN1Util.newObject}</li>
+ * </ul>
+ * NOTE: A parameter 'obj' have been supported
+ * for "OCTET STRING, encapsulates" structure.
+ * since asn1 1.0.11, jsrsasign 6.1.1 (2016-Sep-25).
+ * @see KJUR.asn1.DERAbstractString - superclass
+ * @example
+ * // default constructor
+ * o = new KJUR.asn1.DEROctetString();
+ * // initialize with string
+ * o = new KJUR.asn1.DEROctetString({str: "aaa"});
+ * // initialize with hexadecimal string
+ * o = new KJUR.asn1.DEROctetString({hex: "616161"});
+ * // initialize with ASN1Util.newObject argument
+ * o = new KJUR.asn1.DEROctetString({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}});
+ * // above generates a ASN.1 data like this:
+ * // OCTET STRING, encapsulates {
+ * //   SEQUENCE {
+ * //     INTEGER 3
+ * //     PrintableString 'aaa'
+ * //     }
+ * //   }
+ */
+KJUR.asn1.DEROctetString = function(params) {
+    if (params !== undefined && typeof params.obj !== "undefined") {
+        var o = KJUR.asn1.ASN1Util.newObject(params.obj);
+        params.hex = o.getEncodedHex();
+    }
+    KJUR.asn1.DEROctetString.superclass.constructor.call(this, params);
+    this.hT = "04";
+};
+YAHOO.lang.extend(KJUR.asn1.DEROctetString, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Null
+ * @name KJUR.asn1.DERNull
+ * @class class for ASN.1 DER Null
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * @see KJUR.asn1.ASN1Object - superclass
+ */
+KJUR.asn1.DERNull = function() {
+    KJUR.asn1.DERNull.superclass.constructor.call(this);
+    this.hT = "05";
+    this.hTLV = "0500";
+};
+YAHOO.lang.extend(KJUR.asn1.DERNull, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER ObjectIdentifier
+ * @name KJUR.asn1.DERObjectIdentifier
+ * @class class for ASN.1 DER ObjectIdentifier
+ * @param {Array} params associative array of parameters (ex. {'oid': '2.5.4.5'})
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>oid - specify initial ASN.1 value(V) by a oid string (ex. 2.5.4.13)</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ */
+KJUR.asn1.DERObjectIdentifier = function(params) {
+    var itox = function(i) {
+        var h = i.toString(16);
+        if (h.length == 1) h = '0' + h;
+        return h;
+    };
+    var roidtox = function(roid) {
+        var h = '';
+        var bi = new BigInteger(roid, 10);
+        var b = bi.toString(2);
+        var padLen = 7 - b.length % 7;
+        if (padLen == 7) padLen = 0;
+        var bPad = '';
+        for (var i = 0; i < padLen; i++) bPad += '0';
+        b = bPad + b;
+        for (var i = 0; i < b.length - 1; i += 7) {
+            var b8 = b.substr(i, 7);
+            if (i != b.length - 7) b8 = '1' + b8;
+            h += itox(parseInt(b8, 2));
+        }
+        return h;
+    };
+
+    KJUR.asn1.DERObjectIdentifier.superclass.constructor.call(this);
+    this.hT = "06";
+
+    /**
+     * set value by a hexadecimal string
+     * @name setValueHex
+     * @memberOf KJUR.asn1.DERObjectIdentifier#
+     * @function
+     * @param {String} newHexString hexadecimal value of OID bytes
+     */
+    this.setValueHex = function(newHexString) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = null;
+        this.hV = newHexString;
+    };
+
+    /**
+     * set value by a OID string<br/>
+     * @name setValueOidString
+     * @memberOf KJUR.asn1.DERObjectIdentifier#
+     * @function
+     * @param {String} oidString OID string (ex. 2.5.4.13)
+     * @example
+     * o = new KJUR.asn1.DERObjectIdentifier();
+     * o.setValueOidString("2.5.4.13");
+     */
+    this.setValueOidString = function(oidString) {
+        if (! oidString.match(/^[0-9.]+$/)) {
+            throw "malformed oid string: " + oidString;
+        }
+        var h = '';
+        var a = oidString.split('.');
+        var i0 = parseInt(a[0]) * 40 + parseInt(a[1]);
+        h += itox(i0);
+        a.splice(0, 2);
+        for (var i = 0; i < a.length; i++) {
+            h += roidtox(a[i]);
+        }
+        this.hTLV = null;
+        this.isModified = true;
+        this.s = null;
+        this.hV = h;
+    };
+
+    /**
+     * set value by a OID name
+     * @name setValueName
+     * @memberOf KJUR.asn1.DERObjectIdentifier#
+     * @function
+     * @param {String} oidName OID name (ex. 'serverAuth')
+     * @since 1.0.1
+     * @description
+     * OID name shall be defined in 'KJUR.asn1.x509.OID.name2oidList'.
+     * Otherwise raise error.
+     * @example
+     * o = new KJUR.asn1.DERObjectIdentifier();
+     * o.setValueName("serverAuth");
+     */
+    this.setValueName = function(oidName) {
+        var oid = KJUR.asn1.x509.OID.name2oid(oidName);
+        if (oid !== '') {
+            this.setValueOidString(oid);
+        } else {
+            throw "DERObjectIdentifier oidName undefined: " + oidName;
+        }
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (params !== undefined) {
+        if (typeof params === "string") {
+            if (params.match(/^[0-2].[0-9.]+$/)) {
+                this.setValueOidString(params);
+            } else {
+                this.setValueName(params);
+            }
+        } else if (params.oid !== undefined) {
+            this.setValueOidString(params.oid);
+        } else if (params.hex !== undefined) {
+            this.setValueHex(params.hex);
+        } else if (params.name !== undefined) {
+            this.setValueName(params.name);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERObjectIdentifier, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Enumerated
+ * @name KJUR.asn1.DEREnumerated
+ * @class class for ASN.1 DER Enumerated
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>int - specify initial ASN.1 value(V) by integer value</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ * @example
+ * new KJUR.asn1.DEREnumerated(123);
+ * new KJUR.asn1.DEREnumerated({int: 123});
+ * new KJUR.asn1.DEREnumerated({hex: '1fad'});
+ */
+KJUR.asn1.DEREnumerated = function(params) {
+    KJUR.asn1.DEREnumerated.superclass.constructor.call(this);
+    this.hT = "0a";
+
+    /**
+     * set value by Tom Wu's BigInteger object
+     * @name setByBigInteger
+     * @memberOf KJUR.asn1.DEREnumerated#
+     * @function
+     * @param {BigInteger} bigIntegerValue to set
+     */
+    this.setByBigInteger = function(bigIntegerValue) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.hV = KJUR.asn1.ASN1Util.bigIntToMinTwosComplementsHex(bigIntegerValue);
+    };
+
+    /**
+     * set value by integer value
+     * @name setByInteger
+     * @memberOf KJUR.asn1.DEREnumerated#
+     * @function
+     * @param {Integer} integer value to set
+     */
+    this.setByInteger = function(intValue) {
+        var bi = new BigInteger(String(intValue), 10);
+        this.setByBigInteger(bi);
+    };
+
+    /**
+     * set value by integer value
+     * @name setValueHex
+     * @memberOf KJUR.asn1.DEREnumerated#
+     * @function
+     * @param {String} hexadecimal string of integer value
+     * @description
+     * <br/>
+     * NOTE: Value shall be represented by minimum octet length of
+     * two's complement representation.
+     */
+    this.setValueHex = function(newHexString) {
+        this.hV = newHexString;
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params['int'] != "undefined") {
+            this.setByInteger(params['int']);
+        } else if (typeof params == "number") {
+            this.setByInteger(params);
+        } else if (typeof params['hex'] != "undefined") {
+            this.setValueHex(params['hex']);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DEREnumerated, KJUR.asn1.ASN1Object);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER UTF8String
+ * @name KJUR.asn1.DERUTF8String
+ * @class class for ASN.1 DER UTF8String
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERUTF8String = function(params) {
+    KJUR.asn1.DERUTF8String.superclass.constructor.call(this, params);
+    this.hT = "0c";
+};
+YAHOO.lang.extend(KJUR.asn1.DERUTF8String, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER NumericString
+ * @name KJUR.asn1.DERNumericString
+ * @class class for ASN.1 DER NumericString
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERNumericString = function(params) {
+    KJUR.asn1.DERNumericString.superclass.constructor.call(this, params);
+    this.hT = "12";
+};
+YAHOO.lang.extend(KJUR.asn1.DERNumericString, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER PrintableString
+ * @name KJUR.asn1.DERPrintableString
+ * @class class for ASN.1 DER PrintableString
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERPrintableString = function(params) {
+    KJUR.asn1.DERPrintableString.superclass.constructor.call(this, params);
+    this.hT = "13";
+};
+YAHOO.lang.extend(KJUR.asn1.DERPrintableString, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER TeletexString
+ * @name KJUR.asn1.DERTeletexString
+ * @class class for ASN.1 DER TeletexString
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERTeletexString = function(params) {
+    KJUR.asn1.DERTeletexString.superclass.constructor.call(this, params);
+    this.hT = "14";
+};
+YAHOO.lang.extend(KJUR.asn1.DERTeletexString, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER IA5String
+ * @name KJUR.asn1.DERIA5String
+ * @class class for ASN.1 DER IA5String
+ * @param {Array} params associative array of parameters (ex. {'str': 'aaa'})
+ * @extends KJUR.asn1.DERAbstractString
+ * @description
+ * @see KJUR.asn1.DERAbstractString - superclass
+ */
+KJUR.asn1.DERIA5String = function(params) {
+    KJUR.asn1.DERIA5String.superclass.constructor.call(this, params);
+    this.hT = "16";
+};
+YAHOO.lang.extend(KJUR.asn1.DERIA5String, KJUR.asn1.DERAbstractString);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER UTCTime
+ * @name KJUR.asn1.DERUTCTime
+ * @class class for ASN.1 DER UTCTime
+ * @param {Array} params associative array of parameters (ex. {'str': '130430235959Z'})
+ * @extends KJUR.asn1.DERAbstractTime
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>str - specify initial ASN.1 value(V) by a string (ex.'130430235959Z')</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * <li>date - specify Date object.</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ * <h4>EXAMPLES</h4>
+ * @example
+ * d1 = new KJUR.asn1.DERUTCTime();
+ * d1.setString('130430125959Z');
+ *
+ * d2 = new KJUR.asn1.DERUTCTime({'str': '130430125959Z'});
+ * d3 = new KJUR.asn1.DERUTCTime({'date': new Date(Date.UTC(2015, 0, 31, 0, 0, 0, 0))});
+ * d4 = new KJUR.asn1.DERUTCTime('130430125959Z');
+ */
+KJUR.asn1.DERUTCTime = function(params) {
+    KJUR.asn1.DERUTCTime.superclass.constructor.call(this, params);
+    this.hT = "17";
+
+    /**
+     * set value by a Date object<br/>
+     * @name setByDate
+     * @memberOf KJUR.asn1.DERUTCTime#
+     * @function
+     * @param {Date} dateObject Date object to set ASN.1 value(V)
+     * @example
+     * o = new KJUR.asn1.DERUTCTime();
+     * o.setByDate(new Date("2016/12/31"));
+     */
+    this.setByDate = function(dateObject) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.date = dateObject;
+        this.s = this.formatDate(this.date, 'utc');
+        this.hV = stohex(this.s);
+    };
+
+    this.getFreshValueHex = function() {
+        if (typeof this.date == "undefined" && typeof this.s == "undefined") {
+            this.date = new Date();
+            this.s = this.formatDate(this.date, 'utc');
+            this.hV = stohex(this.s);
+        }
+        return this.hV;
+    };
+
+    if (params !== undefined) {
+        if (params.str !== undefined) {
+            this.setString(params.str);
+        } else if (typeof params == "string" && params.match(/^[0-9]{12}Z$/)) {
+            this.setString(params);
+        } else if (params.hex !== undefined) {
+            this.setStringHex(params.hex);
+        } else if (params.date !== undefined) {
+            this.setByDate(params.date);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERUTCTime, KJUR.asn1.DERAbstractTime);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER GeneralizedTime
+ * @name KJUR.asn1.DERGeneralizedTime
+ * @class class for ASN.1 DER GeneralizedTime
+ * @param {Array} params associative array of parameters (ex. {'str': '20130430235959Z'})
+ * @property {Boolean} withMillis flag to show milliseconds or not
+ * @extends KJUR.asn1.DERAbstractTime
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>str - specify initial ASN.1 value(V) by a string (ex.'20130430235959Z')</li>
+ * <li>hex - specify initial ASN.1 value(V) by a hexadecimal string</li>
+ * <li>date - specify Date object.</li>
+ * <li>millis - specify flag to show milliseconds (from 1.0.6)</li>
+ * </ul>
+ * NOTE1: 'params' can be omitted.
+ * NOTE2: 'withMillis' property is supported from asn1 1.0.6.
+ */
+KJUR.asn1.DERGeneralizedTime = function(params) {
+    KJUR.asn1.DERGeneralizedTime.superclass.constructor.call(this, params);
+    this.hT = "18";
+    this.withMillis = false;
+
+    /**
+     * set value by a Date object
+     * @name setByDate
+     * @memberOf KJUR.asn1.DERGeneralizedTime#
+     * @function
+     * @param {Date} dateObject Date object to set ASN.1 value(V)
+     * @example
+     * When you specify UTC time, use 'Date.UTC' method like this:<br/>
+     * o1 = new DERUTCTime();
+     * o1.setByDate(date);
+     *
+     * date = new Date(Date.UTC(2015, 0, 31, 23, 59, 59, 0)); #2015JAN31 23:59:59
+     */
+    this.setByDate = function(dateObject) {
+        this.hTLV = null;
+        this.isModified = true;
+        this.date = dateObject;
+        this.s = this.formatDate(this.date, 'gen', this.withMillis);
+        this.hV = stohex(this.s);
+    };
+
+    this.getFreshValueHex = function() {
+        if (this.date === undefined && this.s === undefined) {
+            this.date = new Date();
+            this.s = this.formatDate(this.date, 'gen', this.withMillis);
+            this.hV = stohex(this.s);
+        }
+        return this.hV;
+    };
+
+    if (params !== undefined) {
+        if (params.str !== undefined) {
+            this.setString(params.str);
+        } else if (typeof params == "string" && params.match(/^[0-9]{14}Z$/)) {
+            this.setString(params);
+        } else if (params.hex !== undefined) {
+            this.setStringHex(params.hex);
+        } else if (params.date !== undefined) {
+            this.setByDate(params.date);
+        }
+        if (params.millis === true) {
+            this.withMillis = true;
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERGeneralizedTime, KJUR.asn1.DERAbstractTime);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Sequence
+ * @name KJUR.asn1.DERSequence
+ * @class class for ASN.1 DER Sequence
+ * @extends KJUR.asn1.DERAbstractStructured
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>array - specify array of ASN1Object to set elements of content</li>
+ * </ul>
+ * NOTE: 'params' can be omitted.
+ */
+KJUR.asn1.DERSequence = function(params) {
+    KJUR.asn1.DERSequence.superclass.constructor.call(this, params);
+    this.hT = "30";
+    this.getFreshValueHex = function() {
+        var h = '';
+        for (var i = 0; i < this.asn1Array.length; i++) {
+            var asn1Obj = this.asn1Array[i];
+            h += asn1Obj.getEncodedHex();
+        }
+        this.hV = h;
+        return this.hV;
+    };
+};
+YAHOO.lang.extend(KJUR.asn1.DERSequence, KJUR.asn1.DERAbstractStructured);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER Set
+ * @name KJUR.asn1.DERSet
+ * @class class for ASN.1 DER Set
+ * @extends KJUR.asn1.DERAbstractStructured
+ * @description
+ * <br/>
+ * As for argument 'params' for constructor, you can specify one of
+ * following properties:
+ * <ul>
+ * <li>array - specify array of ASN1Object to set elements of content</li>
+ * <li>sortflag - flag for sort (default: true). ASN.1 BER is not sorted in 'SET OF'.</li>
+ * </ul>
+ * NOTE1: 'params' can be omitted.<br/>
+ * NOTE2: sortflag is supported since 1.0.5.
+ */
+KJUR.asn1.DERSet = function(params) {
+    KJUR.asn1.DERSet.superclass.constructor.call(this, params);
+    this.hT = "31";
+    this.sortFlag = true; // item shall be sorted only in ASN.1 DER
+    this.getFreshValueHex = function() {
+        var a = new Array();
+        for (var i = 0; i < this.asn1Array.length; i++) {
+            var asn1Obj = this.asn1Array[i];
+            a.push(asn1Obj.getEncodedHex());
+        }
+        if (this.sortFlag == true) a.sort();
+        this.hV = a.join('');
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params.sortflag != "undefined" &&
+            params.sortflag == false)
+            this.sortFlag = false;
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERSet, KJUR.asn1.DERAbstractStructured);
+
+// ********************************************************************
+/**
+ * class for ASN.1 DER TaggedObject
+ * @name KJUR.asn1.DERTaggedObject
+ * @class class for ASN.1 DER TaggedObject
+ * @extends KJUR.asn1.ASN1Object
+ * @description
+ * <br/>
+ * Parameter 'tagNoNex' is ASN.1 tag(T) value for this object.
+ * For example, if you find '[1]' tag in a ASN.1 dump,
+ * 'tagNoHex' will be 'a1'.
+ * <br/>
+ * As for optional argument 'params' for constructor, you can specify *ANY* of
+ * following properties:
+ * <ul>
+ * <li>explicit - specify true if this is explicit tag otherwise false
+ *     (default is 'true').</li>
+ * <li>tag - specify tag (default is 'a0' which means [0])</li>
+ * <li>obj - specify ASN1Object which is tagged</li>
+ * </ul>
+ * @example
+ * d1 = new KJUR.asn1.DERUTF8String({'str':'a'});
+ * d2 = new KJUR.asn1.DERTaggedObject({'obj': d1});
+ * hex = d2.getEncodedHex();
+ */
+KJUR.asn1.DERTaggedObject = function(params) {
+    KJUR.asn1.DERTaggedObject.superclass.constructor.call(this);
+    this.hT = "a0";
+    this.hV = '';
+    this.isExplicit = true;
+    this.asn1Object = null;
+
+    /**
+     * set value by an ASN1Object
+     * @name setString
+     * @memberOf KJUR.asn1.DERTaggedObject#
+     * @function
+     * @param {Boolean} isExplicitFlag flag for explicit/implicit tag
+     * @param {Integer} tagNoHex hexadecimal string of ASN.1 tag
+     * @param {ASN1Object} asn1Object ASN.1 to encapsulate
+     */
+    this.setASN1Object = function(isExplicitFlag, tagNoHex, asn1Object) {
+        this.hT = tagNoHex;
+        this.isExplicit = isExplicitFlag;
+        this.asn1Object = asn1Object;
+        if (this.isExplicit) {
+            this.hV = this.asn1Object.getEncodedHex();
+            this.hTLV = null;
+            this.isModified = true;
+        } else {
+            this.hV = null;
+            this.hTLV = asn1Object.getEncodedHex();
+            this.hTLV = this.hTLV.replace(/^../, tagNoHex);
+            this.isModified = false;
+        }
+    };
+
+    this.getFreshValueHex = function() {
+        return this.hV;
+    };
+
+    if (typeof params != "undefined") {
+        if (typeof params['tag'] != "undefined") {
+            this.hT = params['tag'];
+        }
+        if (typeof params['explicit'] != "undefined") {
+            this.isExplicit = params['explicit'];
+        }
+        if (typeof params['obj'] != "undefined") {
+            this.asn1Object = params['obj'];
+            this.setASN1Object(this.isExplicit, this.hT, this.asn1Object);
+        }
+    }
+};
+YAHOO.lang.extend(KJUR.asn1.DERTaggedObject, KJUR.asn1.ASN1Object);
+
+/**
+ * Create a new JSEncryptRSAKey that extends Tom Wu's RSA key object.
+ * This object is just a decorator for parsing the key parameter
+ * @param {string|Object} key - The key in string format, or an object containing
+ * the parameters needed to build a RSAKey object.
+ * @constructor
+ */
+var JSEncryptRSAKey = /** @class */ (function (_super) {
+    __extends(JSEncryptRSAKey, _super);
+    function JSEncryptRSAKey(key) {
+        var _this = _super.call(this) || this;
+        // Call the super constructor.
+        //  RSAKey.call(this);
+        // If a key key was provided.
+        if (key) {
+            // If this is a string...
+            if (typeof key === "string") {
+                _this.parseKey(key);
+            }
+            else if (JSEncryptRSAKey.hasPrivateKeyProperty(key) ||
+                JSEncryptRSAKey.hasPublicKeyProperty(key)) {
+                // Set the values for the key.
+                _this.parsePropertiesFrom(key);
+            }
+        }
+        return _this;
+    }
+    /**
+     * Method to parse a pem encoded string containing both a public or private key.
+     * The method will translate the pem encoded string in a der encoded string and
+     * will parse private key and public key parameters. This method accepts public key
+     * in the rsaencryption pkcs #1 format (oid: 1.2.840.113549.1.1.1).
+     *
+     * @todo Check how many rsa formats use the same format of pkcs #1.
+     *
+     * The format is defined as:
+     * PublicKeyInfo ::= SEQUENCE {
+     *   algorithm       AlgorithmIdentifier,
+     *   PublicKey       BIT STRING
+     * }
+     * Where AlgorithmIdentifier is:
+     * AlgorithmIdentifier ::= SEQUENCE {
+     *   algorithm       OBJECT IDENTIFIER,     the OID of the enc algorithm
+     *   parameters      ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)
+     * }
+     * and PublicKey is a SEQUENCE encapsulated in a BIT STRING
+     * RSAPublicKey ::= SEQUENCE {
+     *   modulus           INTEGER,  -- n
+     *   publicExponent    INTEGER   -- e
+     * }
+     * it's possible to examine the structure of the keys obtained from openssl using
+     * an asn.1 dumper as the one used here to parse the components: http://lapo.it/asn1js/
+     * @argument {string} pem the pem encoded string, can include the BEGIN/END header/footer
+     * @private
+     */
+    JSEncryptRSAKey.prototype.parseKey = function (pem) {
+        try {
+            var modulus = 0;
+            var public_exponent = 0;
+            var reHex = /^\s*(?:[0-9A-Fa-f][0-9A-Fa-f]\s*)+$/;
+            var der = reHex.test(pem) ? Hex.decode(pem) : Base64.unarmor(pem);
+            var asn1 = ASN1.decode(der);
+            // Fixes a bug with OpenSSL 1.0+ private keys
+            if (asn1.sub.length === 3) {
+                asn1 = asn1.sub[2].sub[0];
+            }
+            if (asn1.sub.length === 9) {
+                // Parse the private key.
+                modulus = asn1.sub[1].getHexStringValue(); // bigint
+                this.n = parseBigInt(modulus, 16);
+                public_exponent = asn1.sub[2].getHexStringValue(); // int
+                this.e = parseInt(public_exponent, 16);
+                var private_exponent = asn1.sub[3].getHexStringValue(); // bigint
+                this.d = parseBigInt(private_exponent, 16);
+                var prime1 = asn1.sub[4].getHexStringValue(); // bigint
+                this.p = parseBigInt(prime1, 16);
+                var prime2 = asn1.sub[5].getHexStringValue(); // bigint
+                this.q = parseBigInt(prime2, 16);
+                var exponent1 = asn1.sub[6].getHexStringValue(); // bigint
+                this.dmp1 = parseBigInt(exponent1, 16);
+                var exponent2 = asn1.sub[7].getHexStringValue(); // bigint
+                this.dmq1 = parseBigInt(exponent2, 16);
+                var coefficient = asn1.sub[8].getHexStringValue(); // bigint
+                this.coeff = parseBigInt(coefficient, 16);
+            }
+            else if (asn1.sub.length === 2) {
+                // Parse the public key.
+                var bit_string = asn1.sub[1];
+                var sequence = bit_string.sub[0];
+                modulus = sequence.sub[0].getHexStringValue();
+                this.n = parseBigInt(modulus, 16);
+                public_exponent = sequence.sub[1].getHexStringValue();
+                this.e = parseInt(public_exponent, 16);
+            }
+            else {
+                return false;
+            }
+            return true;
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Translate rsa parameters in a hex encoded string representing the rsa key.
+     *
+     * The translation follow the ASN.1 notation :
+     * RSAPrivateKey ::= SEQUENCE {
+     *   version           Version,
+     *   modulus           INTEGER,  -- n
+     *   publicExponent    INTEGER,  -- e
+     *   privateExponent   INTEGER,  -- d
+     *   prime1            INTEGER,  -- p
+     *   prime2            INTEGER,  -- q
+     *   exponent1         INTEGER,  -- d mod (p1)
+     *   exponent2         INTEGER,  -- d mod (q-1)
+     *   coefficient       INTEGER,  -- (inverse of q) mod p
+     * }
+     * @returns {string}  DER Encoded String representing the rsa private key
+     * @private
+     */
+    JSEncryptRSAKey.prototype.getPrivateBaseKey = function () {
+        var options = {
+            array: [
+                new KJUR.asn1.DERInteger({ int: 0 }),
+                new KJUR.asn1.DERInteger({ bigint: this.n }),
+                new KJUR.asn1.DERInteger({ int: this.e }),
+                new KJUR.asn1.DERInteger({ bigint: this.d }),
+                new KJUR.asn1.DERInteger({ bigint: this.p }),
+                new KJUR.asn1.DERInteger({ bigint: this.q }),
+                new KJUR.asn1.DERInteger({ bigint: this.dmp1 }),
+                new KJUR.asn1.DERInteger({ bigint: this.dmq1 }),
+                new KJUR.asn1.DERInteger({ bigint: this.coeff })
+            ]
+        };
+        var seq = new KJUR.asn1.DERSequence(options);
+        return seq.getEncodedHex();
+    };
+    /**
+     * base64 (pem) encoded version of the DER encoded representation
+     * @returns {string} pem encoded representation without header and footer
+     * @public
+     */
+    JSEncryptRSAKey.prototype.getPrivateBaseKeyB64 = function () {
+        return hex2b64(this.getPrivateBaseKey());
+    };
+    /**
+     * Translate rsa parameters in a hex encoded string representing the rsa public key.
+     * The representation follow the ASN.1 notation :
+     * PublicKeyInfo ::= SEQUENCE {
+     *   algorithm       AlgorithmIdentifier,
+     *   PublicKey       BIT STRING
+     * }
+     * Where AlgorithmIdentifier is:
+     * AlgorithmIdentifier ::= SEQUENCE {
+     *   algorithm       OBJECT IDENTIFIER,     the OID of the enc algorithm
+     *   parameters      ANY DEFINED BY algorithm OPTIONAL (NULL for PKCS #1)
+     * }
+     * and PublicKey is a SEQUENCE encapsulated in a BIT STRING
+     * RSAPublicKey ::= SEQUENCE {
+     *   modulus           INTEGER,  -- n
+     *   publicExponent    INTEGER   -- e
+     * }
+     * @returns {string} DER Encoded String representing the rsa public key
+     * @private
+     */
+    JSEncryptRSAKey.prototype.getPublicBaseKey = function () {
+        var first_sequence = new KJUR.asn1.DERSequence({
+            array: [
+                new KJUR.asn1.DERObjectIdentifier({ oid: "1.2.840.113549.1.1.1" }),
+                new KJUR.asn1.DERNull()
+            ]
+        });
+        var second_sequence = new KJUR.asn1.DERSequence({
+            array: [
+                new KJUR.asn1.DERInteger({ bigint: this.n }),
+                new KJUR.asn1.DERInteger({ int: this.e })
+            ]
+        });
+        var bit_string = new KJUR.asn1.DERBitString({
+            hex: "00" + second_sequence.getEncodedHex()
+        });
+        var seq = new KJUR.asn1.DERSequence({
+            array: [
+                first_sequence,
+                bit_string
+            ]
+        });
+        return seq.getEncodedHex();
+    };
+    /**
+     * base64 (pem) encoded version of the DER encoded representation
+     * @returns {string} pem encoded representation without header and footer
+     * @public
+     */
+    JSEncryptRSAKey.prototype.getPublicBaseKeyB64 = function () {
+        return hex2b64(this.getPublicBaseKey());
+    };
+    /**
+     * wrap the string in block of width chars. The default value for rsa keys is 64
+     * characters.
+     * @param {string} str the pem encoded string without header and footer
+     * @param {Number} [width=64] - the length the string has to be wrapped at
+     * @returns {string}
+     * @private
+     */
+    JSEncryptRSAKey.wordwrap = function (str, width) {
+        width = width || 64;
+        if (!str) {
+            return str;
+        }
+        var regex = "(.{1," + width + "})( +|$\n?)|(.{1," + width + "})";
+        return str.match(RegExp(regex, "g")).join("\n");
+    };
+    /**
+     * Retrieve the pem encoded private key
+     * @returns {string} the pem encoded private key with header/footer
+     * @public
+     */
+    JSEncryptRSAKey.prototype.getPrivateKey = function () {
+        var key = "-----BEGIN RSA PRIVATE KEY-----\n";
+        key += JSEncryptRSAKey.wordwrap(this.getPrivateBaseKeyB64()) + "\n";
+        key += "-----END RSA PRIVATE KEY-----";
+        return key;
+    };
+    /**
+     * Retrieve the pem encoded public key
+     * @returns {string} the pem encoded public key with header/footer
+     * @public
+     */
+    JSEncryptRSAKey.prototype.getPublicKey = function () {
+        var key = "-----BEGIN PUBLIC KEY-----\n";
+        key += JSEncryptRSAKey.wordwrap(this.getPublicBaseKeyB64()) + "\n";
+        key += "-----END PUBLIC KEY-----";
+        return key;
+    };
+    /**
+     * Check if the object contains the necessary parameters to populate the rsa modulus
+     * and public exponent parameters.
+     * @param {Object} [obj={}] - An object that may contain the two public key
+     * parameters
+     * @returns {boolean} true if the object contains both the modulus and the public exponent
+     * properties (n and e)
+     * @todo check for types of n and e. N should be a parseable bigInt object, E should
+     * be a parseable integer number
+     * @private
+     */
+    JSEncryptRSAKey.hasPublicKeyProperty = function (obj) {
+        obj = obj || {};
+        return (obj.hasOwnProperty("n") &&
+            obj.hasOwnProperty("e"));
+    };
+    /**
+     * Check if the object contains ALL the parameters of an RSA key.
+     * @param {Object} [obj={}] - An object that may contain nine rsa key
+     * parameters
+     * @returns {boolean} true if the object contains all the parameters needed
+     * @todo check for types of the parameters all the parameters but the public exponent
+     * should be parseable bigint objects, the public exponent should be a parseable integer number
+     * @private
+     */
+    JSEncryptRSAKey.hasPrivateKeyProperty = function (obj) {
+        obj = obj || {};
+        return (obj.hasOwnProperty("n") &&
+            obj.hasOwnProperty("e") &&
+            obj.hasOwnProperty("d") &&
+            obj.hasOwnProperty("p") &&
+            obj.hasOwnProperty("q") &&
+            obj.hasOwnProperty("dmp1") &&
+            obj.hasOwnProperty("dmq1") &&
+            obj.hasOwnProperty("coeff"));
+    };
+    /**
+     * Parse the properties of obj in the current rsa object. Obj should AT LEAST
+     * include the modulus and public exponent (n, e) parameters.
+     * @param {Object} obj - the object containing rsa parameters
+     * @private
+     */
+    JSEncryptRSAKey.prototype.parsePropertiesFrom = function (obj) {
+        this.n = obj.n;
+        this.e = obj.e;
+        if (obj.hasOwnProperty("d")) {
+            this.d = obj.d;
+            this.p = obj.p;
+            this.q = obj.q;
+            this.dmp1 = obj.dmp1;
+            this.dmq1 = obj.dmq1;
+            this.coeff = obj.coeff;
+        }
+    };
+    return JSEncryptRSAKey;
+}(RSAKey));
+
+/**
+ *
+ * @param {Object} [options = {}] - An object to customize JSEncrypt behaviour
+ * possible parameters are:
+ * - default_key_size        {number}  default: 1024 the key size in bit
+ * - default_public_exponent {string}  default: '010001' the hexadecimal representation of the public exponent
+ * - log                     {boolean} default: false whether log warn/error or not
+ * @constructor
+ */
+var JSEncrypt = /** @class */ (function () {
+    function JSEncrypt(options) {
+        options = options || {};
+        this.default_key_size = parseInt(options.default_key_size, 10) || 1024;
+        this.default_public_exponent = options.default_public_exponent || "010001"; // 65537 default openssl public exponent for rsa key type
+        this.log = options.log || false;
+        // The private and public key.
+        this.key = null;
+    }
+    /**
+     * Method to set the rsa key parameter (one method is enough to set both the public
+     * and the private key, since the private key contains the public key paramenters)
+     * Log a warning if logs are enabled
+     * @param {Object|string} key the pem encoded string or an object (with or without header/footer)
+     * @public
+     */
+    JSEncrypt.prototype.setKey = function (key) {
+        if (this.log && this.key) {
+            console.warn("A key was already set, overriding existing.");
+        }
+        this.key = new JSEncryptRSAKey(key);
+    };
+    /**
+     * Proxy method for setKey, for api compatibility
+     * @see setKey
+     * @public
+     */
+    JSEncrypt.prototype.setPrivateKey = function (privkey) {
+        // Create the key.
+        this.setKey(privkey);
+    };
+    /**
+     * Proxy method for setKey, for api compatibility
+     * @see setKey
+     * @public
+     */
+    JSEncrypt.prototype.setPublicKey = function (pubkey) {
+        // Sets the public key.
+        this.setKey(pubkey);
+    };
+    /**
+     * Proxy method for RSAKey object's decrypt, decrypt the string using the private
+     * components of the rsa key object. Note that if the object was not set will be created
+     * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor
+     * @param {string} str base64 encoded crypted string to decrypt
+     * @return {string} the decrypted string
+     * @public
+     */
+    JSEncrypt.prototype.decrypt = function (str) {
+        // Return the decrypted string.
+        try {
+            return this.getKey().decrypt(b64tohex(str));
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Proxy method for RSAKey object's encrypt, encrypt the string using the public
+     * components of the rsa key object. Note that if the object was not set will be created
+     * on the fly (by the getKey method) using the parameters passed in the JSEncrypt constructor
+     * @param {string} str the string to encrypt
+     * @return {string} the encrypted string encoded in base64
+     * @public
+     */
+    JSEncrypt.prototype.encrypt = function (str) {
+        // Return the encrypted string.
+        try {
+            return hex2b64(this.getKey().encrypt(str));
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Proxy method for RSAKey object's sign.
+     * @param {string} str the string to sign
+     * @param {function} digestMethod hash method
+     * @param {string} digestName the name of the hash algorithm
+     * @return {string} the signature encoded in base64
+     * @public
+     */
+    JSEncrypt.prototype.sign = function (str, digestMethod, digestName) {
+        // return the RSA signature of 'str' in 'hex' format.
+        try {
+            return hex2b64(this.getKey().sign(str, digestMethod, digestName));
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Proxy method for RSAKey object's verify.
+     * @param {string} str the string to verify
+     * @param {string} signature the signature encoded in base64 to compare the string to
+     * @param {function} digestMethod hash method
+     * @return {boolean} whether the data and signature match
+     * @public
+     */
+    JSEncrypt.prototype.verify = function (str, signature, digestMethod) {
+        // Return the decrypted 'digest' of the signature.
+        try {
+            return this.getKey().verify(str, b64tohex(signature), digestMethod);
+        }
+        catch (ex) {
+            return false;
+        }
+    };
+    /**
+     * Getter for the current JSEncryptRSAKey object. If it doesn't exists a new object
+     * will be created and returned
+     * @param {callback} [cb] the callback to be called if we want the key to be generated
+     * in an async fashion
+     * @returns {JSEncryptRSAKey} the JSEncryptRSAKey object
+     * @public
+     */
+    JSEncrypt.prototype.getKey = function (cb) {
+        // Only create new if it does not exist.
+        if (!this.key) {
+            // Get a new private key.
+            this.key = new JSEncryptRSAKey();
+            if (cb && {}.toString.call(cb) === "[object Function]") {
+                this.key.generateAsync(this.default_key_size, this.default_public_exponent, cb);
+                return;
+            }
+            // Generate the key.
+            this.key.generate(this.default_key_size, this.default_public_exponent);
+        }
+        return this.key;
+    };
+    /**
+     * Returns the pem encoded representation of the private key
+     * If the key doesn't exists a new key will be created
+     * @returns {string} pem encoded representation of the private key WITH header and footer
+     * @public
+     */
+    JSEncrypt.prototype.getPrivateKey = function () {
+        // Return the private representation of this key.
+        return this.getKey().getPrivateKey();
+    };
+    /**
+     * Returns the pem encoded representation of the private key
+     * If the key doesn't exists a new key will be created
+     * @returns {string} pem encoded representation of the private key WITHOUT header and footer
+     * @public
+     */
+    JSEncrypt.prototype.getPrivateKeyB64 = function () {
+        // Return the private representation of this key.
+        return this.getKey().getPrivateBaseKeyB64();
+    };
+    /**
+     * Returns the pem encoded representation of the public key
+     * If the key doesn't exists a new key will be created
+     * @returns {string} pem encoded representation of the public key WITH header and footer
+     * @public
+     */
+    JSEncrypt.prototype.getPublicKey = function () {
+        // Return the private representation of this key.
+        return this.getKey().getPublicKey();
+    };
+    /**
+     * Returns the pem encoded representation of the public key
+     * If the key doesn't exists a new key will be created
+     * @returns {string} pem encoded representation of the public key WITHOUT header and footer
+     * @public
+     */
+    JSEncrypt.prototype.getPublicKeyB64 = function () {
+        // Return the private representation of this key.
+        return this.getKey().getPublicBaseKeyB64();
+    };
+    JSEncrypt.version = "3.0.0-rc.1";
+    return JSEncrypt;
+}());
+
+window.JSEncrypt = JSEncrypt;
+
+exports.JSEncrypt = JSEncrypt;
+exports.default = JSEncrypt;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/d2d_app/service/private.key b/d2d_app/service/private.key
new file mode 100644 (file)
index 0000000..481f66e
--- /dev/null
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDlOJu6TyygqxfWT7eLtGDwajtNFOb9I5XRb6khyfD1Yt3YiCgQ
+WMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76xFxdU6jE0NQ+Z+zEdhUTooNR
+aY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4gwQco1KRMDSmXSMkDwIDAQAB
+AoGAfY9LpnuWK5Bs50UVep5c93SJdUi82u7yMx4iHFMc/Z2hfenfYEzu+57fI4fv
+xTQ//5DbzRR/XKb8ulNv6+CHyPF31xk7YOBfkGI8qjLoq06V+FyBfDSwL8KbLyeH
+m7KUZnLNQbk8yGLzB3iYKkRHlmUanQGaNMIJziWOkN+N9dECQQD0ONYRNZeuM8zd
+8XJTSdcIX4a3gy3GGCJxOzv16XHxD03GW6UNLmfPwenKu+cdrQeaqEixrCejXdAF
+z/7+BSMpAkEA8EaSOeP5Xr3ZrbiKzi6TGMwHMvC7HdJxaBJbVRfApFrE0/mPwmP5
+rN7QwjrMY+0+AbXcm8mRQyQ1+IGEembsdwJBAN6az8Rv7QnD/YBvi52POIlRSSIM
+V7SwWvSK4WSMnGb1ZBbhgdg57DXaspcwHsFV7hByQ5BvMtIduHcT14ECfcECQATe
+aTgjFnqE/lQ22Rk0eGaYO80cc643BXVGafNfd9fcvwBMnk0iGX0XRsOozVt5Azil
+psLBYuApa66NcVHJpCECQQDTjI2AQhFc1yRnCU/YgDnSpJVm1nASoRUnU8Jfm3Oz
+uku7JUXcVpt08DFSceCEX9unCuMcT72rAQlLpdZir876
+-----END RSA PRIVATE KEY-----
\ No newline at end of file
diff --git a/d2d_app/service/public.key b/d2d_app/service/public.key
new file mode 100644 (file)
index 0000000..474b48f
--- /dev/null
@@ -0,0 +1,6 @@
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDlOJu6TyygqxfWT7eLtGDwajtN
+FOb9I5XRb6khyfD1Yt3YiCgQWMNW649887VGJiGr/L5i2osbl8C9+WJTeucF+S76
+xFxdU6jE0NQ+Z+zEdhUTooNRaY5nZiu5PgDB0ED/ZKBUSLKL7eibMxZtMlUDHjm4
+gwQco1KRMDSmXSMkDwIDAQAB
+-----END PUBLIC KEY-----
\ No newline at end of file
index f4c16ff..4f93916 100755 (executable)
@@ -9,6 +9,7 @@ var RelayServer = function(httpserver, options) {
     var wsServer = new WebSocketServer({ server : httpserver });
 
     wsServer.on('connection', function(ws, req) {
+        console.log("relay-service: connection", ws, req);
         // In case of local client, remoteAddress will be ::1
         // In case of remote client, remoteAddress will be ::ffff:ipaddress
         // e.g.) ::ffff:192.168.0.21
@@ -25,8 +26,10 @@ var RelayServer = function(httpserver, options) {
         if (ip === serviceWsClientIp || ip === '127.0.0.1') {
             console.log("connected from local");
             serviceWs[pkgId] = ws;
-            if (!wsClients[pkgId].length)
+            if (!wsClients[pkgId].length) {
                 console.log("connected : no client-clients");
+            }
+            console.log("relay-service: ws", ws);
             ws.on('message', function(msg) {
                 console.log("msg[" + msg + "]");
                 const res_msg = 'Success to send : ' + msg;
@@ -54,9 +57,6 @@ var RelayServer = function(httpserver, options) {
                         wsClients[myPkgId][id].send(msg);
                 }
             });
-            ws.on('close', function(msg) {
-                console.log("close server-client");
-            });
         } else {
             console.log("connected from", ip);
             if (wsClients[pkgId].indexOf(ws) == -1) {
@@ -86,7 +86,6 @@ var RelayServer = function(httpserver, options) {
                     serviceWs[myPkgId].send(msg);
             });
             ws.on('close', function(msg) {
-                console.log("close client-clients");
                 let myPkgId = null;
                 for (let key in wsClients) {
                     if (wsClients[key].indexOf(ws) != -1) {
index 680b50e..61d20f2 100755 (executable)
-var express = require('express');
-var http = require('http');
-var path = require("path");
-var EventEmitter = require('events');
-
-var httpserver, evtEmit;
-var apps, dataApps = [];
-var relayServer = require('./relay-server.js');
-
-function addD2Ddata(appPkgID, appAppID, appName) {
-  var metaDataArray = tizen.application.getAppMetaData(appAppID);
-  for (var j = 0; j < metaDataArray.length; j++) {
-    if(metaDataArray[j].key === "d2dservice" && metaDataArray[j].value === "enable" ) {
-      dataApps.push({
-        d2dApp: {
-          appPkgID: appPkgID,
-          appAppID: appAppID,
-          appName: appName,
+"use strict";
+
+const express = require('express');
+const http = require('http');
+const path = require("path");
+const relayServer = require('./relay-server.js');
+const session = require('express-session');
+const EventEmitter = require('events');
+const WebSocket = require('ws');
+const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
+
+const PUBLIC_DOMAIN = 'http://mydevice.ga';
+const TAG = '[D2D Server]'
+const TIZEN_WEB_APP_SHARED_RESOURCES = 'shared/res/';
+const WEBCLIP_DIRECTORY = 'webclip';
+const WEBCLIP_MANIFEST = 'manifest.json';
+const is_tv = webapis.cachedProperty !== undefined;
+const non_ip_list = [
+  '127.0.0.1',
+  '192.168.250.250'
+]
+
+var apps = [];
+var dataApps = [];
+var clientRouter = express.Router();
+var httpserver, evtEmit, d2dService;
+var platform_app_path = '/opt/usr/globalapps';
+var serverAppId = '';
+var urlParam = '';
+var watchId = '';
+var pincode;
+var JSEncryptLib = require('./jsencrypt');
+var g = {
+  port: 9000,
+  baseDir: __dirname,
+};
+
+// Watch together doesn't use pincode just for demo.
+var MODE_WT = false;
+
+// manage private key.
+var pvkeyHandle = tizen.filesystem.openFile(path.resolve(__dirname, 'private.key'), 'r');
+var privateKey = pvkeyHandle.readString();
+
+// manage public key.
+var pbkeyHandle = tizen.filesystem.openFile(path.resolve(__dirname, 'public.key'), 'r');
+var publicKey = pbkeyHandle.readString();
+
+class D2DServiceLocal {
+  constructor() {
+    this.initialize();
+  }
+  initialize() {
+    const pkgId = "2FUI52kIJP";
+    const SERVER = -1;
+    const clients = [];
+    const scale = 2.5;
+
+    this.TO_ALL = 100; // Assume that only 100 clients can be connected to a web socket server
+    this.websocket = new WebSocket("ws://localhost:9000/" + pkgId);
+
+    this.websocket.onmessage = function (evt) {
+      console.log(`${TAG} D2DServiceLocal.webscocket.onmessage: ${webapis}`);
+      var msg = JSON.parse(evt.data);
+      if (msg.id == SERVER) {
+        if (msg.type == "new_client") {
+          clients.push(msg.data);
+          webapis.mde.initVirtualEventGenerator(0);
+          webapis.mde.initVirtualEventGenerator(1);
         }
-      });
-    }
+      } else {
+        if (msg.type == "keypress") {
+          webapis.mde.generateVirtualKeyEvent(msg.data.keycode, 2);
+        } else if (msg.type == "click") {
+          webapis.mde.generateVirtualMouseButtonEvent(1, 2);
+        } else if (msg.type == "touchmove") {
+          if (parseInt(msg.data.x * scale) != 0 && parseInt(msg.data.y * scale) != 0) {
+            webapis.mde.generateVirtualMouseMoveEvent(parseInt(msg.data.x * scale), parseInt(msg.data.y * scale), 1);
+          }
+        }
+      }
+    };
+    this.websocket.onclose = function (evt) {
+      webapis.mde.deInitVirtualEventGenerator(0);
+      webapis.mde.deInitVirtualEventGenerator(1);
+    };
+  }
+
+  doSend(type, data, whom = this.TO_ALL) {
+    var packet = { type: type, data: data, id: whom };
+    this.websocket.send(JSON.stringify(packet));
+  }
+
+  sendMessage(what, data, whom = this.TO_ALL) {
+    console.log(`${TAG} D2DServiceLocal.sendMessage: ${what} ${data}`);
+    this.doSend(what, data, whom);
   }
 }
 
+function addD2Ddata(appPkgID, appAppID, appName, iconPath) {
+  var metaDataArray = tizen.application.getAppMetaData(appAppID),
+    app = null;
+
+  metaDataArray = metaDataArray.filter(function (metaData) {
+    return metaData.key === "d2dservice" && metaData.value === "enable";
+  });
+  metaDataArray.forEach(function () {
+    let appPath = path.join(platform_app_path, appPkgID, TIZEN_WEB_APP_SHARED_RESOURCES);
+
+    app = {
+      d2dApp: {
+        appPkgID: appPkgID,
+        appAppID: appAppID,
+        appName: appName,
+        iconPath: iconPath
+      },
+      path: path.join(appPath)
+    }
+
+    dataApps.push(app);
+  });
+
+  return app;
+}
+
 function removeD2Ddata(packageId) {
   for (var j = 0; j < dataApps.length; j++) {
-    if (packageId && !packageId.indexOf(dataApps[j].d2dApp.appPkgID))
-      dataApps.splice(j,1);
+    if (packageId && !packageId.indexOf(dataApps[j].d2dApp.appPkgID)) {
+      dataApps.splice(j, 1);
+    }
   }
 }
 
 function setData() {
   var i;
-  dataApps.length = 0;
+
   for (i = 0; i < apps.length; i++) {
-    addD2Ddata(apps[i].packageId, apps[i].id, apps[i].name);
+    addD2Ddata(apps[i].packageId, apps[i].id, apps[i].name, apps[i].iconPath);
   }
 }
 
 function getAppList() {
-  var i;
   if (tizen.application) {
     try {
-      tizen.application.getAppsInfo(function(applications) {
+      tizen.application.getAppsInfo(function (applications) {
         apps = applications;
         setData();
+        getWebclipsManifest();
       });
     } catch (err) {
       return false;
@@ -53,18 +155,52 @@ function getAppList() {
   return false;
 }
 
+function getWebclipsManifestByApp(app) {
+  var fileHandle;
+  var filePath = path.join(app.path, WEBCLIP_DIRECTORY, WEBCLIP_MANIFEST);
+  var data;
+
+  console.log(`${TAG} webclip path : ${filePath}`);
+  try {
+    fileHandle = tizen.filesystem.openFile(filePath, "r");
+  } catch (err) {
+    console.log(`${TAG} tizen.filesystem.openFile (error): ${filePath} ${err}`);
+  }
+
+  if (fileHandle) {
+    try {
+      data = fileHandle.readString();
+      data = data.replace(/\n/g, "");
+      data = JSON.parse(data);
+      app.webclip = {};
+      app.webclip.manifest = data;
+    } catch (err) {
+      console.log(`${TAG} fileHandle.readString (error): ${err}`);
+      app.webclip = null;
+    }
+    fileHandle.close();
+  }
+}
+
+function getWebclipsManifest() {
+  dataApps.forEach(
+    getWebclipsManifestByApp
+  );
+}
+
 function setPackageInfoEventListener() {
   var packageEventCallback = {
-    oninstalled: function(packageInfo) {
-      console.log("The package " + packageInfo.name + " is installed");
-      addD2Ddata(packageInfo.id, packageInfo.appIds[0], packageInfo.name);
+    oninstalled: function (packageInfo) {
+      console.log(`${TAG} The package ${packageInfo.name} is installed`);
+      let app = addD2Ddata(packageInfo.id, packageInfo.appIds[0], packageInfo.name, packageInfo.iconPath);
+      getWebclipsManifestByApp(app);
       evtEmit.emit("updateapplist", "message", dataApps);
     },
-    onupdated: function(packageInfo) {
-      console.log("The package " + packageInfo.name + " is updated");
+    onupdated: function (packageInfo) {
+      console.log(`${TAG} The package ${packageInfo.name} is updated`);
     },
-    onuninstalled: function(packageId) {
-      console.log("The package " + packageId + " is uninstalled");
+    onuninstalled: function (packageId) {
+      console.log(`${TAG} The package ${packageId} is uninstalled`);
       removeD2Ddata(packageId);
       evtEmit.emit("updateapplist", "message", dataApps);
     }
@@ -76,26 +212,221 @@ function unsetPackageInfoEventListener() {
   tizen.package.unsetPackageInfoEventListener();
 }
 
-var HTTPserverStart = function() {
-  var g = {
-    port: 9000,
-    baseDir: __dirname,
+function getWebClipsList() {
+  var result = [];
+  var webclips = [];
+
+  dataApps.forEach(function (app) {
+    webclips = [];
+    if (app.webclip && app.webclip.manifest) {
+      webclips.push({
+        url: path.join('client', 'webclip', app.webclip.manifest.name),
+        isSelected: true
+      });
+    }
+    result.push({
+      appID: app.d2dApp.appAppID,
+      pkgID: app.d2dApp.appPkgID,
+      isInstalled: true,
+      isActive: false,
+      webClipsList: webclips
+    });
+  });
+
+  return result;
+}
+
+function addAccountListener() {
+  var accountChangeListener = {
+    onadded: function (account) {
+    },
+    onremoved: function (accountId) {
+    },
+    onupdated: function (account) {
+    }
   };
+  watchId = tizen.account.addAccountListener(accountChangeListener);
+}
+
+function removeAccountListener() {
+  tizen.account.removeAccountListener(watchId);
+}
+
+function sendLoginIdAndDeviceName(login_id, device_ip) {
+  let device_name = webapis.mde.getDeviceName();
+  console.log(`${TAG} login_id = ${login_id}, device_name = ${device_name}`);
+
+  var xhr = new XMLHttpRequest();
+  var keyVal = {
+    login_id: login_id,
+    device_name: device_name,
+    device_ip: device_ip
+  };
+  xhr.onreadystatechange = function () {
+    if (xhr.readyState === xhr.DONE) {
+      console.log(`${TAG} xhr text: ${xhr.responseText}`);
+      if (xhr.status === 200 || xhr.status === 201) {
+        if (xhr.responseText === 'DEVICE_EXISTS') {
+          console.log(`${TAG} device exists`);
+        }
+      } else {
+        console.log(`${TAG} xhr error: ${xhr.status}`);
+      }
+    }
+  }
+  xhr.open('POST', PUBLIC_DOMAIN + '/registerDevice');
+  xhr.setRequestHeader('Content-Type', 'application/json');
+  xhr.send(JSON.stringify(keyVal));
+}
+
+function updateDNSresolver(device_ip) {
+  console.log(`${TAG} Server is listening on ${device_ip}:${g.port}`);
+  let login_id = 'stester81@gmail.com';
+  if (is_tv)
+     login_id = webapis.mde.getCurrentLoginId();
+  sendLoginIdAndDeviceName(login_id, device_ip);
+}
+
+function comparePincode(req, res, encrypted) {
+  console.log(`${TAG} comparePincode`);
+  var decrypt = new JSEncryptLib.JSEncrypt();
+  decrypt.setPrivateKey(privateKey);
+  var decrypted = decrypt.decrypt(encrypted);
+
+  console.log('[WT] input pincode : ' + pincode);
+  console.log('[WT] decrypted : ' + decrypted);
+
+  let passed = decrypted === pincode ? true : false;
+  console.log(`${TAG} pincode result : ${passed}`);
+  if (passed) {
+    req.session.pincode = pincode;
+    req.session.logged = true;
+    console.log(`${TAG} session : ${JSON.stringify(req.session)}`);
+  }
+  res.send(passed);
+}
 
+var HTTPserverStart = function () {
+  evtEmit = new EventEmitter();
   var app = express();
+  app.engine('html', require('ejs').renderFile);
+  app.set('view engine', 'ejs');
+  app.set('views', `${g.baseDir}/../`);
+  app.use(express.static(`${g.baseDir}/../client`));
+  // For post method
+  app.use(express.urlencoded({
+    extended: true
+  }));
+  app.use(express.json());
+  // For session management
+  app.use(session({
+    resave: false,
+    saveUninitialized: true,
+    secret: 'mde framework',
+    cookie: {
+      httpOnly: true,
+      secure: false,
+    },
+  }));
+
   var appProxy = require('./app_proxy');
-  httpserver = http.createServer(app);
-  httpserver.listen(g.port, function() {
-    console.log('Server is listening on port ' + g.port);
+  d2dService = new D2DServiceLocal();
+  console.log(`${TAG} d2dService define: ${d2dService}`);
+  app.use('/app', appProxy(app, g.port, d2dService));
+
+  app.use('/client', clientRouter);
+
+  console.log(`${TAG} __dirname: ${__dirname}`);
+
+  if (is_tv) {
+    platform_app_path = '/opt/usr/apps'
+    console.log(`${TAG} TV Profile`);
+  }
+
+  var tizenApp = tizen.application.getCurrentApplication();
+  console.log(`${TAG} ID, packageId: ${tizenApp.appInfo.id} ${tizenApp.appInfo.packageId}`);
+  serverAppId = tizenApp.appInfo.id.split('.')[0];
+  g.baseDir = __dirname.split(serverAppId)[0];
+  console.log(`${TAG} g.baseDir: ${g.baseDir}`);
+
+  clientRouter.get('/webclip/*', function (req, res) {
+    let file = req.originalUrl.replace('/client/webclip/', '').replace(/\?.+$/, '');
+
+    let webclipName = '';
+    let appId;
+
+    let match = file.match(/^[^\/]+/);
+    if (match) {
+      webclipName = match[0];
+    }
+    console.log(`${TAG} webclip name: ${webclipName}`);
+
+    // find appId by webclip name
+    let app = dataApps.filter(function (app) {
+      return !!app.webclip && app.webclip.manifest.name === webclipName;
+    })[0];
+    if (app) {
+      appId = app.d2dApp.appPkgID;;
+    }
+
+    let options = {
+      root: path.join(platform_app_path, appId, TIZEN_WEB_APP_SHARED_RESOURCES, WEBCLIP_DIRECTORY)
+    };
+
+    // remove weblip name from path
+    file = file.replace(webclipName + '/', '');
+    res.sendFile(file, options, function (err) {
+      if (err) {
+        console.log(`${TAG} err: ${err}`);
+        res.send("err", err);
+      } else {
+        console.log(`${TAG} res.sendFile() done: ${file}`);
+      }
+    });
   });
-  evtEmit = new EventEmitter();
-  app.use(express.json());
-  app.use('/app', appProxy(app, g.port));
-  g.baseDir = require('path').join(__dirname, '../client');
-  app.use(express.static(g.baseDir));
 
-  app.get(/^\/(|enter-name\.html|index\.html)$/, (req, res) => {
-    res.redirect('client.html');
+  clientRouter.get('/updateWebclip', function (req, res) {
+    console.log(`${TAG} get(/updateWebclip)`);
+    var apps = getWebClipsList();
+    var result = {
+      type: "full",
+      data: {
+        apps: apps
+      }
+    }
+    res.send(result);
+  });
+
+  clientRouter.get('/*', function (req, res) {
+    let file = req.originalUrl.replace('/client/', '').replace(/\?.+$/, '');
+    let pkgId = webapis.getPackageId();
+    let fullPath = require('path').join(g.baseDir, pkgId, '/res/wgt/client', file);
+    console.log(`${TAG} pkgId: ${pkgId}, fullPath: ${fullPath}`);
+    res.sendFile(fullPath);
+  });
+
+  app.get('/', function (req, res) {
+    console.log(`${TAG} URL parameter : ${req.originalUrl}`);
+    urlParam = req.originalUrl;
+
+    if (!MODE_WT) {
+      const crypto = require('crypto');
+      var byteData = crypto.randomBytes(256);
+      pincode = parseInt(byteData.toString('hex').substr(0, 8), 16).toString().substr(0, 4);
+      webapis.postPlainNotification("PIN Code", pincode, 10);
+      res.redirect("/client/pincode.html");
+    } else {
+      if (req.query.roomId !== undefined) {
+        res.redirect("/client/invited.html");
+      } else {
+        res.render("client/client.html", { logged: true });
+      }
+    }
+  });
+
+  app.get('/d2dIcon/*', (req, res) => {
+    let fullPath = req.originalUrl.replace("d2dIcon", platform_app_path);
+    res.sendFile(fullPath);
   });
 
   app.get('/appList', (req, res) => {
@@ -104,30 +435,90 @@ var HTTPserverStart = function() {
 
   app.get('/updateAppList', (req, res) => {
     res.writeHead(200, {
-        'Content-Type': 'text/event-stream',
-        'Cache-Control': 'no-cache',
-        'Connection': 'keep-alive'
+      'Content-Type': 'text/event-stream',
+      'Cache-Control': 'no-cache',
+      'Connection': 'keep-alive'
     });
     evtEmit.on("updateapplist", (event, data) => {
       res.write("event: " + String(event) + "\n" + "data: " + JSON.stringify(data) + "\n\n");
     });
   });
 
-  new relayServer(httpserver);
+  app.get('/publicKey', (req, res) => {
+    res.send(publicKey);
+  });
+
+  app.post('/pinCodeToServer', (req, res) => {
+    console.log(`${TAG} pinCodeToServer`);
+    var revData = JSON.stringify(req.body);
+    var resultData = revData.replace(/"/g, "").replace(/{/g, "").replace(/}/g, "").replace(/:/g, "").replace(/[\s]/g, "+");
+    comparePincode(req, res, resultData);
+  });
+
+  app.post('/d2d', (req, res) => {
+    if (req.session.pincode === pincode) {
+      console.log(`${TAG} client.html`);
+      res.render("client/client.html", { logged: req.session.logged });
+    } else {
+      console.log(`${TAG} no client.html`);
+    }
+  });
+
+  app.get('/getRoomId', (req, res) => {
+    res.send(urlParam);
+  });
+
+  // receive data or cmd to app on device
+  app.post('/app', (req, res) => {
+    res.send({
+      result: "ok"
+    });
+  });
+
+  app.get('/service', (req, res) => {
+  });
+
+  app.post('/url', (req, res) => {
+    webapis.mde.launchBrowserFromUrl(req.body.url);
+  });
+
+  httpserver = http.createServer(app);
+  httpserver.listen(g.port, function () {
+    var interfaces = require('os').networkInterfaces();
+    for (var devName in interfaces) {
+      if (interfaces.hasOwnProperty(devName)) {
+        var iface = interfaces[devName];
+        for (var i = 0; i < iface.length; i++) {
+          var alias = iface[i];
+          if (alias.family === 'IPv4' && !non_ip_list.includes(alias.address) && !alias.internal)
+            updateDNSresolver(alias.address);
+        }
+      }
+    }
+  });
+  relayServer(httpserver);
 };
 
-module.exports.onStart = function() {
+module.exports.getUrlParam = function () {
+  console.log(`${TAG} getUrlParam is called`);
+  return urlParam;
+};
+
+module.exports.onStart = function () {
   getAppList();
   HTTPserverStart();
   setPackageInfoEventListener();
-  console.log("onStart is called in service1");
+  addAccountListener();
+  console.log(`${TAG} onStart is called in DNS Resolver`);
 };
-module.exports.onStop = function() {
+
+module.exports.onStop = function () {
   if (httpserver) {
     httpserver.close();
-    console.log('Server Terminated');
+    console.log(`${TAG} Server Terminated`);
   }
   unsetPackageInfoEventListener();
+  removeAccountListener();
   evtEmit.off("updateapplist");
-  console.log("onStop is called in service1");
+  console.log(`${TAG} onStop is called in DNS Resolver`);
 };